📄 staffsservice.cpp
字号:
/*****************************************************************************//* Software Testing Automation Framework (STAF) *//* (C) Copyright IBM Corp. 2001, 2004, 2005 *//* *//* This software is licensed under the Common Public License (CPL) V1.0. *//*****************************************************************************/ #include "STAF.h"#include "STAF_iostream.h"#include "STAF_fstream.h"#include "STAFProc.h"#include "STAFProcUtil.h"#include "STAFString.h"#include "STAFRefPtr.h"#include "STAFUtil.h"#include "STAFFSService.h"#include "STAFConnectionManager.h"#include "STAFVariablePool.h"#include "STAFException.h"#include "STAFFileSystem.h"#include "STAFHandleManager.h"#include "STAFFSCopyManager.h"#include "STAFTrace.h"#include "STAFConverter.h"#include "STAFThreadManager.h"#include <set>#include <string>#include <deque>#include <algorithm>typedef std::set<STAFString> SET_STAFString;typedef std::deque<STAFFSEntryPtr> STAFFSEntryList;static STAFMutexSem sStrictFSCopyTrustSem;static const STAFString sEnabled = "Enabled";static const STAFString sDisabled = "Disabled";static const unsigned int sMaxReadAttempts = 20;static const unsigned int sReadRetryDelay = 500; // 1/2 second (500ms)static const STAFString sPeriod(kUTF8_PERIOD);static const STAFString sDoublePeriod(sPeriod + sPeriod);static STAFMapClassDefinitionPtr fListLongInfoClass;static STAFMapClassDefinitionPtr fListDetailsInfoClass;// This table allows for lookup of a hex character (in UTF-8)static const char HEX_TABLE[] ={ // Here's the corresponding non-UTF-8 hex representation // '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // 'A', 'B', 'C', 'D', 'E', 'F' 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};struct STAFSortEnumByName{ STAFSortEnumByName(STAFFSCaseSensitive_t caseSensitive) : fCaseSensitive(caseSensitive) { /* Do nothing */ } bool operator()(STAFFSEntryPtr lhs, STAFFSEntryPtr rhs) { unsigned int comp = 0; if (fCaseSensitive == kSTAFFSCaseSensitive) { STAFStringCompareTo(lhs->path().asString().getImpl(), rhs->path().asString().getImpl(), &comp, 0); } else { STAFStringCompareTo(lhs->path().asString().toUpperCase().getImpl(), rhs->path().asString().toUpperCase().getImpl(), &comp, 0); } return (comp == 1); } STAFFSCaseSensitive_t fCaseSensitive;};static bool sortEnumBySize(STAFFSEntryPtr lhs, STAFFSEntryPtr rhs){ if (lhs->size().first < rhs->size().first) return true; if (lhs->size().first > rhs->size().first) return true; return (lhs->size().second < rhs->size().second);}static bool sortEnumByModTime(STAFFSEntryPtr lhs, STAFFSEntryPtr rhs){ return (lhs->modTime() < rhs->modTime());}STAFString getTypeString(STAFFSEntryType_t type){ switch (type) { case kSTAFFSFile: return "F"; case kSTAFFSSpecialDirectory: // Fall through case kSTAFFSDirectory: return "D"; case kSTAFFSPipe: return "P"; case kSTAFFSSocket: return "S"; case kSTAFFSSymLink: return "L"; case kSTAFFSBlkDev: return "B"; case kSTAFFSCharDev: return "C"; case kSTAFFSOther: return "O"; default: return "?"; }}unsigned int getTypeMaskFromString(const STAFString &typeString, bool includeSpecial){ STAFString upperTypeString = typeString.toUpperCase(); unsigned int entryTypesUInt = kSTAFFSNone; for (int i = 0; i < upperTypeString.length(STAFString::kChar); ++i) { STAFString thisChar = upperTypeString.subString(i, 1, STAFString::kChar); if ((thisChar == "!") && includeSpecial) { entryTypesUInt |= kSTAFFSSpecialDirectory; } else if (thisChar == "F") entryTypesUInt |= kSTAFFSFile; else if (thisChar == "D") entryTypesUInt |= kSTAFFSDirectory; else if (thisChar == "P") entryTypesUInt |= kSTAFFSPipe; else if (thisChar == "S") entryTypesUInt |= kSTAFFSSocket; else if (thisChar == "L") entryTypesUInt |= kSTAFFSSymLink; else if (thisChar == "B") entryTypesUInt |= kSTAFFSBlkDev; else if (thisChar == "C") entryTypesUInt |= kSTAFFSCharDev; else if (thisChar == "O") entryTypesUInt |= kSTAFFSOther; } return entryTypesUInt;}void updateResultString(STAFObjectPtr &outputList, STAFFSEntryPtr &entry, STAFRC_t rc, unsigned int osRC){ if (rc != kSTAFOk) { STAFObjectPtr errorInfoMap = STAFObject::createMap(); errorInfoMap->put("staf-map-class-name", "STAF/Service/FS/ErrorInfo"); errorInfoMap->put("name", entry->path().asString()); errorInfoMap->put("rc", STAFString(rc)); if (rc == kSTAFBaseOSError) errorInfoMap->put("osRC", STAFString(osRC)); // Add remaining map entries here outputList->append(errorInfoMap); }}STAFRC_t readFile(fstream &inFile, char *fileBuffer, unsigned int readLength, const STAFString fromFile, const STAFString toMachine, unsigned int fileLength, unsigned int currentPos){ /* Leave in (commented out) for future debugging purposes. // Make sure that currentPos is the correct current position in the file // (indicating the number of bytes read so far) now that we're no longer // using tellg() because it only returns an int which means it does not // support files >= 2G. if (currentPos <= (INT_MAX - readLength)) { int currentPosInt = inFile.tellg();// Save current position before read unsigned int myCurrentPos = (unsigned int)currentPosInt; if (myCurrentPos != currentPos) { cout << "STAFFSService::readFile() - MISMATCH: myCurrentPos=" << myCurrentPos << " currentPos=" << currentPos << endl; } } */ // Read a block of data from the file inFile.read(fileBuffer, readLength); if (inFile.good()) return kSTAFOk; // Read was successful // If get eof condition reading the file, make sure that all bytes have // really been read to make sure it's not a "pre-mature" eof condition. // // Note: A "pre-mature" eof condition can occur on Windows when copying // from a file on a mapped drive (in text mode) and the drive is // disconnected. if (inFile.eof() && (currentPos + inFile.gcount() == fileLength)) return kSTAFOk; // Completed reading the file // The read failed. Retry the read up to sMaxReadAttempts times with a // delay between each attempt. for (int readAttempt = 1; !inFile.good() && readAttempt <= sMaxReadAttempts; readAttempt++) { if (inFile.fail()) { // Recoverable read error // Log a warning tracepoint message STAFString warningMsg( "STAFFSService::readFile() - Read attempt #" + STAFString(readAttempt) + " failed while copying file " + fromFile + " to machine " + toMachine + " after reading " + STAFString(currentPos) + " bytes"); STAFTrace::trace(kSTAFTraceWarning, warningMsg); // Delay and retry read after clearing any error flags and // repositioning the file pointer STAFThreadManager::sleepCurrentThread( sReadRetryDelay); inFile.clear(); if (readAttempt == sMaxReadAttempts) { // Before the last read attempt, try closing the file and // reopening it first to see if that fixes the problem inFile.close(); inFile.open(fromFile.toCurrentCodePage()->buffer(), ios::in | STAF_ios_binary); } if (currentPos <= INT_MAX) { inFile.seekg(currentPos, ios::beg); inFile.read(fileBuffer, readLength); } else { // Reading a large file, so need to do multiple seekg()'s // because seekg() only accepts an integer for the offset inFile.seekg(INT_MAX, ios::beg); unsigned int setPos = currentPos - INT_MAX; while (setPos > INT_MAX) { inFile.seekg(INT_MAX, ios::cur); setPos = setPos - INT_MAX; } inFile.seekg((int)setPos, ios::cur); if (inFile.good()) inFile.read(fileBuffer, readLength); } } else if (inFile.bad()) { // Unrecoverable read error. break; } } if (!inFile.good()) { // Unrecoverable read failure return kSTAFFileReadError; } return kSTAFOk;}STAFRC_t copyDirectory(STAFFSEnumPtr childEnum, STAFString fromDir, STAFConnectionPtr connection, SET_STAFString textExtList, STAFString currentEOL, STAFString newEOL, bool doCodepageConvert, int level, STAFFSCaseSensitive_t caseSensitive, STAFObjectPtr &outputList, STAFFSCopyManager::FSCopyDataPtr copyDataPtr, const STAFString &toMachine){ unsigned int osRC = 0; STAFRC_t rc = kSTAFOk; STAFRC_t ack = kSTAFOk; STAFString ackResult; STAFFSEntryPtr fileEntry; STAFString toFile; bool textTransfer; SET_STAFString::iterator i; bool doConvert = doCodepageConvert; int currentEOLLength=currentEOL.length(); for (; childEnum->isValid(); childEnum->next()) { fileEntry = childEnum->entry(); STAFString fromFile = fileEntry->path().asString(); fromFile = fromFile.replace(kUTF8_BSLASH, kUTF8_SLASH); toFile = fromFile.subString(fromDir.length()); fstream inFile(fromFile.toCurrentCodePage()->buffer(), ios::in | STAF_ios_binary); // determine if this file is to be text or binary textTransfer = false; unsigned int isMatch; for(i = textExtList.begin(); i != textExtList.end(); i++) { isMatch = STAFFileSystem::matchesWildcards(fileEntry->path(). extension(), *i, caseSensitive); textTransfer |= (isMatch > 0); } doCodepageConvert = doConvert && textTransfer; textTransfer &= (!newEOL.isEqualTo(currentEOL)); if (!inFile) { updateResultString(outputList, fileEntry, kSTAFFileOpenError, osRC); continue; } // Get the size of the file (upperSize and lowerSize). // If the file size is < 4G, upperSize will be zero. unsigned int upperSize = fileEntry->size().first; unsigned int lowerSize = fileEntry->size().second; if ((upperSize > 0) || (lowerSize > UINT_MAX)) { // File size exceeds the maximum that the FS service handles updateResultString(outputList, fileEntry, kSTAFFileReadError, osRC); // XXX: How provide a better error message such as the following? //"File size exceeds maximum size ") + UINT_MAX + ") supported" continue; } unsigned int fileLength = lowerSize; connection->writeUInt(kSTAFFSContinueCopy); connection->writeUInt(kSTAFFSFile); connection->writeString(toFile); if (level > 1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -