Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <venti.h>
4 #include <libsec.h>
6 #define MAGIC 0x54798314
7 #define NOTFREE(p) assert((p)->magic == MAGIC)
9 struct Packet
10 {
11 char *data;
12 int len;
13 void (*free)(void*);
14 void *arg;
15 int magic;
16 };
18 Packet*
19 packetalloc(void)
20 {
21 Packet *p;
23 p = vtmallocz(sizeof *p);
24 p->free = vtfree;
25 p->arg = nil;
26 p->magic = MAGIC;
27 return p;
28 }
30 void
31 packetappend(Packet *p, uchar *buf, int n)
32 {
33 NOTFREE(p);
34 if(n < 0)
35 abort();
36 if(p->free != vtfree)
37 sysfatal("packetappend");
38 p->data = vtrealloc(p->data, p->len+n);
39 p->arg = p->data;
40 memmove(p->data+p->len, buf, n);
41 p->len += n;
42 }
44 uint
45 packetasize(Packet *p)
46 {
47 NOTFREE(p);
48 return p->len;
49 }
51 int
52 packetcmp(Packet *p, Packet *q)
53 {
54 int i, len;
56 NOTFREE(p);
57 NOTFREE(q);
58 len = p->len;
59 if(len > q->len)
60 len = q->len;
61 if(len && (i=memcmp(p->data, q->data, len)) != 0)
62 return i;
63 if(p->len > len)
64 return 1;
65 if(q->len > len)
66 return -1;
67 return 0;
68 }
70 void
71 packetconcat(Packet *p, Packet *q)
72 {
73 NOTFREE(p);
74 NOTFREE(q);
75 packetappend(p, q->data, q->len);
76 if(q->free == vtfree)
77 memset(q->data, 0xFE, q->len);
78 q->free(q->arg);
79 q->data = nil;
80 q->len = 0;
81 }
83 int
84 packetconsume(Packet *p, uchar *buf, int n)
85 {
86 NOTFREE(p);
87 if(n < 0)
88 abort();
89 if(p->len < n)
90 abort();
91 memmove(buf, p->data, n);
92 p->len -= n;
93 memmove(p->data, p->data+n, p->len);
94 return 0;
95 }
97 int
98 packetcopy(Packet *p, uchar *buf, int offset, int n)
99 {
100 NOTFREE(p);
101 if(offset < 0 || n < 0)
102 abort();
103 if(offset > p->len)
104 abort();
105 if(offset+n > p->len)
106 n = p->len - offset;
107 memmove(buf, p->data+offset, n);
108 return 0;
111 Packet*
112 packetdup(Packet *p, int offset, int n)
114 Packet *q;
116 NOTFREE(p);
117 if(offset < 0 || n < 0)
118 abort();
119 if(offset > p->len)
120 abort();
121 if(offset+n > p->len)
122 n = p->len - offset;
123 q = packetalloc();
124 packetappend(q, p->data+offset, n);
125 return q;
128 Packet*
129 packetforeign(uchar *buf, int n, void (*free)(void*), void *a)
131 Packet *p;
133 if(n < 0)
134 abort();
135 p = packetalloc();
136 p->data = (char*)buf;
137 p->len = n;
138 p->free = free;
139 p->arg = a;
140 return p;
143 int
144 packetfragments(Packet *p, IOchunk *io, int nio, int offset)
146 NOTFREE(p);
147 if(offset < 0)
148 abort();
149 if(nio == 0)
150 return 0;
151 memset(io, 0, sizeof(io[0])*nio);
152 if(offset >= p->len)
153 return 0;
154 io[0].addr = p->data + offset;
155 io[0].len = p->len - offset;
156 return p->len;
159 void
160 packetfree(Packet *p)
162 NOTFREE(p);
163 if(p->free == free)
164 memset(p->data, 0xFE, p->len);
165 p->free(p->arg);
166 p->data = nil;
167 p->len = 0;
168 memset(p, 0xFB, sizeof *p);
169 free(p);
172 uchar*
173 packetheader(Packet *p, int n)
175 NOTFREE(p);
176 if(n < 0)
177 abort();
178 if(n > p->len)
179 abort();
180 return p->data;
183 uchar*
184 packetpeek(Packet *p, uchar *buf, int offset, int n)
186 NOTFREE(p);
187 if(offset < 0 || n < 0)
188 abort();
189 if(offset+n > p->len)
190 abort();
191 return p->data+offset;
194 void
195 packetprefix(Packet *p, uchar *buf, int n)
197 NOTFREE(p);
198 if(n < 0)
199 abort();
200 if(p->free != free)
201 sysfatal("packetappend");
202 p->data = vtrealloc(p->data, p->len+n);
203 p->arg = p->data;
204 memmove(p->data+n, p->data, p->len);
205 memmove(p->data, buf, n);
206 p->len += n;
209 void
210 packetsha1(Packet *p, uchar d[20])
212 NOTFREE(p);
213 sha1((uchar*)p->data, p->len, d, nil);
216 uint
217 packetsize(Packet *p)
219 NOTFREE(p);
220 return p->len;
223 Packet*
224 packetsplit(Packet *p, int n)
226 Packet *q;
228 NOTFREE(p);
229 q = packetalloc();
230 q->data = vtmalloc(n);
231 q->arg = q->data;
232 q->free = vtfree;
233 packetconsume(p, q->data, n);
234 return q;
237 void
238 packetstats(void)
242 uchar*
243 packettrailer(Packet *p, int n)
245 NOTFREE(p);
246 if(n < 0)
247 abort();
248 if(n > p->len)
249 abort();
250 return p->data + p->len - n;
253 int
254 packettrim(Packet *p, int offset, int n)
256 NOTFREE(p);
257 if(offset < 0 || n < 0)
258 abort();
259 if(offset+n > p->len)
260 abort();
261 memmove(p->data+offset, p->data+offset+n, p->len-offset-n);
262 p->len -= n;
263 return 0;