#pragma once #pragma pack(push, 1) template class StrTBuffer { private: //************************************************************************* //************************************************************************* ALLOC m_Alloc; STR* m_Data; long m_Len; long m_Size; // Read-Only-Flag: ist 1, wenn der Puffer auf einen konstanten externen // STR verweist // unsigned long m_Ro : 1; //************************************************************************* // Zum Erreichen der Fähigkeit, in unterschiedlichen Runtime-Umgebungen // (DLL's) Allozierungen vornehmen zu können, wird hier ein eigener // Allocator benutzt: über einen Zeiger wird ein globales Objekt angesprochen, // welches in der Umgebung des Moduls liegt, welches das Objekt erzeugte. //************************************************************************* STR* MyStrNew(unsigned long nElem) { // return (STR*)malloc(nElem*sizeof(STR)); return (STR*) m_Alloc.Alloc(nElem*sizeof(STR)); }; void MyStrDelete(STR* lpData) { // free(lpData); m_Alloc.Free((BYTE*)lpData); }; STR* MyStrRealloc(STR* lpData,unsigned long nElem) { // return (STR*) realloc(lpData,nElem*sizeof(STR)); return (STR*)m_Alloc.ReAlloc((BYTE*)lpData,nElem*sizeof(STR)); }; //************************************************************************* // Check if the buffer is able to hold nElem elements. // If the buffer is a constant one it mutates generally to dynamic allocated // memory because all functions that uses _chksize want to modify the data. // if bDup = TRUE the data is duplicated, if false the string is empty // after reallocation (to avoid unnessecary memory copys) //************************************************************************* long _chksize (long nElem, bool bDup = true) { if((nElem==m_Len)&&(m_Size>=nElem)) return 0; // if(nElem=0)) { _chksize(m_Len+len); memcpy(m_Data+m_Len,s,len*sizeof(STR)); m_Len += len; } return m_Len; } /* long Add(const STR& s,long len) { if(len<0) return m_Len; _chksize(m_Len+len); memcpy(m_Data+m_Len,&s,len*sizeof(STR)); m_Len += len; return m_Len; } */ long AddElem(const STR& c) { _chksize(m_Len+1); m_Data[m_Len++] = c; return m_Len; } //************************************************************************* // Insert-Funktion //************************************************************************* long Insert (long pos, STR const * s, long len) { if (len) { long leng = m_Len; if (pos < 0 || pos > leng) pos = leng; _chksize (long(leng + len + 1)); STR * buf = m_Data; if (pos < leng) memmove(buf + pos + len, buf + pos,(leng - pos)*sizeof(STR)); memcpy (buf + pos, s, len * sizeof(STR)); m_Len += len; } return m_Len; } //************************************************************************* // removes a part of the buffer //************************************************************************* long remove (long pos, long len) { if (pos >= 0 && pos < m_Len) { long leng = m_Len; if (len < 0 || (pos + len) > leng) len = long(leng - pos); if (len) { _chksize (0); memcpy (m_Data + pos, m_Data + pos + len, (leng - (pos + len))*sizeof(STR)); m_Len -= len; } } return m_Len; } //************************************************************************* // Replace a part of the buffer // pos = Position, ab welcher ersetzt werden soll // s = Source-Puffer // clen = Länge des zu ersetzenden Abschnittes im Originalstring // len = Länge des einzufügenden Puffers (s) //************************************************************************* long replace (long pos, STR const * s, long clen, long len) { if((s==NULL)||(len<0)||(pos<0)) return m_Len; if (pos >= 0) { long leng = m_Len; if (clen < 0 || (pos + clen) > leng) clen = long(leng - pos); if (pos > leng) pos = leng; _chksize (long(leng - clen + len + 1)); if (clen != len && clen) memmove (m_Data + pos + len, m_Data + pos + clen, (leng - (pos + clen - len))*sizeof(STR)); if (len) memcpy (m_Data + pos, s, len * sizeof(STR)); m_Len += long(len - clen); } return m_Len; } //***************************************************************************** //***************************************************************************** StrTBuffer & left (long len, STR padch) { if (len < 0) return right (long(-len), padch); long leng = m_Len; if (len != leng) { _chksize (long(len )); m_Len = len; if (len > leng) BlockSet(leng,padch,len - leng); } return *this; } //***************************************************************************** //***************************************************************************** StrTBuffer & right (long len, STR padch) { if (len < 0) return left(-1, padch); long leng = m_Len; if (len != leng) { _chksize (long(len )); if (len > leng) { memmove (m_Data + len - leng, m_Data, leng*sizeof(STR)); BlockSet(0,padch,len-leng); } else { // String muß schrumpfen, also herunterkopieren der Daten memmove(m_Data,m_Data+(leng-len),len*sizeof(STR)); }; m_Len = len; } return *this; } //***************************************************************************** //***************************************************************************** StrTBuffer & mid (long pos, long len, STR padch) { if (pos <= 0) return left(len, padch); long leng = m_Len; if (pos > leng) pos = leng; _chksize (long(len )); if (leng < len) // Are we padding? { long nlen = long((len - (leng - pos)) / 2); if (nlen > 0) { memmove (m_Data, m_Data + pos, (leng - pos)*sizeof(STR)); BlockSet((leng - pos),padch,nlen); m_Len -= long(pos - nlen); } } else if(leng > len) { // String muß schrumpfen: Block aus der Mitte heraus nach // links kopieren und Länge anpassen. memmove(m_Data,m_Data+pos,len*sizeof(STR)); m_Len = len; }; return *this; } //************************************************************************* //************************************************************************* STR* BlockSet(long DestOffs,STR& val,long cnt) { // if(DestOffs>m_Len) // return m_Data; // Wachsen angesagt? if(m_Len<(long)(DestOffs+cnt)) { m_Len = DestOffs+cnt; }; _chksize(m_Len); if(sizeof(STR)==1) { // Bescheuerte Konstruktion, weil STR nur unter der Bedingung // direkt als Parameter von memset benutzt werden kann, wenn // es sich um chars oder WCHARS handelt. Unter anderen Bedingugnen // läuft dieser Code sowieso nicht. (Wie könnte man dies zur Compilezeit // festlegen??? Wäre besser für die Laufzeit! int* lpInt = (int*)&val; memset(m_Data+DestOffs,*lpInt,cnt); } else if(sizeof(STR)==2) { int* lpInt = (int*)&val; wmemset((wchar_t*)m_Data+DestOffs,*lpInt,cnt); } else { for(long i = 0;im_Len)||(ScrOffs>m_Len)) return m_Data; _chksize(m_Len); if((DestOffs+cnt)>m_Len) cnt = m_Len - DestOffs; if((SrcOffs+cnt)>m_Len) cnt = m_Len - SrcOffs; memmove(m_Data+DestOffs,m_Data+SrcOffs,cnt*sizeof(STR)); } */ //************************************************************************* // Funktionen zum Ermitteln der Daten. //************************************************************************* // Liefert nur den Zeiger STR* Get(void) { return m_Data; } // Liefert den Zeiger und die Anzahl von Elementen ohne Terminierung STR* Get(long* nElem) { if(nElem) *nElem = m_Len; return m_Data; } // Liefert einen terminierten String. Ist der String ein Verweis auf // einen konstanten Puffer, so mutiert dieser automatisch zu einem dynamischen // Puffer STR* Get(const STR& TermElem,long* nElem) { // Mutiert den Puffer, falls er const ist _chksize(m_Len); m_Data[m_Len] = TermElem; if(nElem) *nElem = m_Len; return m_Data; } // Reserviert einen Puffer von einer bestimmten Länge void ReserveBuffer(long ReqSize) { if(ReqSize>=0) _chksize(ReqSize); } void ReserveBuffer(long ReqSize,STR& FillElem) { if(m_Size=m_Len) Clear(); else { _chksize(m_Len); memmove(m_Data,m_Data+nElem,(m_Len-nElem)*sizeof(STR)); m_Len -= nElem; }; return m_Len; } long TruncateRight(long nElem) { if(nElem>=m_Len) Clear(); else { m_Len -= nElem; _chksize(m_Len-nElem); } return m_Len; } long TruncateChr(STR& chr,bool left,bool right) { if(m_Len==0) return m_Len; unsigned long start,end; start = 0; end = 0; if(right) { for(long i=m_Len-1;i>=0;i--) { if(m_Data[i]!=chr) break; else end++; } } if(left) { for(start=0;startm_Size) len = m_Size; m_Len = len; }; }; #pragma pack(pop) typedef StrTBuffer StrTBufferW; typedef StrTBuffer StrTBufferC;