added gentoo ebuilds
[libmixp.git] / libmixp / convert.c
blob90dfe1d884bf02cf6cf8dce08a4161e90be63b15
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
6 #include <9p-mixp/mixp.h>
7 #include <9p-mixp/convert.h>
8 #include <9p-mixp/stat.h>
9 #include "mixp_local.h"
11 // #define _DEBUG
13 enum {
14 SByte = 1,
15 SWord = 2,
16 SDWord = 4,
17 SQWord = 8,
21 void
22 mixp_puint(MIXP_MESSAGE *msg, unsigned int size, unsigned int *val) {
23 int v;
25 if(msg->pos + size <= msg->end) {
26 switch(msg->mode) {
27 case MsgPack:
28 v = *val;
29 unsigned short int b;
30 printf("pack int: v=%d\n", v);
31 switch(size) {
32 case SDWord:
33 msg->pos[3] = v>>24;
34 msg->pos[2] = v>>16;
35 b = msg->pos[3];
36 printf("pack int: SDW[3]=%d\n", b);
37 b = msg->pos[2];
38 printf("pack int: SDW[2]=%d\n", b);
39 case SWord:
40 msg->pos[1] = v>>8;
41 b = msg->pos[1];
42 printf("pack int: SDW[1]=%d\n", b);
43 case SByte:
44 msg->pos[0] = v;
45 b = msg->pos[0];
46 printf("pack int: SDW[0]=%d\n", b);
47 break;
48 default:
49 printf("mixp_puint32: unhandled int size: %d\n", size);
51 break;
52 case MsgUnpack:
53 v = 0;
54 unsigned short int a;
55 switch(size) {
56 case SDWord:
57 a = msg->pos[3];
58 printf("SDW pos[3]=%d\n", a);
59 a = msg->pos[2];
60 printf("SDW pos[2]=%d\n", a);
61 v |= msg->pos[3]<<24;
62 v |= msg->pos[2]<<16;
63 case SWord:
64 a = msg->pos[1];
65 printf("SW pos[1]=%d\n", a);
66 v |= msg->pos[1]<<8;
67 case SByte:
68 a = msg->pos[0];
69 printf("B pos[0]=%d\n", a);
70 v |= msg->pos[0];
71 break;
73 *val = v;
74 printf("unpack int: %d\n", v);
77 msg->pos += size;
81 void mixp_pu8_store(MIXP_MESSAGE* msg, uint8_t val)
83 uint8_t v;
85 int size = SByte;
86 if(msg->pos + size <= msg->end)
88 v = val;
89 unsigned char p0 = v;
90 unsigned char* packtext = (unsigned char*)msg->pos;
92 packtext[0] = p0;
93 #ifdef _DEBUG
94 printf("mixp_pu8_store() val=%d text=%02X\n",
95 v,
96 packtext[0]);
97 #endif
99 msg->pos += size;
102 void mixp_pu32_store(MIXP_MESSAGE* msg, uint32_t val)
104 uint32_t v;
106 int size = SDWord;
107 if(msg->pos + size <= msg->end)
109 v = val;
110 unsigned char p3 = v>>24;
111 unsigned char p2 = v>>16;
112 unsigned char p1 = v>>8;
113 unsigned char p0 = v;
114 unsigned char* packtext = (unsigned char*)msg->pos;
116 packtext[3] = p3;
117 packtext[2] = p2;
118 packtext[1] = p1;
119 packtext[0] = p0;
120 #ifdef _DEBUG
121 printf("mixp_pu32_store() val=%d text=%02X:%02X:%02X:%02X\n",
123 packtext[0],
124 packtext[1],
125 packtext[2],
126 packtext[3]);
127 #endif
129 msg->pos += size;
132 void mixp_pu64_store(MIXP_MESSAGE* msg, uint64_t val)
134 uint64_t v;
136 int size = SDWord*2;
137 if(msg->pos + size <= msg->end)
139 v = val;
141 unsigned char p7 = v>>56;
142 unsigned char p6 = v>>48;
143 unsigned char p5 = v>>40;
144 unsigned char p4 = v>>32;
145 unsigned char p3 = v>>24;
146 unsigned char p2 = v>>16;
147 unsigned char p1 = v>>8;
148 unsigned char p0 = v;
149 unsigned char* packtext = (unsigned char*)msg->pos;
151 packtext[7] = p7;
152 packtext[6] = p6;
153 packtext[5] = p5;
154 packtext[4] = p4;
155 packtext[3] = p3;
156 packtext[2] = p2;
157 packtext[1] = p1;
158 packtext[0] = p0;
159 #ifdef _DEBUG
160 fprintf(stderr,"mixp_pu64_store() val=%llu text=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
162 packtext[0],
163 packtext[1],
164 packtext[2],
165 packtext[3],
166 packtext[4],
167 packtext[5],
168 packtext[6],
169 packtext[7]
171 #endif
173 msg->pos += size;
176 void mixp_pu16_store(MIXP_MESSAGE* msg, uint16_t val)
178 uint16_t v;
180 if(msg->pos + SWord <= msg->end)
182 v = val;
183 unsigned char p1 = v>>8;
184 unsigned char p0 = v;
185 unsigned char* packtext = (unsigned char*)msg->pos;
187 packtext[1] = p1;
188 packtext[0] = p0;
189 #ifdef _DEBUG
190 printf("mixp_pu16_store() val=%d text=%02X:%02X\n",
192 packtext[1],
193 packtext[0]);
194 #endif
196 msg->pos += SWord;
199 uint8_t mixp_pu8_load(MIXP_MESSAGE* msg)
201 uint8_t v = 0;
202 if(msg->pos + SByte <= msg->end)
204 unsigned char* packtext = (unsigned char*)msg->pos;
205 v |= packtext[0];
206 #ifdef _DEBUG
207 printf("mixp_pu8_load() val=%d text=%02X\n", v, packtext[0]);
208 #endif
210 msg->pos += SByte;
211 return v;
214 uint32_t mixp_pu32_load(MIXP_MESSAGE* msg)
216 uint32_t v = 0;
217 int size = SDWord;
218 if(msg->pos + size <= msg->end)
220 unsigned char* buf = (unsigned char*)msg->pos;
222 v |= buf[3]<<24;
223 v |= buf[2]<<16;
224 v |= buf[1]<<8;
225 v |= buf[0];
226 #ifdef _DEBUG
227 printf("mixp_pu32_load() value=%d text=%02X:%02X:%02X:%02X\n",
229 buf[0],
230 buf[1],
231 buf[2],
232 buf[3]);
233 #endif
235 msg->pos += size;
236 return v;
239 uint64_t mixp_pu64_load(MIXP_MESSAGE* msg)
241 uint64_t v = 0;
242 int size = SDWord*2;
243 if(msg->pos + size <= msg->end)
245 unsigned char* buf = (unsigned char*)msg->pos;
247 v = buf[0] +
248 (buf[1]<<8) +
249 (buf[2]<<16) +
250 (buf[3]<<24) +
251 ((uint64_t)buf[4]<<32) +
252 ((uint64_t)buf[5]<<40) +
253 ((uint64_t)buf[6]<<48) +
254 ((uint64_t)buf[7]<<52);
256 #ifdef _DEBUG
257 fprintf(stderr,"mixp_pu64_load() value=%llu text=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
259 buf[0],
260 buf[1],
261 buf[2],
262 buf[3],
263 buf[4],
264 buf[5],
265 buf[6],
266 buf[7]);
267 #endif
269 msg->pos += size;
270 return v;
273 uint16_t mixp_pu16_load(MIXP_MESSAGE* msg)
275 uint32_t v = 0;
276 int size = SWord;
277 if(msg->pos + size <= msg->end)
279 unsigned char* buf = (unsigned char*)msg->pos;
281 v |= buf[1]<<8;
282 v |= buf[0];
283 #ifdef _DEBUG
284 printf("mixp_pu16_load() value=%d text=%02X:%02X\n",
286 buf[1],
287 buf[0]);
288 #endif
290 msg->pos += size;
291 return v;
294 void
295 mixp_pu32(MIXP_MESSAGE *msg, uint32_t *val)
297 if (msg->mode == MsgPack)
298 mixp_pu32_store(msg, *val);
299 else
300 *val = mixp_pu32_load(msg);
303 void
304 mixp_psize(MIXP_MESSAGE *msg, size_t *val) {
305 mixp_pu32(msg,val);
308 void
309 mixp_pu8(MIXP_MESSAGE *msg, unsigned char *val)
311 if (msg->mode==MsgPack)
312 mixp_pu8_store(msg,*val);
313 else
314 *val = mixp_pu8_load(msg);
317 void
318 mixp_pu16(MIXP_MESSAGE *msg, unsigned short *val)
320 if (msg->mode == MsgPack)
321 mixp_pu16_store(msg,*val);
322 else
323 *val = mixp_pu16_load(msg);
326 void
327 mixp_pu64(MIXP_MESSAGE *msg, uint64_t *val)
329 if (msg->mode == MsgPack)
330 mixp_pu64_store(msg,*val);
331 else
332 *val = mixp_pu64_load(msg);
335 void
336 mixp_pstring(MIXP_MESSAGE *msg, char **s) {
337 unsigned short len;
339 if(msg->mode == MsgPack)
340 len = strlen(*s);
341 mixp_pu16(msg, &len);
343 if(msg->pos + len <= msg->end) {
344 if(msg->mode == MsgUnpack) {
345 *s = malloc(len + 1);
346 memcpy(*s, msg->pos, len);
347 (*s)[len] = '\0';
348 }else
349 memcpy(msg->pos, *s, len);
351 msg->pos += len;
354 void
355 mixp_pstrings(MIXP_MESSAGE *msg, unsigned short *num, char *strings[]) {
356 char *s = NULL; // suppress compiler warning. YES, it's really okay (look carefully ;-P)
357 unsigned int i, size;
358 unsigned short len;
360 mixp_pu16(msg, num);
361 if(*num > IXP_MAX_WELEM) {
362 msg->pos = msg->end+1;
363 return;
366 if(msg->mode == MsgUnpack) {
367 s = (char*)msg->pos;
368 size = 0;
369 for(i=0; i < *num; i++) {
370 mixp_pu16(msg, &len);
371 msg->pos += len;
372 size += len;
373 if(msg->pos > msg->end)
374 return;
376 msg->pos = s;
377 size += *num;
378 s = malloc(size);
381 for(i=0; i < *num; i++) {
382 if(msg->mode == MsgPack)
383 len = strlen(strings[i]);
384 mixp_pu16(msg, &len);
386 if(msg->mode == MsgUnpack) {
387 memcpy(s, msg->pos, len);
388 strings[i] = s;
389 s += len;
390 msg->pos += len;
391 *s++ = '\0';
392 }else
393 mixp_pdata(msg, &strings[i], len);
397 void
398 mixp_pdata(MIXP_MESSAGE *msg, char **data, unsigned int len) {
399 if(msg->pos + len <= msg->end) {
400 if(msg->mode == MsgUnpack) {
401 *data = malloc(len);
402 memcpy(*data, msg->pos, len);
403 }else
404 memcpy(msg->pos, *data, len);
406 msg->pos += len;
409 void
410 mixp_pqid(MIXP_MESSAGE *msg, MIXP_QID *qid) {
411 mixp_pu8(msg, &qid->type);
412 mixp_pu32(msg, &qid->version);
413 mixp_pu64(msg, &qid->path);
416 void
417 mixp_pqids(MIXP_MESSAGE *msg, unsigned short *num, MIXP_QID qid[]) {
418 int i;
420 mixp_pu16(msg, num);
421 if(*num > IXP_MAX_WELEM) {
422 msg->pos = msg->end+1;
423 return;
426 for(i = 0; i < *num; i++)
427 mixp_pqid(msg, &qid[i]);
431 mixp_pstat(MIXP_MESSAGE *msg, MIXP_STAT *stat) {
432 unsigned short size;
434 if (stat==NULL)
436 fprintf(stderr,"mixp_pstat() stat ptr NULL\n");
437 return -1;
440 if(msg->mode == MsgPack)
441 size = mixp_stat_sizeof(stat) - 2;
443 mixp_pu16(msg, &size);
444 mixp_pu16(msg, &stat->type);
445 mixp_pu32(msg, &stat->dev);
446 mixp_pqid(msg, &stat->qid);
447 mixp_pu32(msg, &stat->mode);
448 mixp_pu32(msg, &stat->atime);
449 mixp_pu32(msg, &stat->mtime);
450 mixp_pu64(msg, &stat->length);
451 mixp_pstring(msg, &stat->name);
452 mixp_pstring(msg, &stat->uid);
453 mixp_pstring(msg, &stat->gid);
454 mixp_pstring(msg, &stat->muid);
456 // fix NULL values
457 if (stat->name == NULL)
458 stat->name = strdup("");
459 if (stat->uid == NULL)
460 stat->uid = strdup("");
461 if (stat->gid == NULL)
462 stat->gid = strdup("");
463 if (stat->muid == NULL)
464 stat->muid = strdup("");
466 return 0;