Chinaunix首页 | 论坛 | 博客
  • 博客访问: 166445
  • 博文数量: 43
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 675
  • 用 户 组: 普通用户
  • 注册时间: 2013-01-26 00:58
文章分类
文章存档

2014年(2)

2013年(41)

我的朋友

分类: C/C++

2013-07-29 11:24:21

一、bitset

{size_t *bits;

 size_t nbits;}

bitset *bitset_init(size_t nbits);分配空间

void bitset_reset(bitset *set);分配的空间清零

void bitset_free(bitset *set);释放空间

void bitset_clear_bit(bitset *set, size_t pos);pos位设为0

void bitset_set_bit(bitset *set, size_t pos);pos位设为1

int bitset_test_bit(bitset *set, size_t pos);  看pos位是否为1

CHAR_BIT 是一个字节位数

BITSET_BITS是size_t占的位数,BITSET_USED是nbits占用的size_t数,取整

BITSET_WORD  返回pos位在的size_t块

知识点一:

assert宏的用法

assert宏的原型定义在中,其作用是如果它的条件返回错误,则终止程序执行

完成调试后,不必从源代码中删除assert()语句,因为宏NDEBUG有定义时,宏assert()的定义为空

知识点二:

SEGFAULT宏定义自buffer.h。这里面的do-while循环并不是多余的。恒假判断的dowhile保证了循环内容作为一个整体执行一次,防止宏拓展后意外出错

不然 if(flag==1)

SEGFAULT();

这样不论如何abort()都会执行。与初衷不符


 

二、buffer

struct {

char *ptr;//保存内容,可以保存字符串等不同数据。方便socket发送数据

size_t used;//内容长度,字符串\0也占用一个空间

size_t size;//ptr空间大小} buffer;

typedef struct {

buffer **ptr;

size_t used;//占用的buffer

size_t size;//buffer总长度

} buffer_array;

typedef struct {

char *ptr;

size_t offset; /* input-pointer */

size_t used;   /* output-pointer */

size_t size;

} read_buffer;

buffer_init() //分配空间

buffer_init_buffer(buffer *src)  //返回一个用src初始化的buffer

buffer_copy_string_buffer(buffer *b, const buffer *src)  //复制buffer

buffer_reset  //清零

buffer_copy_string_len(buffer *b, const char *s, size_t s_len)//从s复制len个字节到b的字节长

buffer_prepare_copy(buffer *b, size_t size) //若b的空间没有size大,为b的ptr分配msize长度的空间

       msize =  size+64 - (size % 64);

   msize是64的整数倍

buffer_free()  空间释放

buffer_copy_string()  //复制字符串到buffer

buffer_prepare_append(buffer *b, size_t size) //如果(已用空间+追加空间>分配空间),在当前存储空间后面追加size长度的内容,同时原存储数据不变(如果小于,说明空间够用,没有追加的必要)

buffer_append_string(buffer *b, const char *s)//buffer b的存储空间追加s字符串

buffer_append_string_rfill(buffer *b, const char *s, size_t maxlen)//追加s字符串中maxlen的长度的内容,如果maxlen比s长度大,补空格

高群凯书上说,这个函数有漏洞,但是没有被调用。buffer_prepare_append(b, maxlen + 1);这一步,如果s_len远大于maxlen,申请到的空间不一定装的下s_len

其实没有,如果s_len大于maxlen,那么s字符串会复制maxlen长度的内容。因为s_len=maxlen

buffer_append_string_len(buffer *b, const char *s, size_t s_len)//作用是在b后面追加len长度的s的子串倒是个函数我感觉有漏洞, 按照linux实现memcpy的方式,如果s_len超过了s的空间范围,仍会访问。比如s是char[10],s_len是100,那就会访问到s[99],明显是越界了

linux实现memcpy

void *memcpy(void *dest, const void *src, size_t count)

{

    assert(dest != NULL && src != NULL);

    char *tmp = dest;

    const char *s = src;

    while (count--)

        *tmp++ = *s++ ;

    return dest;

}

测试:

char a[10000];

char b[10]="hello";

memcpy(a,b,9999);

printf("%s\n",a);

