轻量web服务器开发日记03-bufstr结构体的实现

经过日记02说明内存池的实现后,现在开始介绍使用内存池的第一个结构体bufstr。
bufstr结构体以及相关实现函数替服务器管理字符串(服务器的处理信息数据)的内存块使用与操作。
我们先看看bufstr结构体的具体实现:

typedef struct {
    //指向数据
    char **ptr; 
    //指向内存块开头
    memblock * mblock;
    //内存块数目
    int mbnum;
    //已经使用大小(字节)
    int used; 
    //总共内存空间大小(字节)
    int size; 
} bufstr;

bufstr结构体的操作函数中,把指定字符串复制到用户指定的bufstr结构体的数据末尾,这个操作函数实现起来是比较有技巧的,因为不但当前用户指定的bufstr结构体的数据末尾有两种情况,分别是块内,块末。而且当前用户指定的bufstr结构体的块数量是否能容纳所需要追加的字符串。
(1)该操作函数的具体实现:

int bufstr_append_string(mempool *mpool,bufstr *b,char *s) 
{
    int slen,total,mbsize,mbnum,cnum,n;
    slen = strlen(s)+1;
    if(b==NULL||s==NULL)
    {
        return 0;
    } 
    mbsize = MBSIZE;
    for(;;)
    {   
        total = b->size - b->used+1;
        if(total>=slen)
        {

            if(b->used % mbsize > 0)
            {
                if(mbsize-b->used%mbsize+1 >= slen)
                {
                    memcpy((&b->ptr[b->used / mbsize][(b->used % mbsize)-1]),s,slen-1);
                    b->ptr[b->used / mbsize][(b->used % mbsize)-1+(slen-1)] = '\0';
                }
                else
                {
                    memcpy((&b->ptr[b->used / mbsize][(b->used % mbsize)-1]),s,mbsize - b->used%mbsize + 1);
                    s+=mbsize-b->used%mbsize+1;
                    mbnum =  (slen - (mbsize - b->used%mbsize+1)) / mbsize;
                    cnum = (slen - (mbsize - b->used%mbsize+1)) % mbsize;
                    n=0;
                    while(n<mbnum)
                    {
                        memcpy(b->ptr[(b->used / mbsize)+1+n],s,mbsize);
                        s+=mbsize;
                        n++;
                    }
                    if(cnum>0)
                    {
                        memcpy(b->ptr[b->used / mbsize+1+n],s,cnum);
                        b->ptr[b->used / mbsize+1+n][cnum] ='\0';
                    }
                    else
                    {
                        b->ptr[(b->used / mbsize)+1+n][0]='\0';
                    }
                }   
            }
            else
            {
                if(b->used / mbsize == 0) 
                {
                    bufstr_copy_string(mpool,b,s);
                    return 1;
                }
                else
                {
                    memcpy((&b->ptr[(b->used / mbsize)-1][mbsize-1]),s,1);
                    s++;
                    mbnum = (slen - 1) / mbsize;
                    cnum = (slen - 1) % mbsize;
                    n=0;
                    while(n<mbnum)
                    {
                        memcpy(b->ptr[(b->used / mbsize)+n],s,mbsize);
                        s+=mbsize;
                        n++;
                    }
                    if(cnum>0)
                    {
                        memcpy(b->ptr[(b->used / mbsize)+n],s,cnum);
                        b->ptr[(b->used / mbsize)+n][cnum] ='\0';
                    }
                    else
                    {
                        b->ptr[(b->used / mbsize)+n][0]='\0';
                    }
                }
            }
            b->used+=slen-1;
            return 1;
        }
        else
        {
            bufstr_prepare_size(mpool,b,slen);
        }
    }
}

(2)确保用户的bufstr结构体的ptr的指向区域至少有指定大小的空余内存空间,即bufstr_append_string函数中所调用的bufstr_prepare_size函数的实现:

