Blob


1 #include <lib9.h>
3 int
4 encodefmt(Fmt *f)
5 {
6 char *out;
7 char *buf, *p;
8 int len;
9 int ilen;
10 int rv;
11 uchar *b;
12 char obuf[64]; // rsc optimization
14 if(!(f->flags&FmtPrec) || f->prec < 1)
15 goto error;
17 b = va_arg(f->args, uchar*);
18 if(b == 0)
19 return fmtstrcpy(f, "<nil>");
21 ilen = f->prec;
22 f->prec = 0;
23 f->flags &= ~FmtPrec;
24 switch(f->r){
25 case '<':
26 len = (8*ilen+4)/5 + 3;
27 break;
28 case '[':
29 len = (8*ilen+5)/6 + 4;
30 break;
31 case 'H':
32 len = 2*ilen + 1;
33 break;
34 default:
35 goto error;
36 }
38 if(len > sizeof(obuf)){
39 buf = malloc(len);
40 if(buf == nil)
41 goto error;
42 } else
43 buf = obuf;
45 // convert
46 out = buf;
47 switch(f->r){
48 case '<':
49 rv = enc32(out, len, b, ilen);
50 break;
51 case '[':
52 rv = enc64(out, len, b, ilen);
53 break;
54 case 'H':
55 rv = enc16(out, len, b, ilen);
56 if(rv >= 0 && (f->flags & FmtLong))
57 for(p = buf; *p; p++)
58 *p = tolower(*p);
59 break;
60 default:
61 rv = -1;
62 break;
63 }
64 if(rv < 0)
65 goto error;
67 fmtstrcpy(f, buf);
68 if(buf != obuf)
69 free(buf);
70 return 0;
72 error:
73 return fmtstrcpy(f, "<encodefmt>");
74 }