这个文件内有五个类型:TBuffer、TString、TList、TTable和TPool。这些应该是为库构件的基础数据结构。
TBuffer
typedef struct
{
void *data;
xmlrpc_uint32_t size;
xmlrpc_uint32_t staticid;
} TBuffer;
BufferAlloc函数不复杂。函数的作用就是申请memsize个字节的空间,如果申请成功,则让TBuffer的data指针指向这个内存区域,并且TBuffer的size保存这个内存区域的大小。
bool
BufferAlloc(TBuffer * const buf,
xmlrpc_uint32_t const memsize) {
/* ************** Implement the static buffers ***/
buf->staticid=0;
buf->data=(void *)malloc(memsize);
if (buf->data)
{
buf->size=memsize;
return TRUE;
}
else
{
buf->size=0;
return FALSE;
};
}
BufferFree函数就是将在BufferAlloc函数内申请的空间释放掉。
bool
BufferRealloc(TBuffer * const buf,
xmlrpc_uint32_t const memsize) {
if (buf->staticid)
{
TBuffer b;
if (memsize<=buf->size)
return TRUE;
if (BufferAlloc(&b,memsize))
{
memcpy(b.data,buf->data,buf->size);
BufferFree(buf);
*buf=b;
return TRUE;
}
}
else
{
void *d;
d=realloc(buf->data,memsize);
if (d)
{
buf->data=d;
buf->size=memsize;
return TRUE;
}
}
return FALSE;
}
BufferRealloc里的if语句后的第一个分支不会被使用,因为BufferAlloc函数内TBuffer的staticid始终都是0,因此BufferRealloc内的else后的分支总是会被执行。可以看出TBuffer结构体只是简单地封装了c的malloc等内存分配函数。
TString
typedef struct
{
TBuffer buffer;
xmlrpc_uint32_t size;
} TString;
从定义来看,只是简单地包裹了TBuffer类型。既然TBuffer有个size属性,为何TString又有个size属性呢?
bool
StringAlloc(TString * const stringP) {
bool succeeded;
stringP->size = 0;
succeeded = BufferAlloc(&stringP->buffer, 256);
if (succeeded) {
*(char *)(stringP->buffer.data) = '\0';
return TRUE;
} else
return FALSE;
}
TString的创建函数表明每个TString在创建时都只会申请256个字节的空间。除了将第一个字节置为‘\0’外,并无其他处理。
StringConcat顾名思义,就是在第一个字串尾部再追加一个字串。由于TBuffer是个固定长度,所以这类操作必须判断已申请的空间大小是否能容纳下新加入的字串。如果空间不够,会再次申请一个256字节的空间。也就是说在之前的TBuffer空间大小的基础上再加上256个字节大小的空间。
bool
StringConcat(TString * const stringP,
const char * const string2) {
uint32_t const len = strlen(string2);
if (len + stringP->size + 1 > strin