📄 contain.cxx
字号:
theArray = NULL;
else
theArray = (char *)calloc(GetSize(), elementSize);
allocatedDynamically = TRUE;
}
PAbstractArray::PAbstractArray(PINDEX elementSizeInBytes,
const void *buffer,
PINDEX bufferSizeInElements,
BOOL dynamicAllocation)
: PContainer(bufferSizeInElements)
{
elementSize = elementSizeInBytes;
PAssert(elementSize != 0, PInvalidParameter);
allocatedDynamically = dynamicAllocation;
if (GetSize() == 0)
theArray = NULL;
else if (dynamicAllocation) {
PINDEX sizebytes = elementSize*GetSize();
theArray = (char *)malloc(sizebytes);
memcpy(theArray, PAssertNULL(buffer), sizebytes);
}
else
theArray = (char *)buffer;
}
void PAbstractArray::DestroyContents()
{
if (theArray != NULL) {
if (allocatedDynamically)
free(theArray);
theArray = NULL;
}
}
void PAbstractArray::CopyContents(const PAbstractArray & array)
{
elementSize = array.elementSize;
theArray = array.theArray;
allocatedDynamically = array.allocatedDynamically;
}
void PAbstractArray::CloneContents(const PAbstractArray * array)
{
elementSize = array->elementSize;
PINDEX sizebytes = elementSize*GetSize();
char * newArray = (char *)malloc(sizebytes);
if (newArray == NULL)
reference->size = 0;
else
memcpy(newArray, array->theArray, sizebytes);
theArray = newArray;
allocatedDynamically = TRUE;
}
PObject::Comparison PAbstractArray::Compare(const PObject & obj) const
{
PAssert(obj.IsDescendant(PAbstractArray::Class()), PInvalidCast);
const PAbstractArray & other = (const PAbstractArray &)obj;
char * otherArray = other.theArray;
if (theArray == otherArray)
return EqualTo;
if (elementSize < other.elementSize)
return LessThan;
if (elementSize > other.elementSize)
return GreaterThan;
PINDEX thisSize = GetSize();
PINDEX otherSize = other.GetSize();
if (thisSize < otherSize)
return LessThan;
if (thisSize > otherSize)
return GreaterThan;
if (thisSize == 0)
return EqualTo;
int retval = memcmp(theArray, otherArray, elementSize*thisSize);
if (retval < 0)
return LessThan;
if (retval > 0)
return GreaterThan;
return EqualTo;
}
BOOL PAbstractArray::SetSize(PINDEX newSize)
{
PINDEX newsizebytes = elementSize*newSize;
PINDEX oldsizebytes = elementSize*GetSize();
char * newArray;
if (!IsUnique()) {
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);
} else {
if (newsizebytes == oldsizebytes)
return TRUE;
if (theArray != NULL) {
if (newsizebytes == 0) {
if (allocatedDynamically)
free(theArray);
newArray = NULL;
}
else if (allocatedDynamically) {
if ((newArray = (char *)realloc(theArray, newsizebytes)) == NULL)
return FALSE;
}
else {
if ((newArray = (char *)malloc(newsizebytes)) == NULL)
return FALSE;
memcpy(newArray, theArray, PMIN(newsizebytes, oldsizebytes));
allocatedDynamically = TRUE;
}
}
else if (newsizebytes != 0) {
if ((newArray = (char *)malloc(newsizebytes)) == NULL)
return FALSE;
}
else
newArray = NULL;
reference->size = newSize;
}
if (newsizebytes > oldsizebytes)
memset(newArray+oldsizebytes, 0, newsizebytes-oldsizebytes);
theArray = newArray;
return TRUE;
}
void PAbstractArray::Attach(const void *buffer, PINDEX bufferSize)
{
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') {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -