📄 staffsservice.cpp
字号:
if (doCodepageConvert) connection->writeUInt(kSTAFFSTextConvert); else if (textTransfer) connection->writeUInt(kSTAFFSTextNoConvert); else connection->writeUInt(kSTAFFSBinary); } char fileBuffer[4000] = {0}; unsigned int writeLength = 0; STAFRC_t ack = static_cast<STAFRC_t>(connection->readUInt()); ackResult = connection->readString(); if (ack != kSTAFOk) updateResultString(outputList, fileEntry, ack, osRC); else if (doCodepageConvert) { // Perform a text transfer with conversion of eol chars and a // codepage conversion. It runs considerably slower than the // binary transfer. This is the type of transfer that will occur // if the TEXT option is specified and the codepages are different. // Data is sent as a series of buffers of UTF8 chars gFSCopyManagerPtr->updateDirectoryCopy( copyDataPtr, fromFile, kSTAFFSTextConvert, fileLength); connection->writeString(currentEOL); STAFStringBufferPtr newlineStr = currentEOL.toCurrentCodePage(); // How many bytes in the end-of-line sequence unsigned int newlineBufferSize = newlineStr->length(); // Points to a buffer containing end-of-line sequence char * newlineBuffer = new char [newlineBufferSize]; memcpy(newlineBuffer, newlineStr->buffer(), newlineBufferSize); // Last byte of end-of-line sequence char newlineKey = newlineBuffer[newlineBufferSize - 1]; bool done = false; const unsigned int defaultBufferSize = 4096; STAFRefPtr<char> buffer = STAFRefPtr<char>(new char[defaultBufferSize], STAFRefPtr<char>::INIT, STAFRefPtr<char>::ARRAY); unsigned int bufferSize = defaultBufferSize; unsigned int bufferReadOffset = 0; unsigned int bytesCopied = 0; while (!done) { rc = readFile( inFile, static_cast<char *>(buffer + bufferReadOffset), bufferSize - bufferReadOffset, fromFile, toMachine, fileLength, bytesCopied); if (rc != kSTAFOk) { updateResultString(outputList, fileEntry, rc, osRC); break; } unsigned int bytesInBuffer = inFile.gcount() + bufferReadOffset; bytesCopied += inFile.gcount(); if (bytesInBuffer < bufferSize) done = true; // Find a newline. Make sure we don't underrun the buffer; unsigned int i = bytesInBuffer - 1; // Last NewLine index unsigned int bufferGuardIndex = newlineBufferSize - 1; while (((buffer[i] != newlineKey) || !memcmp(buffer + i - newlineBufferSize, newlineBuffer, newlineBufferSize)) && (i > bufferGuardIndex)) { --i; } while ((i == bufferGuardIndex) && !done) { // We have a line bigger than our buffer. // Note: the beginning of the buffer may be a lone newline, but we // ignore that for this algorithm (as the next line is likely // larger than the buffer any way // First, create a buffer that is double our current size, and copy // our existing buffer data into it STAFRefPtr<char> tmpBuffer = STAFRefPtr<char>(new char[bufferSize * 2], STAFRefPtr<char>::INIT, STAFRefPtr<char>::ARRAY); memcpy(tmpBuffer, buffer, bufferSize); buffer = tmpBuffer; bufferSize *= 2; // Now, read in enough data to fill the remainder of the buffer rc = readFile(inFile, buffer + (bufferSize / 2), bufferSize / 2, fromFile, toMachine, fileLength, bytesCopied); if (rc != kSTAFOk) { updateResultString(outputList, fileEntry, rc, osRC); break; } bytesInBuffer += inFile.gcount(); bytesCopied += inFile.gcount(); // Finally, let's check to make sure that this buffer was // big enough, by finding a newline. Otherwise, let's run // the loop again. if (bytesInBuffer < bufferSize) done = true; i = bytesInBuffer - 1; // Last NewLine index bufferGuardIndex = (bufferSize / 2) - newlineBufferSize; while (((buffer[i] != newlineKey) || !memcmp(buffer + i - newlineBufferSize, newlineBuffer, newlineBufferSize)) && (i > bufferGuardIndex)) { --i; } } // while ((i == bufferGuardIndex) && !done) // We now have the last newline in the buffer if (!done) { connection->writeUInt(kSTAFFSContinueCopy); connection->writeString( STAFString(buffer, i + 1, STAFString::kCurrent)); memmove(buffer, buffer + i + 1, bufferSize - i - 1); bufferReadOffset = bufferSize - i - 1; } else { connection->writeUInt(kSTAFFSContinueCopy); connection->writeString( STAFString(buffer, bytesInBuffer, STAFString::kCurrent)); } gFSCopyManagerPtr->updateFileCopy(copyDataPtr, bytesCopied); } // while (!done) delete[] newlineBuffer; connection->writeUInt(kSTAFFSFinishedCopy); inFile.close(); if (rc == kSTAFOk) { // Read an ack, so that we know the file is closed ack = connection->readUInt(); if (ack != kSTAFOk) { updateResultString(outputList, fileEntry, ack, osRC); } } } /* This if clause is used to perform a text transfer with conversion of eol chars without a codepage conversion It runs considerably faster than the codepage conversion transfer. This is the type of transfer that will occur if the NOCONVERT option is enabled This is the type of transfer that will occur if the codepages are the same and a text transfer has been specified */ else if (textTransfer) { gFSCopyManagerPtr->updateDirectoryCopy( copyDataPtr, fromFile, kSTAFFSTextNoConvert, fileLength); STAFString transferString; int bufferSize = 3000; unsigned int transferLen = 0; char * buffer = new char[bufferSize]; unsigned int bytesCopied = 0; connection->writeString(currentEOL); connection->writeUInt(bufferSize); while ((fileLength > 0) && (inFile.good())) { transferLen = STAF_MIN(bufferSize, fileLength); rc = readFile(inFile, buffer, transferLen, fromFile, toMachine, fileLength, bytesCopied); if (rc != kSTAFOk) { updateResultString(outputList, fileEntry, rc, osRC); fileLength = 0; break; } connection->writeUInt(transferLen); connection->write(buffer, transferLen); fileLength -= transferLen; bytesCopied += transferLen; gFSCopyManagerPtr->updateFileCopy(copyDataPtr, bytesCopied); } connection->writeUInt(kSTAFFSFinishedCopy); delete[] buffer; inFile.close(); if (rc == kSTAFOk) { // Read an ack, so that we know the file is closed ack = connection->readUInt(); if (ack != kSTAFOk) { updateResultString(outputList, fileEntry, ack, osRC); fileLength = 0; } } } else { // Perform a binary transfer of a file unsigned int bytesCopied = 0; gFSCopyManagerPtr->updateDirectoryCopy( copyDataPtr, fromFile, kSTAFFSBinary, fileLength); connection->writeUInt(fileLength); if (level > 3) { // Starting with level 4 for the STAFDirectoryCopyAPI, to // improve performance, acks are no longer sent/received // after each read/write. Instead, a final ack is received // after the entire file is processed which indicates if // the copy was successful. while ((fileLength > 0) && (inFile.good())) { writeLength = STAF_MIN(sizeof(fileBuffer), fileLength); rc = readFile( inFile, reinterpret_cast<char *>(fileBuffer), writeLength, fromFile, toMachine, fileLength, bytesCopied); if (rc != kSTAFOk) break; connection->write(fileBuffer, writeLength); fileLength -= writeLength; bytesCopied += writeLength; gFSCopyManagerPtr->updateFileCopy( copyDataPtr, bytesCopied); } inFile.close(); if (rc == kSTAFOk) { // Receive the final acknowledgement that indicates if // the file was copied successfully rc = connection->readUInt(); } if (rc != kSTAFOk) { // Update error information in result updateResultString(outputList, fileEntry, rc, osRC); fileLength = 0; } } else { // Levels < 4 for the STAFDirectoryCopyAPI send/receive // acknowledgements after each read/write. while ((fileLength > 0) && (inFile.good())) { writeLength = STAF_MIN(sizeof(fileBuffer), fileLength); rc = readFile( inFile, reinterpret_cast<char *>(fileBuffer), writeLength, fromFile, toMachine, fileLength, bytesCopied); if (rc != kSTAFOk) { updateResultString(outputList, fileEntry, rc, osRC); fileLength = 0; connection->writeUInt(kSTAFFileReadError); break; } connection->writeUInt(kSTAFOk); connection->write(fileBuffer, writeLength); fileLength -= writeLength; ack = connection->readUInt(); if (ack != kSTAFOk) { updateResultString(outputList, fileEntry, ack, osRC); fileLength = 0; break; } bytesCopied += writeLength; gFSCopyManagerPtr->updateFileCopy( copyDataPtr, bytesCopied); } inFile.close(); } } } return kSTAFOk;}STAFRC_t recurseCopyDir(STAFFSEntryPtr entry, const STAFString &namePattern, const STAFString &extPattern, STAFString fromDir, bool keepEmptyDir, bool onlyDir, unsigned int entryTypesUInt, STAFConnectionPtr connection, STAFFSCaseSensitive_t caseSensitive, SET_STAFString textExtList , STAFString currentEOL, STAFString newEOL, int level, bool doCodepageConvert, STAFObjectPtr &outputList, STAFFSCopyManager::FSCopyDataPtr copyDataPtr, const STAFString &toMachine){ unsigned int osRC = 0; STAFRC_t rc = kSTAFOk; // Enumerate the files in the current entry STAFFSEnumPtr fileEnum = entry->enumerate(namePattern, extPattern, STAFFSEntryType_t(entryTypesUInt & ~kSTAFFSDirectory), kSTAFFSNoSort, caseSensitive); STAFString thisDir = entry->path().asString(); // relative toDirectory STAFString toDir = thisDir.subString(fromDir.length()); toDir = toDir.replace(kUTF8_BSLASH, kUTF8_SLASH); // If the thisDir is equal to fromDir, then the directory already exists // If there is at least one file to be copied or KEEPEMPTYDIRECTORIES // or ONLYDIRECTORIES option was used, then create the current directory. if ((thisDir != fromDir) && (onlyDir || keepEmptyDir || (fileEnum->isValid()))) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -