int ResumableUploader::prepare()

in sdk/src/resumable/ResumableUploader.cc [311:440]


int ResumableUploader::prepare(FileCompleteOutcome& completeOutcome)
{
    determinePartSize();

    FileCreateOutcome outcome;
    // rapid upload
    if (client_->configuration().enableRapidUpload) {
        // caculate pre hash
        uint64_t preHashBlockSize = 1024;
        if (preHashBlockSize > request_.FileSize()) {
            preHashBlockSize = request_.FileSize();
        }

        auto content = GetFstreamByPath(request_.FilePath(), request_.FilePathW(),
            std::ios::in | std::ios::binary);
        char streamBuffer[1024];
        uint64_t readSize = 0;
        if (!content->good()) {
            completeOutcome = FileCompleteOutcome(PdsError("ReadFileError", "Failed to read input file"));
            return -1;
        }
        content->read(streamBuffer, preHashBlockSize);
        readSize = static_cast<uint64_t>(content->gcount());
        content->close();

        if (readSize != preHashBlockSize) {
            completeOutcome = FileCompleteOutcome(PdsError("ReadFileError", "Failed to read enough size for caculate pre hash"));
            return -1;
        }
        std::string preHashSHA1 = ComputeContentSha1(streamBuffer, preHashBlockSize);

        // check pre hash request
        auto fileCreatePreCheckReq = FileCreateRequest(request_.DriveID(), request_.ParentFileID(), request_.Name(),
            request_.FileID(), request_.CheckNameMode(), request_.FileSize());
        fileCreatePreCheckReq.setPreHash(preHashSHA1);
        fileCreatePreCheckReq.setUserTags(request_.UserTags());
        fileCreatePreCheckReq.setHidden(request_.Hidden());
        auto fileCreatePreCheckOutcome = FileCreateWrap(fileCreatePreCheckReq);

        if (!fileCreatePreCheckOutcome.isSuccess()) {
            // check pre hash error
            if (fileCreatePreCheckOutcome.error().Code() != "PreHashMatched") {
                completeOutcome = FileCompleteOutcome(fileCreatePreCheckOutcome.error());
                return -1;
            }

            // check pre hash matched, rapid upload
            std::string hashSHA1;
            if (0 != ComputeFileSha1(completeOutcome, hashSHA1)){
                return -1;
            }

            // rapid upload request
            auto fileCreateRapidUploadReq = FileCreateRequest(request_.DriveID(), request_.ParentFileID(), request_.Name(),
                request_.FileID(), request_.CheckNameMode(), request_.FileSize());
            fileCreateRapidUploadReq.setContentHash(hashSHA1);
            fileCreateRapidUploadReq.setUserTags(request_.UserTags());
            fileCreateRapidUploadReq.setHidden(request_.Hidden());
            auto fileCreateRapidUploadOutcome = FileCreateWrap(fileCreateRapidUploadReq);

            if (!fileCreateRapidUploadOutcome.isSuccess()) {
                completeOutcome = FileCompleteOutcome(fileCreateRapidUploadOutcome.error());
                return -1;
            }

            // rapid upload success
            if (fileCreateRapidUploadOutcome.result().RapidUpload()) {
                FileCompleteResult result(fileCreateRapidUploadOutcome.result());
                completeOutcome = FileCompleteOutcome(result);
                return -1;
            }

            // failed to rapid upload, upload data
            outcome = fileCreateRapidUploadOutcome.result();
        }
        else {
            // pre hash check not matched, upload data
            outcome = fileCreatePreCheckOutcome.result();
        }
    }
    else {
        // create by upload data
        FileCreateRequest fileCreateReq = FileCreateRequest(request_.DriveID(), request_.ParentFileID(), request_.Name(),
            request_.FileID(), request_.CheckNameMode(), fileSize_);
        fileCreateReq.setUserTags(request_.UserTags());
        fileCreateReq.setHidden(request_.Hidden());
        auto fileCreateOutcome = FileCreateWrap(fileCreateReq);
        if (!fileCreateOutcome.isSuccess()) {
            completeOutcome = FileCompleteOutcome(fileCreateOutcome.error());
            return -1;
        }
        outcome = fileCreateOutcome.result();
    }

    if (outcome.result().Exist()) {
        completeOutcome = FileCompleteOutcome(PdsError("SameNameFileExist", "Same name file exist."));
        return -1;
    }

    if (hasRecordPath()) {
        initRecordInfo();
        record_.fileID = outcome.result().FileID();
        record_.uploadID = outcome.result().UploadID();

        Json::Value root;
        root["opType"] = record_.opType;
        root["driveID"] = record_.driveID;
        root["fileID"] = record_.fileID;
        root["uploadID"] = record_.uploadID;
        root["name"] = record_.name;
        root["filePath"] = record_.filePath;
        root["taskID"] = record_.taskID;
        root["mtime"] = record_.mtime;
        root["size"] = record_.size;
        root["partSize"] = record_.partSize;
        root["parts"].resize(0);

        std::stringstream ss;
        ss << root;
        std::string md5Sum = ComputeContentETag(ss);
        root["md5Sum"] = md5Sum;

        auto recordStream = GetFstreamByPath(recordPath_, recordPathW_, std::ios::out);
        if (recordStream->is_open()) {
            *recordStream << root;
            recordStream->close();
        }
    }
    return 0;
}