Files
firestorm/Gameleap/code/mw4/Libraries/stuff/MString.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

496 lines
12 KiB
C++

//===========================================================================//
// 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 <mbstring.h>
#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<int_len;i++)
{
r = ((int *)ptr)[i];
_asm mov ecx, i
_asm ror r, cl
ret += r;
}
switch (len&3)
{
case 1:
case 2:
ret += ((WORD *)ptr)[i*2];
break;
case 3:
ret += ((int *)ptr)[i];
break;
}
return (ret & 0x7fffffff);
}