-
Notifications
You must be signed in to change notification settings - Fork 2
/
buf.c
148 lines (119 loc) · 3.04 KB
/
buf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "buf.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef ASSERT
#define ASSERT(e) assert(e)
#endif //ASSERT
inline static size_t buf_calc_size(size_t need_cap)
{
if (need_cap < 512) {
if (need_cap < 128) {
if (need_cap < 64) {
return 64;
}
return 128;
}
if (need_cap < 256) {
return 256;
}
return 512;
}
return ((need_cap / 512) + 1) * 512;
}
EXTERN struct buf_t* buf_new(size_t cap)
{
size_t size = buf_calc_size(sizeof(struct buf_t) + cap);
struct buf_t* buf = (struct buf_t*)malloc(size);
if (NULL == buf) {
return NULL;
}
buf->error = 0;
buf->cap = size - sizeof(struct buf_t);
buf->len = 0;
buf->data[0] = 0;
return buf;
}
EXTERN void buf_del(struct buf_t* buf)
{
if (NULL != buf) {
free(buf);
}
}
EXTERN struct buf_t* buf_append(struct buf_t* buf, void* data, size_t len)
{
ASSERT(NULL != buf);
ASSERT(NULL != data);
ASSERT(len >= 0);
if (0 == len) {
return buf;
}
if (buf->error) {
return buf;
}
size_t need_cap = (buf->len + len);
if (need_cap > buf->cap) // 缓冲区不够
{
size_t new_size = buf_calc_size(sizeof(struct buf_t) + need_cap);
struct buf_t* new_buf = (struct buf_t*)malloc(new_size);
if (NULL == new_buf) {
buf->error = 1;
return buf;
}
memcpy(new_buf, buf, sizeof(struct buf_t) + buf->len);
new_buf->cap = new_size - sizeof(struct buf_t);
free(buf);
buf = new_buf;
}
memcpy(buf->data + buf->len, data, len);
buf->len += len;
return buf;
}
EXTERN struct buf_t* buf_append_string(struct buf_t* buf, char* s, char* end)
{
ASSERT(NULL != buf);
ASSERT(NULL != s);
size_t len = 0;
if (NULL == end) {
len = strlen(s);
} else {
len = end - s;
}
if (0 == len) {
return buf;
}
return buf_append(buf, s, len);
}
EXTERN struct buf_t* buf_append_char(struct buf_t* buf, char val)
{
return buf_append(buf, &val, sizeof(char));
}
EXTERN struct buf_t* buf_append_wchar(struct buf_t* buf, wchar_t val)
{
return buf_append(buf, &val, sizeof(wchar_t));
}
EXTERN struct buf_t* buf_append_int32(struct buf_t* buf, int val)
{
return buf_append(buf, &val, sizeof(int));
}
EXTERN struct buf_t* buf_append_uint32(struct buf_t* buf, unsigned int val)
{
return buf_append(buf, &val, sizeof(unsigned int));
}
EXTERN struct buf_t* buf_append_int16(struct buf_t* buf, short val)
{
return buf_append(buf, &val, sizeof(short));
}
EXTERN struct buf_t* buf_append_uint16(struct buf_t* buf, unsigned short val)
{
return buf_append(buf, &val, sizeof(unsigned short));
}
EXTERN EXTERN struct buf_t* buf_append_int8(struct buf_t* buf, char val)
{
return buf_append(buf, &val, sizeof(char));
}
EXTERN struct buf_t* buf_append_uint8(struct buf_t* buf, unsigned char val)
{
return buf_append(buf, &val, sizeof(unsigned char));
}