mahlendur/_work/Data/Scripts/Content/LeGo_NewVer/StringBuilder.d
Daniel Heße 892a40ff0f Initial commit with Subversion-codebase from 13/05/2022.
Cleaned up the mess, at this time, only viable data get synced (_work directory for Gothic-data, miranda for mdc-scripts.
Need to symlink files to a working directory.
2022-05-13 17:38:52 +02:00

320 lines
No EOL
7.6 KiB
D

/***********************************\
STRINGBUILDER
\***********************************/
//========================================
// [intern] Klasse / Variablen
//========================================
class StringBuilder {
var int ptr;
var int cln;
var int cal;
};
const int _SB_Current = 0;
//========================================
// Aktiven StringBuilder setzen
//========================================
func void SB_Use(var int sb) {
_SB_Current = sb;
};
//========================================
// Aktiven StringBuilder holen
//========================================
func int SB_Get() {
return _SB_Current;
};
//========================================
// Neuen StringBuilder erstellen
//========================================
func int SB_New() {
SB_Use(MEM_Alloc(12));
return _SB_Current;
};
//========================================
// Buffer initialisieren (def: auto)
//========================================
func void SB_InitBuffer(var int size) {
var StringBuilder c; c = _^(_SB_Current);
if(c.ptr) {
MEM_Error("SB_InitBuffer: Der StringBuilder hat bereits einen Buffer.");
return;
};
if(size < 8) {
size = 8;
};
c.ptr = MEM_Alloc(size);
c.cln = 0;
c.cal = size;
};
//========================================
// Leeren (wird nicht zerstört!)
//========================================
func void SB_Clear() {
var StringBuilder c; c = _^(_SB_Current);
if(c.ptr) {
MEM_Free(c.ptr);
};
c.ptr = 0;
c.cln = 0;
c.cal = 0;
};
//========================================
// Stream entkoppeln
//========================================
func void SB_Release() {
MEM_Free(_SB_Current);
_SB_Current = 0;
};
//========================================
// StringBuilder komplett zerstören
//========================================
func void SB_Destroy() {
SB_Clear();
SB_Release();
};
//========================================
// Stream als String zurückgeben
//========================================
func string SB_ToString() {
var StringBuilder c; c = _^(_SB_Current);
if(!c.ptr) { return ""; };
var string ret; ret = "";
var zString z; z = _^(_@s(ret));
z.ptr = MEM_Alloc(c.cln+2)+1;
MEM_CopyBytes(c.ptr, z.ptr, c.cln);
z.len = c.cln;
z.res = c.cln;
return ret;
};
//========================================
// Stream als Pointer zurückgeben
//========================================
func int SB_GetStream() {
if(!_SB_Current) {
return 0;
};
return MEM_ReadInt(_SB_Current);
};
//========================================
// Kopie des Streams zurückgeben
//========================================
func int SB_ToStream() {
if(!_SB_Current) {
return 0;
};
var StringBuilder c; c = _^(_SB_Current);
var int p; p = MEM_Alloc(c.cln);
MEM_CopyBytes(c.ptr, p, c.cln);
return p;
};
//========================================
// Aktuelle Länge
//========================================
func int SB_Length() {
if(!_SB_Current) {
return 0;
};
return MEM_ReadInt(_SB_Current+4);
};
//========================================
// Rohbytes anhängen
//========================================
func void SBraw(var int ptr, var int len) {
var StringBuilder c; c = _^(_SB_Current);
if(!c.ptr) {
SB_InitBuffer(32);
};
var int n; n = c.cln + len;
if(n > c.cal) {
var int o; o = c.cal;
while(n > c.cal);
c.cal *= 2;
end;
c.ptr = MEM_Realloc(c.ptr, o, c.cal);
};
MEM_CopyBytes(ptr, c.ptr + c.cln, len);
c.cln = n;
};
//========================================
// String anhängen
//========================================
func void SB(var string s) {
var zString z; z = _^(_@s(s));
SBraw(z.ptr, z.len);
};
//========================================
// Int als ASCII anhängen
//========================================
func void SBi(var int i) {
SB(IntToString(i));
};
//========================================
// Buchstaben anhängen (ASCII)
//========================================
func void SBc(var int b) {
var StringBuilder c; c = _^(_SB_Current);
if(!c.ptr) {
SB_InitBuffer(32);
};
if(c.cln+4 > c.cal) {
c.ptr = MEM_Realloc(c.ptr, c.cal, c.cal<<1);
c.cal *= 2;
};
MEM_WriteInt(c.ptr+c.cln, b);
c.cln += 1;
};
//========================================
// Int als 4 Byte roh anhängen
//========================================
func void SBw(var int b) {
var StringBuilder c; c = _^(_SB_Current);
if(!c.ptr) {
SB_InitBuffer(32);
};
if(c.cln+4 > c.cal) {
c.ptr = MEM_Realloc(c.ptr, c.cal, c.cal<<1);
c.cal *= 2;
};
MEM_WriteInt(c.ptr+c.cln, b);
c.cln += 4;
};
//========================================
// Float anhängen (ASCII)
//========================================
func void SBflt(var float f) {
SB(FloatToString(f));
};
//========================================
// Int als Float anhängen (ASCII)
//========================================
func void SBf(var int f) {
f; MEM_Call(SBflt);
};
//========================================
// Länge setzen
//========================================
func void SB_SetLength(var int l) {
while(l > SB_Length());
SBw(0);
end;
MEM_WriteInt(_SB_Current+4, l);
};
//========================================
// STR_Escape / STR_Unescape
//========================================
const int STR_Sequences[33] = {
48, 49, 50, 51, 52, 53, 54, 97,
98, 116, 110, 118, 102, 114, 55, 56,
57, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 95
};
func string STR_Escape(var string s0) {
var int osb; osb = SB_Get();
var zString z; z = _^(_@s(s0));
const int sb = 0;
if(!sb) {
sb = SB_New();
};
SB_Use(sb);
SB_InitBuffer(z.len * 2);
var int i; i = 0;
var int l; l = z.len;
while(i < l);
var int c; c = MEM_ReadByte(z.ptr + i);
if(c == 92) { // '\'
SBc(92);
SBc(92);
}
else if(c < 33) {
SBc(92);
SBc(MEM_ReadStatArr(STR_Sequences, c));
}
else {
SBc(c);
};
i += 1;
end;
var string res; res = SB_ToString();
SB_Clear();
SB_Use(osb);
return res;
};
func string STR_Unescape(var string s0) {
var int osb; osb = SB_Get();
var zString z; z = _^(_@s(s0));
const int sb = 0;
if(!sb) {
sb = SB_New();
};
SB_Use(sb);
SB_InitBuffer(z.len);
var int i; i = 0;
var int l; l = z.len;
while(i < l);
var int c; c = MEM_ReadByte(z.ptr + i);
if(c == 92) { // '\'
i += 1;
c = MEM_ReadByte(z.ptr + i);
if(c == 92) {
SBc(92);
}
else {
var int j; j = 0;
while(j < 33);
var int n; n = MEM_ReadStatArr(STR_Sequences, j);
if(c == n) {
SBc(j);
break;
};
j += 1;
end;
};
}
else {
SBc(c);
};
i += 1;
end;
var string res; res = SB_ToString();
SB_Clear();
SB_Use(osb);
return res;
};
//========================================
// Hilfsfunktion STR_StartsWith
//========================================
func int STR_StartsWith(var string str, var string start) {
var zString z0; z0 = _^(_@s(str));
var zString z1; z1 = _^(_@s(start));
if(z1.len > z0.len) { return 0; };
MEM_CompareBytes(z0.ptr, z1.ptr, z1.len);
};