mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 14:16:09 -06:00
126 lines
2.4 KiB
OpenEdge ABL
126 lines
2.4 KiB
OpenEdge ABL
// These are String methods which are best inlined in heap allocator
|
|
|
|
void String0::LSet(const String0& s)
|
|
{
|
|
w[2] = s.w[2];
|
|
w[3] = s.w[3];
|
|
if(s.IsRef()) {
|
|
ptr = s.ptr;
|
|
if(ptr != (char *)(voidptr + 1))
|
|
AtomicInc(s.Ref()->refcount);
|
|
}
|
|
else {
|
|
ptr = (char *)MemoryAlloc32_i();
|
|
memcpy(qptr, s.qptr, 32); // optimizes to movups
|
|
}
|
|
}
|
|
|
|
void String0::LFree()
|
|
{
|
|
if(IsRef()) {
|
|
if(ptr != (char *)(voidptr + 1)) {
|
|
Rc *rc = Ref();
|
|
ASSERT(rc->refcount > 0);
|
|
if(AtomicDec(rc->refcount) == 0) MemoryFree(rc);
|
|
}
|
|
}
|
|
else
|
|
MemoryFree32_i(ptr);
|
|
}
|
|
|
|
force_inline
|
|
char *String0::Alloc_(int count, char& kind)
|
|
{
|
|
if(count < 32) {
|
|
kind = MEDIUM;
|
|
return (char *)MemoryAlloc32_i();
|
|
}
|
|
size_t sz = sizeof(Rc) + count + 1;
|
|
Rc *rc = (Rc *)MemoryAllocSz(sz);
|
|
rc->alloc = count == INT_MAX ? INT_MAX : (int)sz - sizeof(Rc) - 1;
|
|
rc->refcount = 1;
|
|
kind = min(rc->alloc, 255);
|
|
return rc->GetPtr();
|
|
}
|
|
|
|
char *String0::Alloc(int count, char& kind)
|
|
{
|
|
return Alloc_(count, kind);
|
|
}
|
|
|
|
void String0::SetL(const char *s, int len)
|
|
{
|
|
ptr = Alloc_(len, chr[KIND]);
|
|
memcpy8(ptr, s, len);
|
|
ptr[len] = 0;
|
|
LLen() = len;
|
|
SLen() = 15;
|
|
}
|
|
|
|
void String0::LCat(int c)
|
|
{
|
|
if(IsSmall()) {
|
|
qword *x = (qword *)MemoryAlloc32_i();
|
|
x[0] = q[0];
|
|
x[1] = q[1];
|
|
LLen() = SLen();
|
|
SLen() = 15;
|
|
chr[KIND] = MEDIUM;
|
|
qptr = x;
|
|
}
|
|
int l = LLen();
|
|
if(IsRef() ? !IsShared() && l < (int)Ref()->alloc : l < 31) {
|
|
ptr[l] = c;
|
|
ptr[LLen() = l + 1] = 0;
|
|
}
|
|
else {
|
|
char *s = Insert(l, 1, NULL);
|
|
s[0] = c;
|
|
s[1] = 0;
|
|
}
|
|
}
|
|
|
|
char *StringBuffer::Alloc(int count, int& alloc)
|
|
{
|
|
if(count <= 31) {
|
|
char *s = (char *)MemoryAlloc32_i();
|
|
alloc = 31;
|
|
return s;
|
|
}
|
|
else {
|
|
size_t sz = sizeof(Rc) + count + 1;
|
|
Rc *rc = (Rc *)MemoryAlloc(sz);
|
|
alloc = rc->alloc = (int)min((size_t)INT_MAX, sz - sizeof(Rc) - 1);
|
|
rc->refcount = 1;
|
|
return (char *)(rc + 1);
|
|
}
|
|
}
|
|
|
|
void StringBuffer::Set(String& s)
|
|
{
|
|
s.UnShare();
|
|
int l = s.GetLength();
|
|
if(s.GetAlloc() == 14) {
|
|
pbegin = (char *)MemoryAlloc32_i();
|
|
limit = pbegin + 31;
|
|
memcpy8(pbegin, s.Begin(), l);
|
|
pend = pbegin + l;
|
|
}
|
|
else {
|
|
pbegin = s.ptr;
|
|
pend = pbegin + l;
|
|
limit = pbegin + s.GetAlloc();
|
|
}
|
|
s.Zero();
|
|
}
|
|
|
|
void StringBuffer::Free()
|
|
{
|
|
if(pbegin == buffer)
|
|
return;
|
|
int all = (int)(limit - pbegin);
|
|
if(all == 31)
|
|
MemoryFree32_i(pbegin);
|
|
if(all > 31)
|
|
MemoryFree((Rc *)pbegin - 1);
|
|
}
|