int bufstr_prepare_size(mempool *mpool,bufstr *b, int size) 
{
    int total,mbsize,mbnum,n,i;
    memblock *mbtemp;
    if(b==NULL||b->size==0)
    {
        return 0;
    }
    mbsize = MBSIZE;
    total = b->size - b->used;
    n=size -total;
    if(n > 0)
    {
        mbnum = n / mbsize;
        if(n % mbsize>0)
        {
            mbnum++;
        }
        mbtemp = b->mblock;
        while(mbtemp->next!=NULL)
        {
            mbtemp = mbtemp->next;
        }
        mbtemp->next = mempool_take_mblocks(mpool,mbnum);
        //指向新增块的链头
        mbtemp = mbtemp->next;
        //使ptr指向每个新增内存块的数据部分
        for(i=0;i<mbnum;i++)
        {
            b->ptr[b->mbnum+i] = (char*)mbtemp->memptr;
            mbtemp = mbtemp->next;
        }
        b->mbnum += mbnum;
        b->size += mbsize * mbnum;
    }
    return 1;
}

下面是bufstr结构体的操作函数名字,由于操作函数很多,我就不逐一列举了,若大家需要了解哪一个,可以在评论中告诉我,我看到时更新内容。

//创建bufstr结构b,并拥有一个内存块,即1K的内存空间
bufstr *bufstr_init(mempool *mpool);
//释放用户指定的bufstr结构体b
void bufstr_free(mempool *mpool,bufstr *b);
//确保用户指定的bufstr结构体b的ptr的指向区域至少有size大小的空余内存空间
int bufstr_prepare_size(mempool *mpool,bufstr *b, int size);
//把指定字符串s复制到用户指定的bufstr结构体b的数据空间,覆盖之前b的数据
int bufstr_copy_string(mempool *mpool,bufstr *b,char *s);
//把指定字符串s前s_len个字符复制到用户指定的bufstr结构体b的数据空间,覆盖之前b的数据
int bufstr_copy_string_len(mempool *mpool,bufstr *b,char *s,int s_len);
//将bufstr结构体src的内容复制到bufstr结构体des中,覆盖之前des的数据
int bufstr_copy_string_bufstr(mempool *mpool,bufstr *des,bufstr *src); 
int bufstr_append_string_len(mempool *mpool,bufstr *b,char *s,int len);
//把指定字符串s复制到用户指定的bufstr结构体b的数据末尾(覆盖之前'\0'int bufstr_append_string(mempool *mpool,bufstr *b,char *s);
//把指定bufstr的src里面的数据复制到用户指定的bufstr结构体des的数据末尾(覆盖之前'\0'int bufstr_append_bufstr(mempool *mpool,bufstr *des, bufstr *src);
//把bufstr的数据转换成字符串,并返回
char *read_string_bufstr(bufstr * src);
//把bufstr里面的数据转换成整形输出
int read_int_bufstr(bufstr *src);
//将path字符串里面的文件名提取出来,复制给bufstr结构体,覆盖掉先前数据
bufstr *bufstr_copy_bufstr_filename(mempool *mpool,bufstr *src);
bufstr *bufstr_copy_filename(mempool *mpool,char *path);
//将path字符串里面的文件扩展名提取出来,复制给bufstr结构体并返回,覆盖掉先前数据
bufstr *bufstr_copy_bufstr_etrname(mempool *mpool,bufstr *src);
bufstr *bufstr_copy_etrname(mempool *mpool,char *path);
//比较bufstr和string
int bufstr_compare_string(bufstr *a, char *b);
//比较bufstr和bufstr
int bufstr_compare_bufstr(bufstr *a, char  *b);
char* string_to_lower(char *str);
char* string_to_upper(char *str);
//将bufstr里面的大写字符转换成小写字符
int bufstr_to_lower(bufstr * b);
//将bufstr里面的小写字符转换成大写字符
int bufstr_to_upper(bufstr * b);
//将一个整数转换成字符串
char *itoa(size_t num);
//判断用户指定的bufstr结构体b所指的内容中是否含有字符串src
int bufstr_include_string(bufstr *b, char *src);
//判断用户指定的bufstr结构体str1所指字符串中是否含有str2所指字符串
int bufstr_include_bufstr(bufstr *str1, bufstr *str2);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值