syncmanager.cpp

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

CPP
1,631
字号
                            step++;
                            if (syncItem == NULL)
                                step++;

                        }
                        if (step == 3) {
                            do {
                                if (syncItem == NULL) {
                                    syncItem = getItem(*sources[count], &SyncSource::getNextUpdatedItem);
                                    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,
                                                          REPLACE_COMMAND_NAME,
                                                          syncItem, sources[count]->getConfig().getType());

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

                        //
                        // Deleted Item
                        //
                        if (step == 4) {

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

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

                            step++;
                            if (syncItem == NULL)
                                step++;
                        }
                        if (step == 5) {
                            do {
                                if (syncItem == NULL) {
                                    syncItem = getItem(*sources[count], &SyncSource::getNextDeletedItem);
                                    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,
                                                          DELETE_COMMAND_NAME,
                                                          syncItem, sources[count]->getConfig().getType());

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

                        break;
                    }
            }

            if (modificationCommand) {
                list->add(*modificationCommand);
                delete modificationCommand;
                modificationCommand = NULL;
            }
            sync->setCommands(list);
            delete list;
            commands.add(*sync);
            delete sync;

            //
            // Check if all the sources were synced.
            // If not the prepareSync doesn't use the <final/> tag
            //
            syncml = syncMLBuilder.prepareSyncML(&commands, (iterator != toSync ? false : last));
            msg    = syncMLBuilder.prepareMsg(syncml);

            deleteSyncML(&syncml);
			commands.clear();

            if (msg == NULL) {
                ret = getLastErrorCode();
                goto finally;
            }

            // Synchronization message:
            long realMsgSize = strlen(msg);
            LOG.debug("%s estimated size %ld, allowed size %ld, real size %ld / estimated size %ld = %ld%%",
                      MSG_MODIFICATION_MESSAGE,
                      msgSize, maxMsgSize, realMsgSize, msgSize,
                      msgSize ? (100 * realMsgSize / msgSize) : 100);

            //Fire Modifications Event
            fireSyncEvent(NULL, SEND_MODIFICATION);

            responseMsg = transportAgent->sendMessage(msg);
            if (responseMsg == NULL) {
                ret=getLastErrorCode();
                goto finally;
            }
            // increment the msgRef after every send message
            syncMLBuilder.increaseMsgRef();
            syncMLBuilder.resetCommandID();

            syncml = syncMLProcessor.processMsg(responseMsg);
            safeDelete(&responseMsg);
            safeDelete(&msg);

            if (syncml == NULL) {
                ret = getLastErrorCode();
                goto finally;
            }

            isFinalfromServer = syncml->isLastMessage();
            ret = syncMLProcessor.processSyncHdrStatus(syncml);
            if (isErrorStatus(ret)) {
                //lastErrorCode = ret;
                //sprintf(lastErrorMsg, "Server Failure: server returned error code %i", ret);
                setErrorF(ret, "Server Failure: server returned error code %i", ret);
                LOG.error("%s", getLastErrorMsg());
                goto finally;

            }
            ret = 0;
            //
            // Process the status of the item sent by client. It invokes the
            // source method
            //
            int itemret = syncMLProcessor.processItemStatus(*sources[count], syncml->getSyncBody());
            if(itemret){
                char *name = toMultibyte(sources[count]->getName());
                LOG.error("Error #%d in source %s", itemret, name);
                delete [] name;
                // skip the source, and set an error
                setSourceStateAndError(count, SOURCE_ERROR, itemret, getLastErrorMsg());
                //lastErrorCode = itemret;
                setError(itemret, "");
                break;
            }

            // Fire SyncSourceEvent: END sync of a syncsource (client modifications)
            if (last)
                fireSyncSourceEvent(sources[count]->getConfig().getURI(), sources[count]->getConfig().getName(), sources[count]->getSyncMode(), 0, SYNC_SOURCE_END);

            // The server might have included a <Sync> command without waiting
            // for a 222 alert. If it hasn't, then nothing is done here.
            ArrayList statusList;
            if (checkForServerChanges(syncml, statusList)) {
                goto finally;
            }
            if (statusList.size()) {
                Status* status = syncMLBuilder.prepareSyncHdrStatus(NULL, 200);
                commands.add(*status);
                deleteStatus(&status);
                commands.add(&statusList);
            }

            // deleteSyncML(&syncml);

        } while (last == false);

        // Fire SyncSourceEvent: END sync of a syncsource (client modifications)
        // fireSyncSourceEvent(sources[count]->getConfig().getURI(), sources[count]->getConfig().getName(), sources[count]->getSyncMode(), 0, SYNC_SOURCE_END);

    } // end for (count = 0; count < sourcesNumber; count ++)

    if (isToExit()) {
        // error. no source to sync
        ret = getLastErrorCode();
        goto finally;
    }

    deleteSyncML(&syncml);

    //
    // If this was the last chunk, we move the state to STATE_PKG3_SENT
    // At this time "last" is always true. The client is going to send
    // the 222 package for to get the server modification if at least a source is correct
    //
    last = true;
    currentState = STATE_PKG3_SENT;

    //
    // send 222 alert code to retrieve the item from server
    //
    if ( !isFinalfromServer && isAtLeastOneSourceCorrect ) {
        status = syncMLBuilder.prepareSyncHdrStatus(NULL, 200);
	commands.add(*status);
        deleteStatus(&status);
        for (count = 0; count < sourcesNumber; count ++) {
            if(!sources[count]->getReport()->checkState()) {
                continue;
            }
            if ((sources[count]->getSyncMode() != SYNC_ONE_WAY_FROM_CLIENT) &&
                (sources[count]->getSyncMode() != SYNC_REFRESH_FROM_CLIENT))
            {
                alert = syncMLBuilder.prepareAlert(*sources[count]);
                commands.add(*alert);
                deleteAlert(&alert);
            }
        }

        syncml = syncMLBuilder.prepareSyncML(&commands, false);
        msg    = syncMLBuilder.prepareMsg(syncml);

        LOG.debug("Alert to request server changes");

        responseMsg = transportAgent->sendMessage(msg);
        if (responseMsg == NULL) {
            LOG.debug("SyncManager::sync(): null responseMsg");
            ret=getLastErrorCode();
            goto finally;
        }

        // increment the msgRef after every send message
        syncMLBuilder.increaseMsgRef();
        syncMLBuilder.resetCommandID();

        deleteSyncML(&syncml);
        safeDelete(&msg);

        syncml = syncMLProcessor.processMsg(responseMsg);
        safeDelete(&responseMsg);
        commands.clear();

        if (syncml == NULL) {
            LOG.debug("SyncManager::sync(): null syncml");
            ret = getLastErrorCode();
            goto finally;
        }
        ret = syncMLProcessor.processSyncHdrStatus(syncml);
        if (isErrorStatus(ret)) {
            //lastErrorCode = ret;
            //sprintf(lastErrorMsg, "Server Failure: server returned error code %i", ret);
            setErrorF(ret, "Server Failure: server returned error code %i", ret);
            LOG.error("%s", getLastErrorMsg());
            goto finally;
        }
        ret = 0;

        //
        // Process the items returned from server
        //

        do {
            last = syncml->getSyncBody()->getFinalMsg();
            ArrayList statusList;

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

            if (checkForServerChanges(syncml, statusList)) {
                goto finally;
            }

            commands.add(&statusList);

            // Add any map command pending for the active sources
            for(int i=0; i<sourcesNumber; i++) {
                addMapCommand(i);
            }

            if (!last) {
                deleteSyncML(&syncml);
                syncml = syncMLBuilder.prepareSyncML(&commands, last);
                msg    = syncMLBuilder.prepareMsg(syncml);

                LOG.debug("Status to the server");

                responseMsg = transportAgent->sendMes

⌨️ 快捷键说明

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