landmarks/locationlandmarks/localaccess/src/EPos_CPosLmLocalImportOp.cpp
changeset 0 667063e416a2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/landmarks/locationlandmarks/localaccess/src/EPos_CPosLmLocalImportOp.cpp	Tue Feb 02 01:06:48 2010 +0200
@@ -0,0 +1,764 @@
+/*
+* Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Operation for importing landmarks to a database.
+*
+*
+*/
+
+
+#include    <eposlmasyncops.rsg>
+#include    <EPos_LandmarksErrors.h>
+#include    <EPos_CPosLandmarkParser.h>
+#include    <EPos_PosLmImplExtension.h>
+#include    <epos_poslmlandmarkhandler.h>
+#include    <epos_poslmcategoryhandler.h>
+#include    <epos_cposlmglobalcategoryreader.h>
+#include    <epos_cposlmdiskutilities.h>
+
+#include    "epos_cposlmlocaldatabase.h"
+#include    "epos_cposlmlocaldbaccess.h"
+#include    "EPos_LocalLandmarks.h"
+#include    "EPos_RPosLmLocalAccessSubsession.h"
+#include    "EPos_CPosLmLocalInternalOpActive.h"
+#include    "EPos_CPosLmLocalImportOp.h"
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CPosLmLocalImportOp::CPosLmLocalImportOp(
+    CPosLmLocalDatabase& aDb,
+    CPosLandmarkParser& aLandmarkParser,
+    CPosLandmarkDatabase::TTransferOptions aTransferOptions,
+    CPosLmDiskUtilities& aDiskUtils)
+:   CPosLmLocalModifyOp(aDb),
+    iLandmarkParser(&aLandmarkParser),
+    iTransferOptions(aTransferOptions),
+    iImportState(EImportParseLm),
+    iParserOpStatus(KPosLmOperationNotComplete),
+    iDiskUtils(&aDiskUtils)
+    {
+    iUsesServerData = ETrue; // updates lm name index
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::ConstructL()
+    {
+    CPosLandmarkDatabase::TTransferOptions invalidOptions =
+        iTransferOptions &
+        ~CPosLandmarkDatabase::EIncludeCategories &
+        ~CPosLandmarkDatabase::EIncludeGlobalCategoryNames &
+        ~CPosLandmarkDatabase::ESupressCategoryCreation;
+
+    __ASSERT_ALWAYS(invalidOptions == CPosLandmarkDatabase::EDefaultOptions,
+        Panic(KPosLandmarksClientPanic, EPosLmInvalidArgument));
+
+    BaseConstructL();
+
+    ReadInfoFromResourceFileL(R_POS_LM_LOCAL_IMPORT_LMS_OP);
+
+    if (iTransferOptions & CPosLandmarkDatabase::EIncludeCategories)
+        {
+        iReader = CPosLmGlobalCategoryReader::NewL();
+        }
+
+    CPosLmOperation* parserOp = iLandmarkParser->ParseContentL(EFalse);
+    CleanupStack::PushL(parserOp);
+
+    iInternalOpActive = CPosLmLocalInternalOpActive::NewL(*this, parserOp);
+    CleanupStack::Pop(parserOp); // ownership transferred
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::ConstructL(
+    const RArray<TUint>& aLandmarksSelection)
+    {
+    if (aLandmarksSelection.Count() == 0)
+        {
+        User::Leave(KErrArgument);
+        }
+
+    for (TInt i = 0; i < aLandmarksSelection.Count(); i++)
+        {
+        User::LeaveIfError(iSelectedLmIds.Append(aLandmarksSelection[i]));
+        }
+    iSelectedLmIds.SortUnsigned();
+
+    ConstructL();
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CPosLmLocalImportOp* CPosLmLocalImportOp::NewL(
+    CPosLmLocalDatabase& aDb,
+    CPosLandmarkParser& aLandmarkParser,
+    CPosLandmarkDatabase::TTransferOptions aTransferOptions,
+    CPosLmDiskUtilities& aDiskUtils)
+    {
+    CPosLmLocalImportOp* self = new (ELeave)
+        CPosLmLocalImportOp(aDb, aLandmarkParser, aTransferOptions, aDiskUtils);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CPosLmLocalImportOp* CPosLmLocalImportOp::NewL(
+    CPosLmLocalDatabase& aDb,
+    CPosLandmarkParser& aLandmarkParser,
+    const RArray<TUint>& aLandmarksSelection,
+    CPosLandmarkDatabase::TTransferOptions aTransferOptions,
+    CPosLmDiskUtilities& aDiskUtils)
+    {
+    CPosLmLocalImportOp* self = new (ELeave)
+        CPosLmLocalImportOp(aDb, aLandmarkParser, aTransferOptions, aDiskUtils);
+    CleanupStack::PushL(self);
+    self->ConstructL(aLandmarksSelection);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CPosLmLocalImportOp::~CPosLmLocalImportOp()
+    {
+    RollbackAndGenerateEventIfNeeded(Progress());
+
+    delete iReader;
+
+    delete iCurrentLm;
+    iCurrentCategoryIds.Close();
+
+    iSelectedLmIds.Close();
+    iImportedLmIds.Close();
+
+    delete iInternalOpActive;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::ImportedLandmarkItemIdsL(
+    RArray<TPosLmItemId>& aLmItemIds)
+    {
+    for (TInt i=0; i<iImportedLmIds.Count(); i++)
+        {
+        User::LeaveIfError(aLmItemIds.Append(iImportedLmIds[i]));
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::DoNextStepPreL(
+    TReal32& aProgress)
+    {
+    if (iImportState == EImportParseLm)
+        {
+        ParseLandmarkL();
+
+        // If it is a selected landmark we need to import it to db
+        if (IsSelectedLandmark())
+            {
+            GetParsedLandmarkL();
+            if (iTransferOptions & CPosLandmarkDatabase::EIncludeCategories &&
+                iCurrentCategoryIds.Count() != 0)
+                {
+                iImportState = EImportAddLmCatToDb;
+                }
+            else
+                {
+                iImportState = EImportAddLmToDb;
+                }
+            }
+        }
+    else if (iImportState == EImportAddLmCatToDb)
+        {
+        ImportLmCategoriesL();
+        // Ready importing categories ?
+        if (iCurrentCategory == iCurrentCategoryIds.Count())
+            {
+            iImportState = EImportAddLmToDb;
+            }
+        }
+    else
+        {
+        // iImportState == EImportAddLmToDb
+        ImportLandmarkL();
+        // Ready importing landmark
+        iImportState = EImportParseLm;
+        }
+
+    // Update progress
+    UpdateProgress(aProgress);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TBool CPosLmLocalImportOp::DoNextStepPostL(
+    TReal32& aProgress)
+    {
+    // Check if we are ready parsing or not
+    if ((iParserOpStatus == KErrNone && iImportState == EImportParseLm) ||
+        (IsSelectedLandmarksImported()))
+        {
+        __ASSERT_ALWAYS(!LandmarkSelection() ||
+                        IsSelectedLandmarksImported() ||
+                        (LandmarkSelection() &&
+                         iSelectedLmIds.Count() > iSelectedLmIdPos &&
+                         iCurrentLmIndex > iSelectedLmIds[iSelectedLmIdPos]),
+                Panic(KPosLandmarksClientPanic, EPosInvalidIndex));
+
+        User::LeaveIfError(GenerateEventIfNeeded(aProgress));
+        iStatusFlag = KErrNone;
+        return EFalse;
+        }
+
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TReal32 CPosLmLocalImportOp::Step()
+    {
+    return iCurrentProgress - iLastReportedProgress;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::CheckResourceValue(
+    TInt /*aResourceId*/,
+    TInt aNoOfSubOperations)
+    {
+    __ASSERT_ALWAYS(aNoOfSubOperations > 0, Panic(KPosLandmarksClientPanic,
+        EPosInvalidValueSpecifiedInResourceFile));
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::HandleError(
+    TInt& aError)
+    {
+    iStatusFlag = aError;
+    RollbackAndGenerateEventIfNeeded(Progress());
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::InternalOpCompleted(
+    TInt aStatus,
+    TReal32 aProgress,
+    TRequestStatus& aClientStatus,
+    TReal32& aClientProgress)
+    {
+    iParserOpStatus = aStatus;
+    iParserProgress = aProgress;
+
+    if (aStatus == KErrNone || aStatus == KPosLmOperationNotComplete)
+        {
+        // Internal operation did not fail. Even if parser operation completed
+        // with KErrNone, this operation is not done; the landmark must be
+        // imported as well.
+
+        TRAP(aStatus, DoNextStepPreL(aClientProgress));
+
+        if (aStatus == KErrNone)
+            {
+            // Status must be changed to KPosLmOperationNotComplete. Otherwise,
+            // the client thinks that the operation is done.
+            aStatus = KPosLmOperationNotComplete;
+            }
+        else
+            {
+            RollbackAndGenerateEventIfNeeded(aProgress);
+            }
+        }
+    else
+        {
+        RollbackAndGenerateEventIfNeeded(aProgress);
+        }
+
+    TRequestStatus* clientStatus = &aClientStatus;
+    User::RequestComplete(clientStatus, aStatus);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::DoNextStep(
+    TRequestStatus& aStatus,
+    TReal32& aProgress)
+    {
+    if (IsInParsingState())
+        {
+        // Performs next step on parser operation with active object.
+        aStatus = KRequestPending;
+        PrepareNextParsingStep();
+        iInternalOpActive->DoNext(aStatus, aProgress);
+        }
+    else
+        {
+        // Import landmark or categories. May also be in compacting state.
+        NextStep(aStatus, aProgress);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::DoExecuteL()
+    {
+    TRequestStatus status(KPosLmOperationNotComplete);
+    TRequestStatus statusInternalOp;
+    TReal32 progress;
+
+    do
+        {
+        if (IsInParsingState())
+            {
+            // Performs next step on parser operation without active object.
+            // Using an active object would hang the thread when calling
+            // User::WaitForRequest.
+            PrepareNextParsingStep();
+            iInternalOpActive->InternalOpNextStep(statusInternalOp, progress);
+            User::WaitForRequest(statusInternalOp);
+            User::LeaveIfError(statusInternalOp.Int());
+
+            // To finish a parsing next step, this function must be called.
+            // The function would have been called by the active object if
+            // running asynchronously (DoNextStep).
+            InternalOpCompleted(statusInternalOp.Int(), progress, status,
+                progress);
+            }
+        else
+            {
+            // Import landmark or categories. May also be in compacting state.
+            NextStep(status, progress);
+            }
+
+        User::WaitForRequest(status);
+        User::LeaveIfError(status.Int());
+        } while (status.Int() == KPosLmOperationNotComplete);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::ParseLandmarkL()
+    {
+    // A landmark has previously been parsed when this function is called.
+
+    // Error during parsing of landmarks
+    if (iParserOpStatus != KErrNone &&
+        iParserOpStatus != KPosLmOperationNotComplete)
+        {
+        User::Leave(iParserOpStatus);
+        }
+
+    // Reset landmark and landmark category
+    delete iCurrentLm;
+    iCurrentLm = NULL;
+    iCurrentCategoryIds.Reset();
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::GetParsedLandmarkL()
+    {
+    // Get landmark and landmark category ids
+    iCurrentLm = iLandmarkParser->LandmarkLC();
+    CleanupStack::Pop();
+    iCurrentLm->GetCategoriesL(iCurrentCategoryIds);
+
+    // Reset category ids in landmark
+    iCurrentLm->RemoveLandmarkAttributes(CPosLandmark::ECategoryInfo);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::ImportLandmarkL()
+    {
+    iDiskUtils->DiskSpaceBelowCriticalLevelL(
+        iDiskUtils->EstimatedDiskSizeOfLmOperation(
+        CPosLmDiskUtilities::EAddLandmarkOp,
+        *iCurrentLm ), iDb->DatabaseDrive() );
+
+    // Add landmark to db
+    PosLmLandmarkHandler::AddLandmarkL( *iDb->DatabaseAccess(), *iCurrentLm );
+    iDb->NameIndex().AddL( *iCurrentLm );
+
+    // Add lm item id to array of imported lm item ids
+    User::LeaveIfError( iImportedLmIds.Append( iCurrentLm->LandmarkId() ) );
+
+    // Imported a selected landmark, so point to next id in array
+    iSelectedLmIdPos++;
+
+    iCurrentCategory = 0;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::ImportLmCategoriesL()
+    {
+    for (TInt i = 0;
+        i < iNoOfSubOperations &&
+        iCurrentCategory < iCurrentCategoryIds.Count();
+        i++)
+        {
+        // Get next gategory
+        CPosLandmarkCategory* lmcat =
+            iLandmarkParser->LandmarkCategoryLC(
+            iCurrentCategoryIds[iCurrentCategory++]);
+        TPosLmItemId dbItemId;
+        TBool lmCatInDb = ETrue;
+
+        // Is global category ?
+        if (lmcat->GlobalCategory() != KPosLmNullGlobalCategory)
+            {
+            TBool dummyBool;
+            // Is global category in db ?
+            if (PosLmCategoryHandler::IsGlobalCategoryExistingL(
+                    *iDb->DatabaseAccess(), lmcat->GlobalCategory(),
+                    dbItemId, dummyBool))
+                {
+                // Set category id for global category
+                PosLmImplExtension::SetCategoryIdL(*lmcat, dbItemId);
+
+                // Import global category names ?
+                if (iTransferOptions &
+                    CPosLandmarkDatabase::EIncludeGlobalCategoryNames)
+                    {
+                    // Update global category name in db
+                    TPtrC categoryName;
+                    TInt err = lmcat->GetCategoryName(categoryName);
+                    if (err == KErrNone)
+                        {
+                        PosLmCategoryHandler::UpdateGlobalCategoryNameL(
+                            *iDb->DatabaseAccess(), *lmcat);
+                        iLastChangedCategoryId = lmcat->CategoryId();
+                        iNrOfCategoriesUpdated++;
+                        }
+                    }
+                }
+            else
+                {
+                // Is global category in resource ?
+                HBufC* categoryNameFromResource =
+                    GlobalCategoryNameInResourceL(lmcat);
+                CleanupStack::PushL(categoryNameFromResource);
+                if (categoryNameFromResource)
+                    {
+                    // Import global category names ?
+                    if (iTransferOptions &
+                        CPosLandmarkDatabase::EIncludeGlobalCategoryNames)
+                        {
+                        // Add global category to db with imported name
+                        lmCatInDb = AddCategoryL(*lmcat);
+                        }
+                    else
+                        {
+                        // Add global category to db with name from resource
+                        lmcat->SetCategoryNameL(
+                            categoryNameFromResource->Des());
+                        lmCatInDb = AddCategoryL(*lmcat);
+                        }
+                    }
+                else
+                    {
+                    // Global category neither in db or resource file
+                    lmCatInDb = AddLocalCategoryL(*lmcat, dbItemId);
+                    }
+
+                CleanupStack::PopAndDestroy(categoryNameFromResource);
+                }
+            }
+        else
+            {
+            // Not a global category
+            lmCatInDb = AddLocalCategoryL(*lmcat, dbItemId);
+            }
+
+        if (lmCatInDb)
+            {
+            // Add category id to landmark
+            iCurrentLm->AddCategoryL(lmcat->CategoryId());
+            }
+
+        CleanupStack::PopAndDestroy(lmcat);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TBool CPosLmLocalImportOp::AddLocalCategoryL(
+    CPosLandmarkCategory& aLmCat,
+    TPosLmItemId& aLmItemId)
+    {
+    // Set category id for category
+    PosLmImplExtension::SetGlobalCategory(aLmCat, KPosLmNullGlobalCategory);
+
+    // Category name doesn't exists in db ?
+    if (PosLmCategoryHandler::VerifyCategoryNameNotExistsL(
+            *iDb->DatabaseAccess(), aLmCat, PosLmCategoryHandler::EAddCheck,
+            aLmItemId) == KErrNone)
+        {
+        // Add local category
+        return AddCategoryL(aLmCat);
+        }
+    else
+        {
+        // Set category id for category
+        PosLmImplExtension::SetCategoryIdL(aLmCat, aLmItemId);
+        }
+
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::UpdateProgress(TReal32& aProgress)
+    {
+    iLastReportedProgress = iCurrentProgress;
+
+    // Set the progress for the operation
+    TReal32 importStateProgress;
+    // Three (3) step are taken per imported landmark for each NextStepL call
+    TReal32 importStatePartProgress =
+        (iParserProgress - iOldParserProgress) / 3;
+    if (iImportState == EImportAddLmCatToDb)
+        {
+        TReal32 importLmCatPart = importStatePartProgress;
+        // Add current lm cat index
+        if (iCurrentCategoryIds.Count() > 0)
+            {
+            importStatePartProgress =
+                (TReal32(1) / iCurrentCategoryIds.Count()) *
+                importStatePartProgress;
+            importLmCatPart = importStatePartProgress *
+                (iCurrentCategory + 1);
+            }
+        aProgress = iOldParserProgress + importLmCatPart;
+        }
+    else if (iImportState == EImportAddLmToDb)
+        {
+        importStateProgress = importStatePartProgress;
+        aProgress = iOldParserProgress + (2 * importStateProgress);
+        }
+    else
+        {
+        // iImportState == EImportParseLm
+        aProgress = iParserProgress;
+        }
+
+    iCurrentProgress = aProgress;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TBool CPosLmLocalImportOp::LandmarkSelection()
+    {
+    return (iSelectedLmIds.Count() > 0);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TBool CPosLmLocalImportOp::IsSelectedLandmark()
+    {
+    if (!LandmarkSelection() ||
+        (LandmarkSelection() &&
+        iSelectedLmIds.Count() > iSelectedLmIdPos &&
+        iCurrentLmIndex == iSelectedLmIds[iSelectedLmIdPos]))
+        {
+        return ETrue;
+        }
+
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TBool CPosLmLocalImportOp::IsSelectedLandmarksImported()
+    {
+    if (LandmarkSelection() &&
+        iSelectedLmIds.Count() == iSelectedLmIdPos)
+        {
+        return ETrue;
+        }
+
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+HBufC* CPosLmLocalImportOp::GlobalCategoryNameInResourceL(
+    CPosLandmarkCategory* aCategory)
+    {
+    HBufC* name = NULL;
+    TPosLmGlobalCategory globalCat = aCategory->GlobalCategory();
+
+    for (TInt i = 0; i < iReader->Count() && !name; i++)
+        {
+        CPosLandmarkCategory* readerCategory = iReader->GlobalCategoryLC(i);
+
+        TPtrC catName;
+        if (readerCategory->GlobalCategory() == globalCat &&
+            readerCategory->GetCategoryName(catName) == KErrNone)
+            {
+            name = catName.AllocL();
+            }
+
+        CleanupStack::PopAndDestroy(readerCategory);
+        }
+
+    return name;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::RollbackAndGenerateEventIfNeeded(
+    TReal32 aProgress)
+    {
+    RollbackIfNeeded();
+
+    GenerateEventIfNeeded(aProgress);
+
+    // Reset flag: rollback and event generation should not be done twice.
+    iStatusFlag = KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TInt CPosLmLocalImportOp::GenerateEventIfNeeded(
+    TReal32 /*aProgress*/)
+    {
+    TInt status = KErrNone;
+    if (iStatusFlag != KErrNone && iImportedLmIds.Count() > 0)
+        {
+        if (iImportedLmIds.Count() == 1)
+            {
+            status = iDb->RegisterEvent(EPosLmEventLandmarkCreated,
+                iImportedLmIds[0]);
+            if (status != KErrNone)
+                {
+                return status;
+                }
+            }
+        if (iNrOfCategoriesAdded == 1 && iNrOfCategoriesUpdated <= 1)
+            {
+            status = iDb->RegisterEvent(EPosLmEventCategoryCreated,
+                iLastChangedCategoryId);
+            if (status != KErrNone)
+                {
+                return status;
+                }
+            }
+        if (iNrOfCategoriesUpdated == 1 && iNrOfCategoriesAdded <= 1)
+            {
+            status = iDb->RegisterEvent(EPosLmEventCategoryUpdated,
+                iLastChangedCategoryId);
+            if (status != KErrNone)
+                {
+                return status;
+                }
+            }
+
+        if (iImportedLmIds.Count() > 1 &&
+            (iNrOfCategoriesAdded > 1 || iNrOfCategoriesUpdated > 1))
+            {
+            return iDb->RegisterEvent(EPosLmEventUnknownChanges);
+            }
+        else if (iImportedLmIds.Count() > 1)
+            {
+            return iDb->RegisterEvent(EPosLmEventLandmarkUnknownChanges);
+            }
+        else if (iNrOfCategoriesAdded > 1 || iNrOfCategoriesUpdated > 1)
+            {
+            return iDb->RegisterEvent(EPosLmEventCategoryUnknownChanges);
+            }
+        }
+    return status;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TBool CPosLmLocalImportOp::AddCategoryL(
+    CPosLandmarkCategory& aCategory)
+    {
+    TBool toreturn = ETrue;
+
+    if (iTransferOptions &
+        CPosLandmarkDatabase::ESupressCategoryCreation)
+        {
+        toreturn = EFalse;
+        }
+    else
+        {
+        iDiskUtils->DiskSpaceBelowCriticalLevelL(
+            iDiskUtils->EstimatedDiskSizeOfLmOperation(
+                CPosLmDiskUtilities::EAddLmCategoryOp, aCategory),
+            iDb->DatabaseDrive());
+
+        PosLmCategoryHandler::AddCategoryL(*iDb->DatabaseAccess(), aCategory);
+        iLastChangedCategoryId = aCategory.CategoryId();
+        iNrOfCategoriesAdded++;
+        }
+
+    return toreturn;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmLocalImportOp::PrepareNextParsingStep()
+    {
+    iOldParserProgress = iParserProgress;
+    iCurrentLmIndex = iLandmarkParser->NumOfParsedLandmarks();
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TBool CPosLmLocalImportOp::IsInParsingState()
+    {
+    return (iImportState == EImportParseLm && !IsInCompactingState() &&
+        iParserOpStatus == KPosLmOperationNotComplete);
+    }
+