//===========================================================================// // File: string.cpp // // Project: MUNGA // // Contents: // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 03/26/95 ECH Initial coding. // //---------------------------------------------------------------------------// // Copyright (C) 1994, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include "StuffHeaders.hpp" #include #define __mbsrchr(s,c) (char*)_mbsrchr((const unsigned char*)(s),(c)) //############################################################################# //############################## MString ################################ //############################################################################# MString *MString::s_Empty = NULL; HGOSHEAP g_MStringHeap = NULL; // //############################################################################# //############################################################################# // void MString::InitializeClass() { Verify(!g_MStringHeap); g_MStringHeap = gos_CreateMemoryHeap("MString"); Check_Pointer(g_MStringHeap); Verify(!s_Empty); s_Empty = new MString(""); Check_Object(s_Empty); } // //############################################################################# //############################################################################# // void MString::TerminateClass() { Check_Object(s_Empty); delete s_Empty; s_Empty = NULL; Check_Pointer(g_MStringHeap); gos_DestroyMemoryHeap(g_MStringHeap); g_MStringHeap = NULL; } // //############################################################################# //############################################################################# // MString::MString(const char *cstr) { gos_PushCurrentHeap(g_MStringHeap); if (!cstr) m_text = NULL; else { unsigned t = strlen(cstr)+2; m_text = new char[t]; Check_Pointer(m_text); *m_text++ = 1; Mem_Copy(m_text, cstr, t-1, t-1); } gos_PopCurrentHeap(); } // //############################################################################# //############################################################################# // MString::MString( const char *cstr1, const char *cstr2 ) { Check_Pointer(cstr1); Check_Pointer(cstr2); gos_PushCurrentHeap(g_MStringHeap); unsigned t1 = strlen(cstr1); unsigned t2 = strlen(cstr2); unsigned t = t1 + t2 + 2; m_text = new char[t]; Check_Pointer(m_text); *m_text++ = 1; Mem_Copy(m_text, cstr1, t1, t-1); Mem_Copy(m_text+t1, cstr2, t2+1, t-1-t1); gos_PopCurrentHeap(); } // //############################################################################# //############################################################################# // MString::MString( const char *cstr, char ch ) { Check_Pointer(cstr); Verify(ch != '\0'); gos_PushCurrentHeap(g_MStringHeap); unsigned t = strlen(cstr)+3; m_text = new char[t]; Check_Pointer(m_text); *m_text++ = 1; Mem_Copy(m_text, cstr, t-3, t-1); m_text[t-3] = ch; m_text[t-2] = '\0'; gos_PopCurrentHeap(); } // //############################################################################# //############################################################################# // void MString::AllocateLength(unsigned length) { Check_Object(this); gos_PushCurrentHeap(g_MStringHeap); DetachReference(); if (!length) m_text = NULL; else { unsigned t = length+2; m_text = new char[t]; Check_Pointer(m_text); *m_text++ = 1; #if defined(_ARMOR) memset(m_text, ' ', length); m_text[length] = '\0'; #endif } gos_PopCurrentHeap(); } // //############################################################################# //############################################################################# // MString& MString::operator=(const MString &str) { Check_Object(this); Check_Object(&str); Verify(!m_text || m_text != str.m_text || m_text[-1]>1); DetachReference(); m_text = str.m_text; if (m_text) { char *count = m_text-1; Check_Pointer(count); Verify(*count != -1); ++(*count); } return *this; } // //############################################################################# //############################################################################# // MString& MString::operator=(const char *cstr) { Check_Object(this); Verify(!m_text || m_text != cstr || m_text[-1]>1); DetachReference(); if (!cstr) m_text = NULL; else { gos_PushCurrentHeap(g_MStringHeap); unsigned t = strlen(cstr)+2; m_text = new char[t]; Check_Pointer(m_text); *(m_text++) = 1; Mem_Copy(m_text, cstr, t-1, t-1); gos_PopCurrentHeap(); } return *this; } // //############################################################################# //############################################################################# // bool Stuff::Close_Enough( const char *str1, const char *str2, Scalar e ) { Check_Pointer(str1); Check_Pointer(str2); return !_stricmp(str1, str2); } // //############################################################################# //############################################################################# // MString MString::GetNthToken( size_t nth_token, const char *delimiters ) const { Check_Object(this); if (!m_text) return *this; // // Which delimters to use // const char *delimiter_string = " \t,"; if (delimiters != NULL) delimiter_string = delimiters; Check_Pointer(delimiter_string); // // Parse string with strtok // MString temp((const char*)*this); size_t i; Check_Pointer(temp.m_text); char *ptr = strtok(temp, delimiter_string); for (i = 0; i < nth_token; i++) { if ((ptr = strtok(NULL, delimiter_string)) == NULL) break; } return MString(ptr); } // //############################################################################# //############################################################################# // void MString::ToUpper() { Check_Object(this); Check_Pointer(m_text); // //----------------------------------------------------------------- // If there is more that one reference to this string, split it off //----------------------------------------------------------------- // if ((BYTE)m_text[-1] > 1) operator=(operator char*()); strupr(m_text); } // //############################################################################# //############################################################################# // void MString::ToLower() { Check_Object(this); Check_Pointer(m_text); // //----------------------------------------------------------------- // If there is more that one reference to this string, split it off //----------------------------------------------------------------- // if ((BYTE)m_text[-1] > 1) operator=(operator char*()); strlwr(m_text); } // //############################################################################# //############################################################################# // // Removes spaces and makes them _ characters void MString::RemoveSpaces() { Check_Object(this); Check_Pointer(m_text); // //----------------------------------------------------------------- // If there is more that one reference to this string, split it off //----------------------------------------------------------------- // if ((BYTE)m_text[-1] > 1) operator=(operator char*()); unsigned len = strlen(m_text); for (int i = 0; i < len; i++) { if (m_text[i] == ' ') m_text[i] = '_'; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MString& MString::StripExtension() { Check_Object(this); Check_Pointer(m_text); // //----------------------------------------------------------------- // If there is more that one reference to this string, split it off //----------------------------------------------------------------- // if ((BYTE)m_text[-1] > 1) operator=(operator char*()); char *p = strrchr(m_text, '.'); if (p) *p = '\0'; return *this; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MString& MString::IsolateDirectory() { Check_Object(this); Check_Pointer(m_text); // //----------------------------------------------------------------- // If there is more that one reference to this string, split it off //----------------------------------------------------------------- // if ((BYTE)m_text[-1] > 1) operator=(operator char*()); char *p = __mbsrchr(m_text, '\\'); if (p) *++p = '\0'; else *m_text = '\0'; return *this; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MString& MString::StripDirectory() { Check_Object(this); Check_Pointer(m_text); // //----------------------------------------------------------------- // If there is more that one reference to this string, split it off //----------------------------------------------------------------- // if ((BYTE)m_text[-1] > 1) operator=(operator char*()); char *p = __mbsrchr(m_text, '\\'); if (p) { char *q = m_text; do { *q++ = *++p; } while (*p); } return *this; } // //############################################################################# //############################################################################# // MemoryStream& MemoryStreamIO::Read( MemoryStream *stream, MString *str ) { Check_Object(stream); Check_Object(str); size_t string_length; Read(stream, &string_length); if (string_length > 0) { str->AllocateLength(string_length); Verify(str->GetLength() == string_length); stream->ReadBytes(str->m_text, string_length + 1); } Check_Object(str); return *stream; } // //############################################################################# //############################################################################# // MemoryStream& MemoryStreamIO::Write( MemoryStream *stream, const MString *str ) { Check_Object(stream); Check_Object(str); unsigned len = 0; if (str->m_text) len = str->GetLength(); Write(stream, &len); if (len > 0) stream->WriteBytes(str->m_text, len + 1); return *stream; } // //############################################################################# //############################################################################# // unsigned MString::ComputeHash(const char* ptr) { // // Verify that the unsigned is 32 bits wide // Hash value is first 16 bits of fileID and first 16 bits of recordID // Verify(sizeof(unsigned) == sizeof(DWORD)); unsigned ret = 0; register i, r, len = strlen(ptr), int_len = len >> 2; for(i=0;i