syncmanager.cpp

来自「funambol window mobile客户端源代码」· C++ 代码 · 共 1,631 行 · 第 1/5 页

CPP
1,631
字号
        i++;
    } // End: while (sortedSourcesFromServer[i])


  finally:
    this->count = oldCount;
    return result;
}


/*
 * Starts the synchronization phase
 */
int SyncManager::sync() {

    char* msg            = NULL;
    char* responseMsg    = NULL;
    Status* status       = NULL;
    SyncML* syncml       = NULL;
    /** Current item to be transmitted. Might be split across multiple messages if LargeObjectSupport is on. */
    SyncItem* syncItem   = NULL;
    /** number of bytes already transmitted from syncItem */
    long syncItemOffset  = 0;
    Alert* alert         = NULL;
    ModificationCommand* modificationCommand = NULL;
    unsigned int tot     = 0;
    unsigned int step    = 0;
    unsigned int toSync  = 0;
    unsigned int iterator= 0;
    int ret              = 0;
    bool last            = false;
    //ArrayList* list      = new ArrayList();
    bool isFinalfromServer = false;
    bool isAtLeastOneSourceCorrect = false;

    //for refresh from server sync (TO BE REMOVED?)
    allItemsList = new ArrayList*[sourcesNumber];

    //
    // If this is the first message, currentState is STATE_PKG1_SENT,
    // otherwise it is already in STATE_PKG3_SENDING.
    //
    if (currentState == STATE_PKG1_SENT) {
        currentState = STATE_PKG3_SENDING;
    }

    // The real number of source to sync (XXX REMOVE ME)
    for (count = 0; count < sourcesNumber; count ++) {
        if (!sources[count]->getReport()->checkState())
            continue;
        toSync++;
    }

    for (count = 0; count < sourcesNumber; count ++) {
        allItemsList[count] = NULL;
        if (!sources[count]->getReport()->checkState())
            continue;

        // note: tot == 0 is used to detect when to start iterating over
        // items from the beginning
        tot  = 0;
        step = 0;
        last = false;
        iterator++;

        // Fire SyncSource event: BEGIN sync of a syncsource (client modifications)
        fireSyncSourceEvent(sources[count]->getConfig().getURI(), sources[count]->getConfig().getName(), sources[count]->getSyncMode(), 0, SYNC_SOURCE_BEGIN);

        if ( sources[count]->beginSync() ) {
            // Error from SyncSource
            //lastErrorCode = ERR_UNSPECIFIED;
            setError(ERR_UNSPECIFIED, "");
            ret = getLastErrorCode();
            // syncsource should have set its own errors. If not, set default error.
            if (sources[count]->getReport()->checkState()) {
                setSourceStateAndError(count, SOURCE_ERROR, ERR_UNSPECIFIED, "Error in begin sync");
            }
            continue;
        }
        else {
            isAtLeastOneSourceCorrect = true;
        }

        // keep sending changes for current source until done with it
        do {
            if (modificationCommand) {
                delete modificationCommand;
                modificationCommand = NULL;
            }

            if (commands.isEmpty()) {

                status = syncMLBuilder.prepareSyncHdrStatus(NULL, 200);
                commands.add(*status);
                deleteStatus(&status);

            }

            // Accumulate changes for the current sync source until the maxMsgSize
            // is reached.
            //
            // In each loop iteration at least one change must be sent to ensure 
            // progress.
            // Keeping track of the current message size is a heuristic which 
            // assumes a constant overhead for each message and change item 
            // and then adds the actual item data sent.
            deleteSyncML(&syncml);
            static long changeOverhead = 150;
            long msgSize = 0;
            Sync* sync = syncMLBuilder.prepareSyncCommand(*sources[count]);
            ArrayList* list = new ArrayList();

            switch (sources[count]->getSyncMode()) {
                case SYNC_SLOW:
                    {
                        if (syncItem == NULL) {
                            if (tot == 0) {
                                syncItem = getItem(*sources[count], &SyncSource::getFirstItem);
                                syncItemOffset = 0;
                                if (syncItem) {
                                    // Fire Sync Item Event - Item sent as Updated
                                    fireSyncItemEvent(sources[count]->getConfig().getURI(), sources[count]->getConfig().getName(), syncItem->getKey(), ITEM_UPDATED_BY_CLIENT);
                                }
                            }
                        }
                        tot = 0;
                        do {
                            if (syncItem == NULL) {
                                syncItem = getItem(*sources[count], &SyncSource::getNextItem);
                                syncItemOffset = 0;
                                if (syncItem) {
                                    // Fire Sync Item Event - Item sent as Updated
                                    fireSyncItemEvent(sources[count]->getConfig().getURI(), sources[count]->getConfig().getName(), syncItem->getKey(), ITEM_UPDATED_BY_CLIENT);
                                }
                            }

                            if (tot &&
                                maxMsgSize &&
                                syncItem &&
                                msgSize + changeOverhead + syncItem->getDataSize() - syncItemOffset > maxMsgSize) {
                                // avoid adding another item that exceeds the message size
                                break;
                            }

                            msgSize += changeOverhead;
                            msgSize +=
                                syncMLBuilder.addItem(modificationCommand,
                                                      syncItemOffset,
                                                      (maxMsgSize && loSupport) ? (maxMsgSize - msgSize) : LONG_MAX,
                                                      REPLACE_COMMAND_NAME,
                                                      syncItem,
                                                      sources[count]->getConfig().getType());

                            if (syncItem) {
                                if (syncItemOffset == syncItem->getDataSize()) {
                                    // the item is only the pointer not another instance. to save mem
                                    delete syncItem; syncItem = NULL;
                                } else {
                                    assert(msgSize >= maxMsgSize);
                                    break;
                                }
                            }
                            else {
                                last = true;
                                break;
                            }
                            tot++;
                        } while(msgSize < maxMsgSize);
                    }
                    break;

                case SYNC_REFRESH_FROM_SERVER:
                    {
                        last = true;
                        char *name = toMultibyte(sources[count]->getName());
                        if (sources[count]->removeAllItems() == 0) {                        
                            LOG.debug("Removed all items for source %s", name);
                        } else {
                            LOG.error("Error removing all items for source %s", name);
                        }
                        delete [] name;
                        // TODO: remove me...
                        allItemsList[count] = new ArrayList();
                        syncItem = getItem(*sources[count], &SyncSource::getFirstItemKey);
                        if(syncItem) {
                            allItemsList[count]->add((ArrayElement&)*syncItem);
                            delete syncItem; syncItem = NULL;
                        }
                        syncItem = getItem(*sources[count], &SyncSource::getNextItemKey);
                        while(syncItem) {
                            allItemsList[count]->add((ArrayElement&)*syncItem);
                            delete syncItem; syncItem = NULL;
                            syncItem = getItem(*sources[count], &SyncSource::getNextItemKey);
                        }
                    }
                    break;
                    
                case SYNC_ONE_WAY_FROM_SERVER:
                    last = true;
                    break;

                case SYNC_REFRESH_FROM_CLIENT:
                    {
                        if (syncItem == NULL) {
                            if (tot == 0) {
                                syncItem = getItem(*sources[count], &SyncSource::getFirstItem);
                                syncItemOffset = 0;
                                if (syncItem) {
                                    // Fire Sync Item Event - Item sent as Updated
                                    fireSyncItemEvent(sources[count]->getConfig().getURI(), sources[count]->getConfig().getName(), syncItem->getKey(), ITEM_UPDATED_BY_CLIENT);
                                }
                            }
                        }
                        tot = 0;
                        do {
                            if (syncItem == NULL) {
                                syncItem = getItem(*sources[count], &SyncSource::getNextItem);
                                syncItemOffset = 0;
                                if (syncItem) {
                                    // Fire Sync Item Event - Item sent as Updated
                                    fireSyncItemEvent(sources[count]->getConfig().getURI(), sources[count]->getConfig().getName(), syncItem->getKey(), ITEM_UPDATED_BY_CLIENT);
                                }
                            }

                            if (tot &&
                                maxMsgSize &&
                                syncItem &&
                                msgSize + changeOverhead + syncItem->getDataSize() - syncItemOffset > maxMsgSize) {
                                // avoid adding another item that exceeds the message size
                                break;
                            }

                            msgSize += changeOverhead;
                            msgSize +=
                                syncMLBuilder.addItem(modificationCommand,
                                                      syncItemOffset,
                                                      (maxMsgSize && loSupport) ? (maxMsgSize - msgSize) : LONG_MAX,
                                                      REPLACE_COMMAND_NAME, syncItem,
                                                      sources[count]->getConfig().getType());

                            if (syncItem) {
                                if (syncItemOffset == syncItem->getDataSize()) {
                                    delete syncItem; syncItem = NULL;// the item is only the pointer not another instance. to save mem
                                } else {
                                    assert(msgSize >= maxMsgSize);
                                    break;
                                }
                            }
                            else {
                                last = true;
                                break;
                            }
                            tot++;
                        } while(msgSize < maxMsgSize);
                    }
                    break;

                default:
                    {
                        tot = 0;
                        //
                        // New Item
                        //
                        if (step == 0) {
                            assert(syncItem == NULL);
                            syncItem = getItem(*sources[count], &SyncSource::getFirstNewItem);
                            syncItemOffset = 0;
                            step++;
                            if (syncItem == NULL)
                                step++;
                        }
                        if (step == 1) {
                            do {
                                if (syncItem == NULL) {
                                    syncItem = getItem(*sources[count], &SyncSource::getNextNewItem);
                                    syncItemOffset = 0;
                                }

                                if (tot &&
                                    maxMsgSize &&
                                    syncItem &&
                                    msgSize + changeOverhead + syncItem->getDataSize() - syncItemOffset > maxMsgSize) {
                                    // avoid adding another item that exceeds the message size
                                    break;
                                }

                                msgSize += changeOverhead;
                                msgSize +=
                                    syncMLBuilder.addItem(modificationCommand,
                                                          syncItemOffset,
                                                          (maxMsgSize && loSupport) ? (maxMsgSize - msgSize) : LONG_MAX,
                                                          ADD_COMMAND_NAME,
                                                          syncItem, sources[count]->getConfig().getType());

                                if (syncItem) {
                                    if (syncItemOffset == syncItem->getDataSize()) {
                                        // Fire Sync Item Event - New Item Detected
                                        fireSyncItemEvent(sources[count]->getConfig().getURI(), sources[count]->getConfig().getName(), syncItem->getKey(), ITEM_ADDED_BY_CLIENT);
                                        delete syncItem; syncItem = NULL;
                                    } else {
                                        assert(msgSize >= maxMsgSize);
                                        break;
                                    }
                                }
                                else {
                                    step++;
                                    break;
                                }
                                tot++;
                            } while(msgSize < maxMsgSize);
                        }

                        //
                        // Updated Item
                        //
                        if (step == 2) {

                            if (modificationCommand) {
                                list->add(*modificationCommand);
                                delete modificationCommand;
                                modificationCommand = NULL;
                            }

                            assert(syncItem == NULL);
                            syncItem = getItem(*sources[count], &SyncSource::getFirstUpdatedItem);
                            syncItemOffset = 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?