📄 contain.cxx
字号:
{
if (allocatedDynamically && theArray != NULL)
free(theArray);
theArray = (char *)buffer;
reference->size = bufferSize;
allocatedDynamically = FALSE;
}
void * PAbstractArray::GetPointer(PINDEX minSize)
{
PAssert(SetMinSize(minSize), POutOfMemory);
return theArray;
}
BOOL PAbstractArray::Concatenate(const PAbstractArray & array)
{
if (!allocatedDynamically || array.elementSize != elementSize)
return FALSE;
PINDEX oldLen = GetSize();
PINDEX addLen = array.GetSize();
if (!SetSize(oldLen + addLen))
return FALSE;
memcpy(theArray+oldLen*elementSize, array.theArray, addLen*elementSize);
return TRUE;
}
void PAbstractArray::PrintNumbersOn(ostream & strm, PINDEX size, BOOL is_signed) const
{
PINDEX line_width = strm.width();
if (line_width == 0)
line_width = 16/size;
PINDEX indent = strm.precision();
PINDEX val_width;
switch (strm.flags()&ios::basefield) {
case ios::hex :
val_width = size*2;
is_signed = FALSE;
break;
case ios::oct :
val_width = ((size*8)+2)/3;
is_signed = FALSE;
break;
default :
switch (size) {
case 1 :
val_width = 3;
break;
case 2 :
val_width = 5;
break;
default :
val_width = 10;
break;
}
if (is_signed)
val_width++;
}
long mask = -1;
if (size < sizeof(mask))
mask = (1L << (size*8)) - 1;
PINDEX i = 0;
while (i < GetSize()) {
if (i > 0)
strm << '\n';
PINDEX j;
for (j = 0; j < indent; j++)
strm.put(' ');
for (j = 0; j < line_width; j++) {
if (j == line_width/2)
strm.put(' ');
if (i+j < GetSize()) {
strm << setw(val_width);
if (is_signed)
strm << GetNumberValueAt(i+j);
else
strm << (DWORD)(GetNumberValueAt(i+j)&mask);
}
else {
PINDEX k;
for (k = 0; k < val_width; k++)
strm.put(' ');
}
strm << ' ';
}
strm << " ";
for (j = 0; j < line_width; j++) {
if (i+j < GetSize()) {
long val = GetNumberValueAt(i+j);
if (val >= 0 && val < 256 && isprint(val))
strm << (char)val;
else
strm << '.';
}
}
i += line_width;
}
}
long PAbstractArray::GetNumberValueAt(PINDEX) const
{
PAssertAlways(PUnimplementedFunction);
return 0;
}
///////////////////////////////////////////////////////////////////////////////
void PCharArray::PrintOn(ostream & strm) const
{
PINDEX width = strm.width();
if (width > GetSize())
width -= GetSize();
else
width = 0;
BOOL left = (strm.flags()&ios::adjustfield) == ios::left;
if (left)
strm.write(theArray, GetSize());
while (width-- > 0)
strm.put(strm.fill());
if (!left)
strm.write(theArray, GetSize());
}
void PShortArray::PrintOn(ostream & strm) const
{
PrintNumbersOn(strm, sizeof(short), TRUE);
}
long PShortArray::GetNumberValueAt(PINDEX idx) const
{
return ((short *)theArray)[idx];
}
void PIntArray::PrintOn(ostream & strm) const
{
PrintNumbersOn(strm, sizeof(int), TRUE);
}
long PIntArray::GetNumberValueAt(PINDEX idx) const
{
return ((int *)theArray)[idx];
}
void PLongArray::PrintOn(ostream & strm) const
{
PrintNumbersOn(strm, sizeof(long), TRUE);
}
long PLongArray::GetNumberValueAt(PINDEX idx) const
{
return ((long *)theArray)[idx];
}
void PBYTEArray::PrintOn(ostream & strm) const
{
PrintNumbersOn(strm, sizeof(BYTE), FALSE);
}
long PBYTEArray::GetNumberValueAt(PINDEX idx) const
{
return ((BYTE *)theArray)[idx];
}
void PWORDArray::PrintOn(ostream & strm) const
{
PrintNumbersOn(strm, sizeof(WORD), FALSE);
}
long PWORDArray::GetNumberValueAt(PINDEX idx) const
{
return ((WORD *)theArray)[idx];
}
void PUnsignedArray::PrintOn(ostream & strm) const
{
PrintNumbersOn(strm, sizeof(unsigned), FALSE);
}
long PUnsignedArray::GetNumberValueAt(PINDEX idx) const
{
return ((unsigned *)theArray)[idx];
}
void PDWORDArray::PrintOn(ostream & strm) const
{
PrintNumbersOn(strm, sizeof(DWORD), FALSE);
}
long PDWORDArray::GetNumberValueAt(PINDEX idx) const
{
return ((DWORD *)theArray)[idx];
}
///////////////////////////////////////////////////////////////////////////////
#ifdef PHAS_UNICODE
#define PSTRING_COPY(d, s, l) UnicodeCopy((WORD *)(d), (s), (l))
#define PSTRING_MOVE(d, doff, s, soff, l) \
memmove(((WORD*)(d))+(doff), ((WORD*)(s))+(soff), (l)*sizeof(WORD))
static void UnicodeCopy(WORD * theArray, char * src, size_t len)
{
while (len-- > 0)
*theArray++ = *src++;
}
#else
#define PSTRING_COPY(d, s, l) memcpy((d), (s), (l))
#define PSTRING_MOVE(d, doff, s, soff, l) memmove((d)+(doff), (s)+(soff), (l))
#endif
PString::PString(const char * cstr)
: PSTRING_ANCESTOR_CLASS(strlen(PAssertNULL(cstr))+1)
{
PSTRING_COPY(theArray, cstr, GetSize());
}
PString::PString(const WORD * ustr)
{
const WORD * ptr = PAssertNULL(ustr);
PINDEX len = 0;
while (*ptr++ != 0)
len++;
SetSize(len+1);
#ifdef PHAS_UNICODE
memcpy(theArray, ustr, len*sizeof(WORD))
#else
char * cstr = theArray;
while (len-- > 0)
*cstr++ = (char)*ustr++;
#endif
}
PString::PString(const char * cstr, PINDEX len)
: PSTRING_ANCESTOR_CLASS(len+1)
{
PSTRING_COPY(theArray, PAssertNULL(cstr), len);
}
PString::PString(const WORD * ustr, PINDEX len)
: PSTRING_ANCESTOR_CLASS(len+1)
{
PAssertNULL(ustr);
#ifdef PHAS_UNICODE
memcpy(theArray, ustr, len*sizeof(WORD))
#else
char * cstr = theArray;
while (len-- > 0)
*cstr++ = (char)*ustr++;
#endif
}
static int TranslateHex(char x)
{
if (x >= 'a')
return x - 'a' + 10;
if (x >= 'A')
return x - 'A' + '\x0a';
return x - '0';
}
static const char PStringEscapeCode[] = { 'a', 'b', 'f', 'n', 'r', 't', 'v' };
static const char PStringEscapeValue[] = { '\a', '\b', '\f', '\n', '\r', '\t', '\v' };
static void TranslateEscapes(const char * src, char * dst)
{
if (*src == '"')
src++;
while (*src != '\0') {
int c = *src++;
if (c == '"' && *src == '\0')
c = '\0'; // Trailing '"' is ignored
else if (c == '\\') {
c = *src++;
for (PINDEX i = 0; i < PARRAYSIZE(PStringEscapeCode); i++) {
if (c == PStringEscapeCode[i])
c = PStringEscapeValue[i];
}
if (c == 'x' && isxdigit(*src)) {
c = TranslateHex(*src++);
if (isxdigit(*src))
c = (c << 4) + TranslateHex(*src++);
}
else if (c >= '0' && c <= '7') {
int count = c <= '3' ? 3 : 2;
src--;
c = 0;
do {
c = (c << 3) + *src++ - '0';
} while (--count > 0 && *src >= '0' && *src <= '7');
}
}
*dst++ = (char)c;
}
}
PString::PString(ConversionType type, const char * str, ...)
{
switch (type) {
case Pascal :
if (*str != '\0') {
PINDEX len = *str & 0xff;
PAssert(SetSize(len+1), POutOfMemory);
PSTRING_COPY(theArray, str+1, len);
}
break;
case Basic :
if (str[0] != '\0' && str[1] != '\0') {
PINDEX len = str[0] | (str[1] << 8);
PAssert(SetSize(len+1), POutOfMemory);
PSTRING_COPY(theArray, str+2, len);
}
break;
case Literal :
PAssert(SetSize(strlen(str)+1), POutOfMemory);
TranslateEscapes(str, theArray);
PAssert(MakeMinimumSize(), POutOfMemory);
break;
case Printf :
va_list args;
va_start(args, str);
vsprintf(str, args);
break;
default :
PAssertAlways(PInvalidParameter);
}
}
static char * ltostr(DWORD value, unsigned base, char * str)
{
if (value >= base)
str = ltostr(value/base, base, str);
value %= base;
if (value < 10)
*str = (char)(value + '0');
else
*str = (char)(value + 'A'-10);
return str+1;
}
PString::PString(ConversionType type, long value, unsigned base)
: PCharArray(100)
{
PAssert(base >= 2 && base <= 36, PInvalidParameter);
switch (type) {
case Signed :
if (value < 0) {
*theArray = '-';
ltostr(-value, base, theArray+1);
break;
}
// Otherwise do Unsigned case
case Unsigned :
ltostr(value, base, theArray);
break;
default :
PAssertAlways(PInvalidParameter);
}
MakeMinimumSize();
}
PString::PString(ConversionType type, double value, unsigned places)
{
switch (type) {
case Decimal :
sprintf("%0.*f", (int)places, value);
break;
case Exponent :
sprintf("%0.*e", (int)places, value);
break;
default :
PAssertAlways(PInvalidParameter);
}
}
PString & PString::operator=(const char * cstr)
{
PString pstr(cstr);
PCharArray::operator=(pstr);
return *this;
}
PString & PString::operator=(char ch)
{
PString pstr(ch);
PCharArray::operator=(pstr);
return *this;
}
PObject * PString::Clone() const
{
return new PString(*this);
}
void PString::PrintOn(ostream &strm) const
{
strm << theArray;
}
void PString::ReadFrom(istream &strm)
{
SetMinSize(100);
char * ptr = theArray;
PINDEX len = 0;
int c;
while ((c = strm.get()) != EOF && c != '\n') {
*ptr++ = (char)c;
len++;
if (len >= GetSize()) {
SetSize(len + 100);
ptr = theArray + len;
}
}
*ptr = '\0';
PAssert(MakeMinimumSize(), POutOfMemory);
}
PObject::Comparison PString::Compare(const PObject & obj) const
{
PAssert(obj.IsDescendant(PString::Class()), PInvalidCast);
return InternalCompare(0, P_MAX_INDEX, ((const PString &)obj).theArray);
}
PINDEX PString::HashFunction() const
{
#ifdef PHAS_UNICODE
return (((WORD*)theArray)[0]+((WORD*)theArray)[1]+((WORD*)theArray)[2])%23;
#else
return ((BYTE)toupper(theArray[0]) +
(BYTE)toupper(theArray[1]) +
(BYTE)toupper(theArray[2]))%23;
#endif
}
BOOL PString::IsEmpty() const
{
#ifdef PHAS_UNICODE
return *(WORD*)theArray == '\0';
#else
return *theArray == '\0';
#endif
}
BOOL PString::SetSize(PINDEX newSize)
{
if (IsUnique())
return PAbstractArray::SetSize(newSize);
PINDEX newsizebytes = elementSize*newSize;
PINDEX oldsizebytes = elementSize*GetSize();
char * newArray;
if (newsizebytes == 0)
newArray = NULL;
else {
if ((newArray = (char *)malloc(newsizebytes)) == NULL)
return FALSE;
if (theArray != NULL)
memcpy(newArray, theArray, PMIN(oldsizebytes, newsizebytes));
}
reference->count--;
reference = new Reference(newSize);
if (newsizebytes > oldsizebytes)
memset(newArray+oldsizebytes, 0, newsizebytes-oldsizebytes);
theArray = newArray;
return TRUE;
}
BOOL PString::MakeUnique()
{
if (IsUnique())
return TRUE;
SetSize(GetSize());
return FALSE;
}
#ifdef PHAS_UNICODE
PINDEX PString::GetLength() const
{
for (len = 0; len < GetSize(); len++)
if (((WORD *)theArray)[len] == 0)
break;
return len;
}
#endif
PString PString::operator+(const char * cstr) const
{
PINDEX olen = GetLength();
PINDEX alen = strlen(PAssertNULL(cstr))+1;
PString str;
str.SetSize(olen+alen);
PSTRING_MOVE(str.theArray, 0, theArray, 0, olen);
PSTRING_COPY(str.theArray+olen, cstr, alen);
return str;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -