Imports the current Win32 source for the pod-racing game 'Red Planet', built on the MUNGA engine and its L4 (Win32/DirectX) platform layer: - MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend - RP / RP_L4: Red Planet game logic and Win32 application - DivLoader, Setup1: asset loader and installer project - lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies Removed stale Subversion metadata and added .gitignore/.gitattributes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
445 lines
9.6 KiB
C++
445 lines
9.6 KiB
C++
#include "munga.h"
|
|
#include "cstr.h"
|
|
#include "memstrm.h"
|
|
|
|
//namespace Munga
|
|
//{
|
|
rString StringRepresentation::operator+=(char chr)
|
|
{
|
|
Check(this);
|
|
size_t len = strlen(&firstByte);
|
|
*(&firstByte + len++) = chr;
|
|
*(&firstByte + len) = '\0';
|
|
return *this;
|
|
}
|
|
|
|
#if defined(USE_SIGNATURE)
|
|
int Is_Signature_Bad(const StringRepresentation *)
|
|
{
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
MemoryStream& MemoryStream_Read(MemoryStream *stream, StringRepresentation *str)
|
|
{
|
|
Check(stream);
|
|
Check(str);
|
|
|
|
pString ptr = *str;
|
|
for (*stream >> ptr[(size_t)0]; ptr[(size_t)0]; ++ptr)
|
|
*stream >> ptr[(size_t)0];
|
|
return *stream;
|
|
}
|
|
|
|
MemoryStream& MemoryStream_Write(MemoryStream *stream, const StringRepresentation &str)
|
|
{
|
|
Check(stream);
|
|
Check(&str);
|
|
|
|
return stream->WriteBytes((const char*)str, str.GetLength() + 1);
|
|
}
|
|
|
|
#define DELETE_FILL_CHAR ('0')
|
|
|
|
size_t CStringRepresentation::allocationIncrement = 8;
|
|
|
|
inline size_t CStringRepresentation::CalculateSize(size_t needed)
|
|
{
|
|
Verify(!Small_Enough(allocationIncrement));
|
|
size_t x = ((needed + allocationIncrement) / allocationIncrement) * allocationIncrement;
|
|
return x;
|
|
}
|
|
|
|
CStringRepresentation::CStringRepresentation()
|
|
{
|
|
stringLength = 0;
|
|
stringSize = 0;
|
|
stringText = NULL;
|
|
referenceCount = 0;
|
|
}
|
|
|
|
CStringRepresentation::CStringRepresentation(const CStringRepresentation &str)
|
|
{
|
|
Check(&str);
|
|
stringLength = str.stringLength;
|
|
stringSize = str.stringSize;
|
|
|
|
if (str.stringText == NULL)
|
|
stringText = NULL;
|
|
else
|
|
{
|
|
stringText = new char[stringSize];
|
|
Register_Pointer(stringText);
|
|
Mem_Copy(stringText, str.stringText, stringLength + 1, stringSize);
|
|
}
|
|
referenceCount = 0;
|
|
}
|
|
|
|
CStringRepresentation::CStringRepresentation(const char *cstr)
|
|
{
|
|
if ((cstr == NULL) || (cstr[0] == '\x00'))
|
|
{
|
|
stringLength = 0;
|
|
stringSize = 0;
|
|
stringText = NULL;
|
|
}
|
|
else
|
|
{
|
|
stringLength = strlen(cstr);
|
|
stringSize = CalculateSize(stringLength);
|
|
|
|
stringText = new char[stringSize];
|
|
Register_Pointer(stringText);
|
|
Mem_Copy(stringText, cstr, stringLength + 1, stringSize);
|
|
}
|
|
referenceCount = 0;
|
|
}
|
|
|
|
CStringRepresentation::~CStringRepresentation()
|
|
{
|
|
if (stringText != NULL)
|
|
{
|
|
#if DEBUG_LEVEL>0
|
|
memset(stringText, DELETE_FILL_CHAR, stringSize);
|
|
#endif
|
|
Unregister_Pointer(stringText);
|
|
delete[] stringText;
|
|
}
|
|
}
|
|
|
|
Logical CStringRepresentation::TestInstance() const
|
|
{
|
|
if (stringText == NULL)
|
|
{
|
|
Verify(stringSize == 0);
|
|
Verify(stringLength == 0);
|
|
}
|
|
else
|
|
{
|
|
Verify(stringSize > 0);
|
|
Verify(stringLength == strlen(stringText));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
CStringRepresentation CStringRepresentation::operator = (const CStringRepresentation &str)
|
|
{
|
|
Check(this);
|
|
|
|
if (this == &str)
|
|
return *this;
|
|
|
|
if (stringText != NULL)
|
|
{
|
|
#if DEBUG_LEVEL>0
|
|
memset(stringText, DELETE_FILL_CHAR, stringSize);
|
|
#endif
|
|
Unregister_Pointer(stringText);
|
|
delete[] stringText;
|
|
}
|
|
|
|
Check(&str);
|
|
stringLength = str.stringLength;
|
|
stringSize = str.stringSize;
|
|
|
|
if (stringSize == 0)
|
|
stringText = NULL;
|
|
else
|
|
{
|
|
stringText = new char[stringSize];
|
|
Register_Pointer(stringText);
|
|
Mem_Copy(stringText, str.stringText, stringLength + 1, stringSize);
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
CStringRepresentation CStringRepresentation::operator = (const char *cstr)
|
|
{
|
|
Check(this);
|
|
|
|
if (stringText != NULL)
|
|
{
|
|
#if DEBUG_LEVEL>0
|
|
memset(stringText, DELETE_FILL_CHAR, stringSize);
|
|
#endif
|
|
Unregister_Pointer(stringText);
|
|
delete[] stringText;
|
|
}
|
|
|
|
if ((cstr == NULL) || (cstr[0] == '\x00'))
|
|
{
|
|
stringLength = 0;
|
|
stringSize = 0;
|
|
stringText = NULL;
|
|
}
|
|
else
|
|
{
|
|
stringLength = strlen(cstr);
|
|
stringSize = CalculateSize(stringLength);
|
|
|
|
stringText = new char[stringSize];
|
|
Register_Pointer(stringText);
|
|
Mem_Copy(stringText, cstr, stringLength + 1, stringSize);
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
CStringRepresentation operator + (const CStringRepresentation &str1, const CStringRepresentation &str2)
|
|
{
|
|
Check(&str1);
|
|
Check(&str2);
|
|
|
|
CStringRepresentation temp;
|
|
|
|
unsigned long totalLen = str1.stringLength + str2.stringLength;
|
|
|
|
if (totalLen == 0)
|
|
return temp;
|
|
|
|
temp.stringLength = 0;
|
|
temp.stringSize = CStringRepresentation::CalculateSize((size_t)totalLen);
|
|
temp.stringText = new char[temp.stringSize];
|
|
Register_Pointer(temp.stringText);
|
|
|
|
Verify(temp.stringSize >= 1);
|
|
temp.stringText[0] = '\000';
|
|
|
|
if (str1.stringText != NULL)
|
|
{
|
|
Mem_Copy(temp.stringText, str1.stringText, str1.stringLength, temp.stringSize);
|
|
temp.stringLength = str1.stringLength;
|
|
}
|
|
|
|
if (str2.stringText != NULL)
|
|
{
|
|
Verify(temp.stringLength < temp.stringSize);
|
|
Mem_Copy(&temp.stringText[temp.stringLength], str2.stringText, str2.stringLength + 1, temp.stringSize - temp.stringLength);
|
|
temp.stringLength += str2.stringLength;
|
|
}
|
|
|
|
Check(&temp);
|
|
return temp;
|
|
}
|
|
|
|
CStringRepresentation operator + (const CStringRepresentation &str, char ch)
|
|
{
|
|
Check(&str);
|
|
|
|
CStringRepresentation temp;
|
|
|
|
if (str.stringText == NULL)
|
|
{
|
|
temp.stringLength = 1;
|
|
temp.stringSize = CStringRepresentation::allocationIncrement;
|
|
temp.stringText = new char [temp.stringSize];
|
|
Register_Pointer(temp.stringText);
|
|
|
|
Verify(temp.stringSize >= 2);
|
|
temp.stringText[0] = ch;
|
|
temp.stringText[1] = '\000';
|
|
}
|
|
else
|
|
{
|
|
Verify(str.stringLength != UINT_MAX);
|
|
|
|
temp.stringLength = str.stringLength + 1;
|
|
|
|
if (temp.stringLength == str.stringSize)
|
|
temp.stringSize = str.stringSize + CStringRepresentation::allocationIncrement;
|
|
else
|
|
temp.stringSize = str.stringSize;
|
|
|
|
temp.stringText = new char[temp.stringSize];
|
|
Register_Pointer(temp.stringText);
|
|
Mem_Copy(temp.stringText, str.stringText, str.stringLength, temp.stringSize);
|
|
|
|
Verify(str.stringLength < temp.stringSize);
|
|
Verify(temp.stringLength < temp.stringSize);
|
|
temp.stringText[str.stringLength] = ch;
|
|
temp.stringText[temp.stringLength] = '\000';
|
|
}
|
|
|
|
Check(&temp);
|
|
return temp;
|
|
}
|
|
|
|
int CStringRepresentation::Compare(const CStringRepresentation &str) const
|
|
{
|
|
Check(this);
|
|
Check(&str);
|
|
|
|
// handle special cases where one string is empty
|
|
if (stringText == NULL)
|
|
{
|
|
if (str.stringText == NULL)
|
|
return 0;
|
|
else
|
|
return -1;
|
|
}
|
|
if (str.stringText == NULL)
|
|
return 1;
|
|
|
|
return strcmp(stringText, str.stringText);
|
|
}
|
|
|
|
CStringRepresentation CStringRepresentation::GetNthToken(size_t nth_token, char *delimiters) const
|
|
{
|
|
Check(this);
|
|
|
|
//
|
|
// Which delimters to use
|
|
//
|
|
char *delimter_string = " \t,";
|
|
|
|
if (delimiters != NULL)
|
|
delimter_string = delimiters;
|
|
Check_Pointer(delimter_string);
|
|
|
|
//
|
|
// Make temporary
|
|
//
|
|
CStringRepresentation temp(*this);
|
|
|
|
if (temp.stringText == NULL)
|
|
return temp;
|
|
|
|
//
|
|
// Parse string with strtok
|
|
//
|
|
size_t i;
|
|
char *ptr;
|
|
|
|
Check_Pointer(temp.stringText);
|
|
ptr = strtok(temp.stringText, delimter_string);
|
|
for (i = 0; i < nth_token; i++)
|
|
if ((ptr = strtok(NULL, delimter_string)) == NULL)
|
|
break;
|
|
|
|
if (ptr == NULL)
|
|
{
|
|
CStringRepresentation null_return;
|
|
return null_return;
|
|
}
|
|
CStringRepresentation token_return(ptr);
|
|
return token_return;
|
|
}
|
|
|
|
#if 0
|
|
void CStringRepresentation::ToUpper()
|
|
{
|
|
Check(this);
|
|
if (stringText != NULL)
|
|
strupr(stringText);
|
|
}
|
|
|
|
void CStringRepresentation::ToLower()
|
|
{
|
|
Check(this);
|
|
if (stringText != NULL)
|
|
strlwr(stringText);
|
|
}
|
|
#endif
|
|
|
|
MemoryStream& MemoryStream_Read(MemoryStream *stream, CStringRepresentation *str)
|
|
{
|
|
Check(stream);
|
|
Check(str);
|
|
|
|
size_t string_length;
|
|
char *ptr;
|
|
|
|
MemoryStream_Read(stream, &string_length);
|
|
ptr = new char[string_length + 1];
|
|
Register_Pointer(ptr);
|
|
stream->ReadBytes(ptr, string_length + 1);
|
|
|
|
*str = ptr;
|
|
|
|
Unregister_Pointer(ptr);
|
|
delete[] ptr;
|
|
|
|
Check(str);
|
|
return *stream;
|
|
}
|
|
|
|
MemoryStream& MemoryStream_Write(MemoryStream *stream, const CStringRepresentation &str)
|
|
{
|
|
Check(stream);
|
|
Check(&str);
|
|
|
|
MemoryStream_Write(stream, &str.stringLength);
|
|
return stream->WriteBytes(str.stringText, str.stringLength + 1);
|
|
}
|
|
|
|
void Convert_From_Ascii(const char *str, CStringRepresentation *value)
|
|
{
|
|
#if 0
|
|
Check_Pointer(str);
|
|
Check(value);
|
|
*value = str;
|
|
#else
|
|
if (str == NULL)
|
|
Fail("Convert_From_Ascii - str == NULL");
|
|
if (value == NULL)
|
|
Fail("Convert_From_Ascii - value == NULL");
|
|
*value = str;
|
|
#endif
|
|
}
|
|
|
|
CString CString::operator = (const CString &str)
|
|
{
|
|
Check(this);
|
|
Check(&str);
|
|
|
|
if (this == &str)
|
|
return *this;
|
|
|
|
Check(representation);
|
|
representation->DecrementReferenceCount();
|
|
representation = str.representation;
|
|
representation->IncrementReferenceCount();
|
|
return *this;
|
|
}
|
|
|
|
CString CString::operator = (const char *cstr)
|
|
{
|
|
Check(representation);
|
|
representation->DecrementReferenceCount();
|
|
representation = new CStringRepresentation(cstr);
|
|
Register_Object(representation);
|
|
representation->IncrementReferenceCount();
|
|
return *this;
|
|
}
|
|
|
|
MemoryStream& MemoryStream_Read(MemoryStream *stream, CString *str)
|
|
{
|
|
Check(str);
|
|
Check(str->representation);
|
|
str->representation->DecrementReferenceCount();
|
|
str->representation = new CStringRepresentation;
|
|
Register_Object(str->representation);
|
|
str->representation->IncrementReferenceCount();
|
|
Verify(str->representation->referenceCount == 1);
|
|
return MemoryStream_Read(stream, str->representation);
|
|
}
|
|
|
|
void Convert_From_Ascii(const char *str, CString *value)
|
|
{
|
|
Check(value);
|
|
Check(value->representation);
|
|
value->representation->DecrementReferenceCount();
|
|
value->representation = new CStringRepresentation;
|
|
Register_Object(value->representation);
|
|
value->representation->IncrementReferenceCount();
|
|
Verify(value->representation->referenceCount == 1);
|
|
Convert_From_Ascii(str, value->representation);
|
|
}
|
|
//}
|
|
|
|
#if defined(TEST_CLASS)
|
|
#include "cstr.tcp"
|
|
#endif
|
|
|