⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 data.c

📁 一个很好用的解析
💻 C
字号:
/********************************************************************************** list.c**** This file is part of the ABYSS Web server project.**** Copyright (C) 2000 by Moez Mahfoudh <mmoez@bigfoot.com>.** All rights reserved.**** Redistribution and use in source and binary forms, with or without** modification, are permitted provided that the following conditions** are met:** 1. Redistributions of source code must retain the above copyright**    notice, this list of conditions and the following disclaimer.** 2. Redistributions in binary form must reproduce the above copyright**    notice, this list of conditions and the following disclaimer in the**    documentation and/or other materials provided with the distribution.** 3. The name of the author may not be used to endorse or promote products**    derived from this software without specific prior written permission.** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF** SUCH DAMAGE.*********************************************************************************/#include <assert.h>#include <stdlib.h>#include <string.h>#include "mallocvar.h"#include "xmlrpc-c/util_int.h"#include "xmlrpc-c/string_int.h"#include "xmlrpc-c/abyss.h"#include "token.h"#include "data.h"/*********************************************************************** List*********************************************************************/void ListInit(TList *sl){    sl->item=NULL;    sl->size=sl->maxsize=0;    sl->autofree=FALSE;}void ListInitAutoFree(TList *sl){    sl->item=NULL;    sl->size=sl->maxsize=0;    sl->autofree=TRUE;}voidListFree(TList * const sl) {    if (sl->item) {        if (sl->autofree) {            unsigned int i;            for (i = sl->size; i > 0; --i)                free(sl->item[i-1]);                    }        free(sl->item);    }    sl->item = NULL;    sl->size = 0;    sl->maxsize = 0;}voidListFreeItems(TList * const sl) {    if (sl->item) {        unsigned int i;        for (i = sl->size; i > 0; --i)            free(sl->item[i-1]);    }}abyss_boolListAdd(TList * const sl,        void *  const str) {/*----------------------------------------------------------------------------   Add an item to the end of the list.-----------------------------------------------------------------------------*/    abyss_bool success;    if (sl->size >= sl->maxsize) {        uint16_t newSize = sl->maxsize + 16;        void **newitem;                newitem = realloc(sl->item, newSize * sizeof(void *));        if (newitem) {            sl->item    = newitem;            sl->maxsize = newSize;        }    }    if (sl->size >= sl->maxsize)        success = FALSE;    else {        success = TRUE;        sl->item[sl->size++] = str;    }    return success;}voidListRemove(TList * const sl) {/*----------------------------------------------------------------------------   Remove the last item from the list.-----------------------------------------------------------------------------*/    assert(sl->size > 0);    --sl->size;}abyss_boolListAddFromString(TList *      const list,                  const char * const stringArg) {    abyss_bool retval;        if (!stringArg)        retval = TRUE;    else {        char * buffer;                buffer = strdup(stringArg);        if (!buffer)            retval = FALSE;        else {            abyss_bool endOfString;            abyss_bool error;            char * c;            for (c = &buffer[0], endOfString = FALSE, error = FALSE;                 !endOfString && !error;                ) {                const char * t;                NextToken((const char **)&c);                                while (*c == ',')                    ++c;                                t = GetToken(&c);                if (!t)                    endOfString = TRUE;                else {                    char * p;                    for (p = c - 2; *p == ','; --p)                        *p = '\0';                                        if (t[0] != '\0') {                        abyss_bool added;                        added = ListAdd(list, (void*)t);                                                if (!added)                            error = TRUE;                    }                }            }            retval = !error;            xmlrpc_strfree(buffer);        }    }    return retval;}abyss_boolListFindString(TList *      const sl,               const char * const str,               uint16_t *   const indexP){    uint16_t i;    if (sl->item && str)        for (i=0;i<sl->size;i++)            if (strcmp(str,(char *)(sl->item[i]))==0)            {                *indexP=i;                return TRUE;            };    return FALSE;}/*********************************************************************** Buffer*********************************************************************/abyss_bool BufferAlloc(TBuffer *buf,uint32_t 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;    };}void BufferFree(TBuffer *buf){    if (buf->staticid)    {        /* ************** Implement the static buffers ***/    }    else        free(buf->data);    buf->size=0;    buf->staticid=0;}abyss_bool BufferRealloc(TBuffer *buf,uint32_t 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;}/*********************************************************************** String*********************************************************************/abyss_bool StringAlloc(TString *s){    s->size=0;    if (BufferAlloc(&(s->buffer),256))    {        *(char *)(s->buffer.data)='\0';        return TRUE;    }    else        return FALSE;}abyss_bool StringConcat(TString *s,char *s2){    uint32_t len=strlen(s2);    if (len+s->size+1>s->buffer.size)        if (!BufferRealloc(&(s->buffer),((len+s->size+1+256)/256)*256))            return FALSE;        strcat((char *)(s->buffer.data),s2);    s->size+=len;    return TRUE;}abyss_bool StringBlockConcat(TString *s,char *s2,char **ref){    uint32_t len=strlen(s2)+1;    if (len+s->size>s->buffer.size)        if (!BufferRealloc(&(s->buffer),((len+s->size+1+256)/256)*256))            return FALSE;        *ref=(char *)(s->buffer.data)+s->size;    memcpy(*ref,s2,len);    s->size+=len;    return TRUE;}void StringFree(TString *s){    s->size=0;    BufferFree(&(s->buffer));}char *StringData(TString *s){    return (char *)(s->buffer.data);}/*********************************************************************** Hash*********************************************************************/static uint16_tHash16(const char * const start) {    const char * s;        uint16_t i;        s = start;    i = 0;    while(*s)        i = i * 37 + *s++;    return i;}/*********************************************************************** Table*********************************************************************/void TableInit(TTable *t){    t->item=NULL;    t->size=t->maxsize=0;}void TableFree(TTable *t){    uint16_t i;    if (t->item)    {        if (t->size)            for (i=t->size;i>0;i--)            {                free(t->item[i-1].name);                free(t->item[i-1].value);            };                    free(t->item);    }    TableInit(t);}abyss_boolTableFindIndex(TTable *     const t,               const char * const name,               uint16_t *   const index) {    uint16_t i,hash=Hash16(name);    if ((t->item) && (t->size>0) && (*index<t->size))    {        for (i=*index;i<t->size;i++)            if (hash==t->item[i].hash)                if (strcmp(t->item[i].name,name)==0)                {                    *index=i;                    return TRUE;                };    };    return FALSE;}abyss_boolTableAddReplace(TTable *     const t,                const char * const name,                const char * const value) {    uint16_t i=0;    if (TableFindIndex(t,name,&i))    {        free(t->item[i].value);        if (value)            t->item[i].value=strdup(value);        else        {            free(t->item[i].name);            if (--t->size>0)                t->item[i]=t->item[t->size];        };        return TRUE;    }    else        return TableAdd(t,name,value);}abyss_boolTableAdd(TTable *     const t,         const char * const name,         const char * const value) {    if (t->size>=t->maxsize) {        TTableItem *newitem;                t->maxsize+=16;        newitem=(TTableItem *)realloc(t->item,(t->maxsize)*sizeof(TTableItem));        if (newitem)            t->item=newitem;        else {            t->maxsize-=16;            return FALSE;        }    }    t->item[t->size].name=strdup(name);    t->item[t->size].value=strdup(value);    t->item[t->size].hash=Hash16(name);    ++t->size;    return TRUE;}char *TableFind(TTable *     const t,          const char * const name) {    uint16_t i=0;    if (TableFindIndex(t,name,&i))        return t->item[i].value;    else        return NULL;}/*********************************************************************** Pool*********************************************************************/static TPoolZone *PoolZoneAlloc(uint32_t const zonesize) {    TPoolZone * poolZoneP;        MALLOCARRAY(poolZoneP, zonesize);    if (poolZoneP) {        poolZoneP->pos    = &poolZoneP->data[0];        poolZoneP->maxpos = poolZoneP->pos + zonesize;        poolZoneP->next   = NULL;        poolZoneP->prev   = NULL;    }    return poolZoneP;}static voidPoolZoneFree(TPoolZone * const poolZoneP) {    free(poolZoneP);}abyss_boolPoolCreate(TPool *  const poolP,           uint32_t const zonesize) {    abyss_bool success;    abyss_bool mutexCreated;    poolP->zonesize = zonesize;    mutexCreated = MutexCreate(&poolP->mutex);    if (mutexCreated) {        TPoolZone * const firstZoneP = PoolZoneAlloc(zonesize);        if (firstZoneP != NULL) {            poolP->firstzone   = firstZoneP;            poolP->currentzone = firstZoneP;            success = TRUE;        } else            success = FALSE;        if (!success)            MutexFree(&poolP->mutex);    } else        success = FALSE;    return success;}void *PoolAlloc(TPool *  const poolP,          uint32_t const size) {/*----------------------------------------------------------------------------   Allocate a block of size 'size' from pool 'poolP'.-----------------------------------------------------------------------------*/    void * retval;    if (size == 0)        retval = NULL;    else {        abyss_bool gotMutexLock;        gotMutexLock = MutexLock(&poolP->mutex);        if (!gotMutexLock)            retval = NULL;        else {            TPoolZone * const curPoolZoneP = poolP->currentzone;            if (curPoolZoneP->pos + size < curPoolZoneP->maxpos) {                retval = curPoolZoneP->pos;                curPoolZoneP->pos += size;            } else {                uint32_t const zonesize = MAX(size, poolP->zonesize);                TPoolZone * const newPoolZoneP = PoolZoneAlloc(zonesize);                if (newPoolZoneP) {                    newPoolZoneP->prev = curPoolZoneP;                    newPoolZoneP->next = curPoolZoneP->next;                    curPoolZoneP->next = newPoolZoneP;                    poolP->currentzone = newPoolZoneP;                    retval= newPoolZoneP->data;                    newPoolZoneP->pos = newPoolZoneP->data + size;                } else                    retval = NULL;            }            MutexUnlock(&poolP->mutex);        }    }    return retval;}voidPoolReturn(TPool *  const poolP,           void *   const blockP) {/*----------------------------------------------------------------------------   Return the block at 'blockP' to the pool 'poolP'.  WE ASSUME THAT IS   THE MOST RECENTLY ALLOCATED AND NOT RETURNED BLOCK IN THE POOL.-----------------------------------------------------------------------------*/    TPoolZone * const curPoolZoneP = poolP->currentzone;    assert((char*)curPoolZoneP->data < (char*)blockP &&           (char*)blockP < (char*)curPoolZoneP->pos);    curPoolZoneP->pos = blockP;    if (curPoolZoneP->pos == curPoolZoneP->data) {        /* That emptied out the current zone.  Free it and make the previous           zone current.        */        assert(curPoolZoneP->prev);  /* entry condition */        curPoolZoneP->prev->next = NULL;        PoolZoneFree(curPoolZoneP);    }}voidPoolFree(TPool * const poolP) {    TPoolZone * poolZoneP;    TPoolZone * nextPoolZoneP;        for (poolZoneP = poolP->firstzone; poolZoneP; poolZoneP = nextPoolZoneP) {        nextPoolZoneP = poolZoneP->next;        free(poolZoneP);    }}const char *PoolStrdup(TPool *      const poolP,           const char * const origString) {    char * newString;    if (origString == NULL)        newString = NULL;    else {        newString = PoolAlloc(poolP, strlen(origString) + 1);        if (newString != NULL)            strcpy(newString, origString);    }    return newString;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -