//++ ------------------------------------------------------------------------------------ // Details: Write data to existing opened file. // Type: Method. // Args: vData - (R) Text data. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMIUtilFileStd::Write( const CMIUtilString & vData ) { if( vData.size() == 0 ) return MIstatus::success; if( m_bFileError ) return MIstatus::failure; if( m_pFileHandle == nullptr ) { m_bFileError = true; SetErrorDescriptionn( MIRSRC( IDE_UTIL_FILE_ERR_WRITING_NOTOPEN ), m_fileNamePath.c_str() ); return MIstatus::failure; } // Get the string size MIuint size = vData.size(); if( ::fwrite( vData.c_str(), 1, size, m_pFileHandle ) == size ) { // Flush the data to the file ::fflush( m_pFileHandle ); return MIstatus::success; } // Not all of the data has been transferred m_bFileError = true; SetErrorDescriptionn( MIRSRC( IDE_UTIL_FILE_ERR_WRITING_FILE ), m_fileNamePath.c_str() ); return MIstatus::failure; }
//++ // Details: Check if two strings share equal contents. // Type: Method. // Args: vrLhs - (R) String A. // vrRhs - (R) String B. // Return: bool - True = yes equal, false - different. // Throws: None. //-- bool CMIUtilString::Compare(const CMIUtilString &vrLhs, const CMIUtilString &vrRhs) { // Check the sizes match if (vrLhs.size() != vrRhs.size()) return false; return (::strncmp(vrLhs.c_str(), vrRhs.c_str(), vrLhs.size()) == 0); }
//++ //------------------------------------------------------------------------------------ // Details: Perform a snprintf format style on a string data. A new string // object is // created and returned. // Type: Static method. // Args: vrFormat - (R) Format string data instruction. // vArgs - (R) Var list args of any type. // Return: CMIUtilString - Number of splits found in the string data. // Throws: None. //-- CMIUtilString CMIUtilString::FormatPriv(const CMIUtilString &vrFormat, va_list vArgs) { CMIUtilString strResult; MIint nFinal = 0; MIint n = vrFormat.size(); // IOR: mysterious crash in this function on some windows builds not able to // duplicate // but found article which may be related. Crash occurs in vsnprintf() or // va_copy() // Duplicate vArgs va_list argument pointer to ensure that it can be safely // used in // a new frame // http://julipedia.meroh.net/2011/09/using-vacopy-to-safely-pass-ap.html va_list argsDup; va_copy(argsDup, vArgs); // Create a copy va_list to reset when we spin va_list argsCpy; va_copy(argsCpy, argsDup); if (n == 0) return strResult; n = n << 4; // Reserve 16 times as much the length of the vrFormat std::unique_ptr<char[]> pFormatted; while (1) { pFormatted.reset(new char[n + 1]); // +1 for safety margin ::strncpy(&pFormatted[0], vrFormat.c_str(), n); // We need to restore the variable argument list pointer to the start again // before running vsnprintf() more then once va_copy(argsDup, argsCpy); nFinal = ::vsnprintf(&pFormatted[0], n, vrFormat.c_str(), argsDup); if ((nFinal < 0) || (nFinal >= n)) n += abs(nFinal - n + 1); else break; } va_end(argsCpy); va_end(argsDup); strResult = pFormatted.get(); return strResult; }
//++ ------------------------------------------------------------------------------------ // Details: Massage the data to behave correct when submitted to file. Insert extra log // specific text. The veType is there to allow in the future to parse the log and // filter in out specific types of message to make viewing the log more manageable. // Type: Method. // Args: vData - (R) Raw data. // veType - (R) Message type. // Return: CMIUtilString - Massaged data. // Throws: None. //-- CMIUtilString CMICmnLogMediumFile::MassagedData( const CMIUtilString & vData, const CMICmnLog::ELogVerbosity veType ) { const CMIUtilString strCr( "\n" ); CMIUtilString data; const MIchar verbosityCode( ConvertLogVerbosityTypeToId( veType ) ); const CMIUtilString dt( CMIUtilString::Format( "%s %s", m_strDate.c_str(), m_dateTime.GetTime().c_str() ) ); data = CMIUtilString::Format( "%c,%s,%s", verbosityCode, dt.c_str(), vData.c_str() ); data = ConvertCr( data ); // Look for EOL... const MIint pos = vData.rfind( strCr ); if( pos == (MIint) vData.size() ) return data; // ... did not have an EOL so add one data += GetLineReturn(); return data; }
//++ ------------------------------------------------------------------------------------ // Details: Return the resolved file's path for the given file. // Type: Method. // Args: vstrUnknown - (R) String assigned to path when resolved path is empty. // vwrResolvedPath - (RW) The original path overwritten with resolved path. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLLDBDebugSessionInfo::ResolvePath(const CMIUtilString &vstrUnknown, CMIUtilString &vwrResolvedPath) { if (vwrResolvedPath.size() < 1) { vwrResolvedPath = vstrUnknown; return MIstatus::success; } bool bOk = MIstatus::success; CMIUtilString::VecString_t vecPathFolders; const MIuint nSplits = vwrResolvedPath.Split("/", vecPathFolders); MIunused(nSplits); MIuint nFoldersBack = 1; // 1 is just the file (last element of vector) while (bOk && (vecPathFolders.size() >= nFoldersBack)) { CMIUtilString strTestPath; MIuint nFoldersToAdd = nFoldersBack; while (nFoldersToAdd > 0) { strTestPath += "/"; strTestPath += vecPathFolders[vecPathFolders.size() - nFoldersToAdd]; nFoldersToAdd--; } bool bYesAccessible = false; bOk = AccessPath(strTestPath, bYesAccessible); if (bYesAccessible) { vwrResolvedPath = strTestPath; return MIstatus::success; } else nFoldersBack++; } // No files exist in the union of working directory and debuginfo path // Simply use the debuginfo path and let the IDE handle it. return bOk; }