CString BabelQuotedString (const CString &sString) { char *pPos = sString.GetASCIIZ(); char *pStart = (char *)_alloca(2 * sString.GetLength() + 2); char *pDest = pStart; while (*pPos) { if (*pPos == '\"') { *pDest++ = '\\'; *pDest++ = '\"'; } else if (*pPos == '\\') { *pDest++ = '\\'; *pDest++ = '\\'; } else *pDest++ = *pPos; pPos++; } *pDest = '\0'; return CString(pStart); }
int CAtomTable::AddAtomWithData (const CString &sString, void *pData, int iDataLen) // AddAtomWithData // // Adds an atom. If the atom does not exist, adds the given data also { // Hash the string int iHash = (utlHashFunctionCase((BYTE *)sString.GetASCIIZ(), sString.GetLength()) % ctHashTableSize); // See if we've found it int iNext = m_HashTable[iHash]; while (iNext != -1) { SEntry *pEntry = GetEntry(iNext); if (strEqualsCase(sString, pEntry->GetString())) return (m_iBaseAtom + iNext); iNext = pEntry->iNext; } // We did not find the atom, so add it return (m_iBaseAtom + AllocAtom(sString, iHash, pData, iDataLen)); }
CString pathStripExtension (const CString &sPath) // pathStripExtension // // Returns the path without the extension on the filename { char *pPos; int iLength; pPos = sPath.GetASCIIZ(); iLength = sPath.GetLength(); // Look for the extension while (iLength > 0) { if (pPos[iLength] == '.') break; iLength--; } // Return everything except the extension return strSubString(sPath, 0, iLength); }
bool CAtomTable::FindAtom (const CString &sString, int *retiAtom) // FindAtom // // Returns TRUE if the atom exists, FALSE otherwise { // Hash the string int iHash = (utlHashFunctionCase((BYTE *)sString.GetASCIIZ(), sString.GetLength()) % ctHashTableSize); // See if we've found it int iNext = m_HashTable[iHash]; while (iNext != -1) { SEntry *pEntry = GetEntry(iNext); if (strEqualsCase(sString, pEntry->GetString())) { if (retiAtom) *retiAtom = (m_iBaseAtom + iNext); return true; } iNext = pEntry->iNext; } // We did not find the atom return false; }
CString pathGetExtension (const CString &sPath) // pathGetExtension // // Returns the extension (without dot) { char *pPos; int iLength; pPos = sPath.GetASCIIZ(); iLength = sPath.GetLength(); // Look for the extension while (iLength > 0) { if (pPos[iLength] == '.') break; iLength--; } // Return the extension return strSubString(sPath, iLength + 1, -1); }
CString pathAddComponent (const CString &sPath, const CString &sComponent) // pathAddComponent // // Concatenates the given component to the given path and returns // the result // // sPath: full pathname to a directory (e.g. "c:\", "\\lawrence\cdrom", "d:\test") // sComponent: directory, filename, or wildcard. { CString sResult = sPath; int iPathLength = sResult.GetLength(); char *pString = sResult.GetASCIIZ(); // If the path name does not have a trailing backslash, add one if (!sPath.IsBlank() && pString[iPathLength-1] != '\\') sResult.Append(STR_PATH_SEPARATOR); // Now concatenate the component sResult.Append(sComponent); return sResult; }
bool pathExists (const CString &sPath) // pathExists // // Returns TRUE if the given path exists { DWORD dwResult = ::GetFileAttributes(sPath.GetASCIIZ()); return (dwResult != 0xffffffff); }
bool pathCreate (const CString &sPath) // pathCreate // // Makes sure that the given path exists. Creates all intermediate folders. // Returns TRUE if successful. { CString sTest = sPath; char *pPos = sTest.GetASCIIZ(); // Make sure the path exists from the top down. while (*pPos != '\0') { // Skip over this backslash while (*pPos == '\\' && *pPos != '0') pPos++; // Skip to the next backslash while (*pPos != '\\' && *pPos != '\0') pPos++; // Trim the path here and see if it exists so far char chSaved = *pPos; *pPos = '\0'; // If the path doesn't exist, create it. if (!pathExists(sTest)) { if (!::CreateDirectory(sTest.GetASCIIZ(), NULL)) return false; } *pPos = chSaved; } return true; }
bool pathIsAbsolute (const CString &sPath) // pathIsAbsolute // // Returns TRUE if the path is absolute { char *pPos = sPath.GetASCIIZ(); if (*pPos == '\\') return true; else if (*pPos != '\0' && pPos[1] == ':') return true; else return false; }
CString pathGetPath (const CString &sPath) // pathGetPath // // Returns the path without the filename { char *pStart = sPath.GetASCIIZ(); char *pPos = pStart + sPath.GetLength() + 1; // Look for the first backslash while (pPos > pStart && *(pPos - 1) != '\\') pPos--; return CString(pStart, pPos - pStart); }
int CAtomTable::AllocAtom (const CString &sString, int iHash, void *pExtraData, int iExtraDataLen) // AllocAtom // // Allocate a new atom { int iAtom = m_iCount; // Compute length of entry int iStringLen = sString.GetLength(); int iStringPad = ((~((DWORD)(iStringLen + 1))) + 1) & 0x3; int iEntryLen = sizeof(SEntry) // Header + iStringLen // String + 1 // '/0' terminator + iStringPad // Pad to 32-bits + iExtraDataLen; // Extra data // Allocate a new entry SEntry *pEntry = (SEntry *)(new char[iEntryLen]); pEntry->iNext = m_HashTable[iHash]; pEntry->iLen = -iStringLen; *((DWORD *)&pEntry->sStr) = 0; pEntry->sStr = CString(((char *)pEntry) + sizeof(SEntry), true); char *pSource = sString.GetASCIIZ(); char *pDest = (char *)(&pEntry[1]); while (*pSource) *pDest++ = *pSource++; *pDest = '\0'; // Copy any extra data if (pExtraData) { pDest += iStringPad; pSource = (char *)pExtraData; char *pSourceEnd = pSource + iExtraDataLen; while (pSource < pSourceEnd) *pDest++ = *pSource++; } // Figure out which segment to place the entry in int iSegment = (iAtom / ctSegmentSize); // Make sure this segment is allocated if (iSegment == m_Backbone.GetCount()) { SEntry **pSegment = new SEntry *[ctSegmentSize]; m_Backbone.Insert(pSegment); } ASSERT(iSegment < m_Backbone.GetCount()); // Place the entry in the segment int iSlot = (iAtom % ctSegmentSize); m_Backbone[iSegment][iSlot] = pEntry; // Update the hash table m_HashTable[iHash] = iAtom; // Update the count m_iCount++; // Done return iAtom; }
CString pathAbsolutePath (const CString &sPath) // pathAbsolutePath // // Makes the given path absolute (based on the current directory) // // Test: // // c:\ // \\leibowitz\c\ // \test\ // \test\test2 // .\test // ..\test\ // ..\..\test\ // test\test2 { enum States { stateStart, stateSingleDot, stateSingleSlash, stateComponent, stateFirstCharacter, }; // Get the current path. NOTE: GetCurrentDirectory does not return // a trailing backslash UNLESS the current directory is the root. char szCurrentDir[4096]; int iLen = ::GetCurrentDirectory(sizeof(szCurrentDir), szCurrentDir); ASSERT(iLen < sizeof(szCurrentDir)); char *pDest = szCurrentDir + iLen; // Append a backslash if (*(pDest - 1) != '\\') *pDest++ = '\\'; // We use szCurrentDir to build the resulting path. char *pPos = sPath.GetASCIIZ(); int iState = stateStart; while (*pPos != '\0') { switch (iState) { case stateStart: { // If we have a leading backslash then this is // either an absolute path or a UNC path. if (*pPos == '\\') iState = stateSingleSlash; // A leading dot means either this directory or one // directory up. else if (*pPos == '.') iState = stateSingleDot; // A character means a drive letter or a directory/filename else { iState = stateFirstCharacter; *pDest++ = *pPos; } break; } case stateSingleSlash: { // If we get a second slash then this is an absolute // UNC path name. if (*pPos == '\\') return sPath; // If we get character then this is an absolute path // starting with the current drive. else { pDest = szCurrentDir; while (*pDest != '\\' && *pDest != '\0') pDest++; pPos = sPath.GetASCIIZ(); while (*pPos != '\0') *pDest++ = *pPos++; *pDest = '\0'; return CString(szCurrentDir); } break; } case stateSingleDot: { // If we get a second dot then this says that we // should pop up one directory if (*pPos == '.') { pDest--; pDest--; while (*pDest != '\\') pDest--; pDest++; pPos++; // skip next backslash iState = stateStart; } // Otherwise, a slash means that we are relative // to the current directory. else if (*pPos == '\\') { iState = stateStart; } else ASSERT(false); break; } case stateFirstCharacter: { // A colon means that we've got an absolute path if (*pPos == ':') return sPath; // Otherwise, we've got a normal component else { *pDest++ = *pPos; iState = stateComponent; } break; } case stateComponent: { *pDest++ = *pPos; break; } } pPos++; } // Done *pDest = '\0'; return CString(szCurrentDir); }