     //段错误

buffer_append_memory(buffer *b, const char *s, size_t s_len) //把s内容部分s_len长度的放在b的数据部分后面,如果是字符串,放在\0后面。同样有漏洞,如果s_len远大于s,那么对s的访问越界 

buffer_copy_memory(buffer *b, const char *s, size_t s_len) //把用s替代b的数据部分  这个函数调用buffer_append_memory,有漏洞

buffer_append_long_hex(buffer *b, unsigned long value)  // 转化为十六进制字符串

LI_ltostr(char *buf, long val) //十进制转为字符串,返回字符串长度

buffer_append_long(buffer *b, long val)  //把long型转化为字符串添加在buffer中

buffer_copy_long(buffer *b, long val)  //把long转化为字符串覆盖b数据部分

buffer_append_off_t  //off_t型十进制,和上面long操作一样

buffer_copy_off_t//同上

int2hex //char字符低4位对应的16进制值

hex2int  //16进制字符转化为int

buffer_array* buffer_array_init(void) //buffer数组初始化

reset//置0

free//释放空间

buffer_array_append_get_buffer//如果没有任何空间,追加16个没如果空间全部使用,添加16个

buffer_search_string_len //查找具有该字符串len位的第一个buffer

buffer_is_empty//buffer是否为空

buffer_caseless_compare//对两个字符串做不区分大小写的比较

buffer_is_equal//比较两个buffer数据部分是否相等

buffer_is_equal_string//buffer数据部分和字符串比较

buffer_is_equal_right_len//两个buffer末尾len位内容是否相等

buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) //把in字符串转化为16进制存在b中

buffer_path_simplify(buffer *dest, buffer *src)//把字符串路径转化为等同的简单形式  疑问pre = ('/' << 8) | pre1;//这里移8位不久清0了么,char共8位?

buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding)//ss_len长度的子串,转化编码,追加在b后面

知识点一:realloc()

先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照 newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动 释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。

知识点二:

#if 0作为注释使用,比/**/方便,因为这个取消注释,之需要把0改为1,而且,还可以嵌套注释

知识点三:学习借鉴

int buffer_append_long_hex(buffer *b, unsigned long value) {

char *buf;

int shift = 0;

unsigned long copy = value;

while (copy) {

copy >>= 4;

shift++;

}

if (shift == 0) //也就是value是0,也需要转化一次

shift++;

if (shift & 0x01)//如果末位是1,也就是奇数,再加一次转化。保证转化的次数为偶数次。比如14==》e。应该是0e

shift++;

buffer_prepare_append(b, shift + 1);

if (b->used == 0)

b->used++;

buf = b->ptr + (b->used - 1);

b->used += shift;

shift <<= 2;//移动4*shift位可以全部转换

while (shift > 0) {

shift -= 4;

*(buf++) = hex_chars[(value >> shift) & 0x0F];//& 0x0F,屏蔽高位,保证每次取后四位

}

*buf = '\0';

return 0;

}

知识点四:

if (hex > 9) {

hex = (hex + '0' - 1) | 0x20;/*大于9,说明不是数字部分,因为ascii中0-9和a不连续,+'0'并取低8位。可能是A或者a

a-A=0x20 。 经过|0x20,大写转化为小写,*/

hex = hex - 'a' + 11;

}

为什么先-1后+11呢,因为

A和a的前一个字符比较特殊

拿@来说

@   01000000  | 020x  →   01100000

01100000-'a'+10=9

这是A为01000001,如果A为01000010,那这里就是要+2了。

使得a和A前15个字符,|0x20后不再是'a'的前15个字符就OK

知识点五:巧妙用法,每次比较四个字符

int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len) {

size_t ndx = 0, max_ndx;

size_t *al, *bl;

size_t mask = sizeof(*al) – 1;

al = (size_t *)a;

bl = (size_t *)b;

/* is the alignment correct ? */

if ( ((size_t)al & mask) == 0 &&

   //如果低三位是0,也就是地址是四个字节的整数

     ((size_t)bl & mask) == 0 ) {

max_ndx = ((a_len < b_len) ? a_len : b_len) & ~mask;

for (; ndx < max_ndx; ndx += sizeof(*al)) {

if (*al != *bl) break;

al++; bl++;

}

}

a = (char *)al;

b = (char *)bl;

max_ndx = ((a_len < b_len) ? a_len : b_len);

for (; ndx < max_ndx; ndx++) {

int a1 = *a++, b1 = *b++;

if (a1 != b1) {

if (a1 >= 'A' && a1 <= 'Z') a1 |= 32;

if (b1 >= 'A' && b1 <= 'Z') b1 |= 32;

if ((a1 - b1) != 0) return (a1 - b1);

}

}

if (a_len == b_len) return 0;

return (a_len - b_len);

}

知识点五:编码转化

http://www.ruanyifeng.com/blog/2010/02/url_encoding.html

http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html


后续的结构体看完了追加....

阅读(2241) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~