blob: 6e127986e8ffde812ff0eadc4c17b1a9ffd40d02 [file] [log] [blame]
rscb2cfc4e2003-09-30 17:47:41 +00001#include <lib9.h>
2
3int
4encodefmt(Fmt *f)
5{
6 char *out;
rsce686c2b2004-12-27 00:11:01 +00007 char *buf, *p;
rscb2cfc4e2003-09-30 17:47:41 +00008 int len;
9 int ilen;
10 int rv;
11 uchar *b;
12 char obuf[64]; // rsc optimization
13
rsca3add392004-12-26 23:17:03 +000014 if(!(f->flags&FmtPrec) || f->prec < 1)
rscb2cfc4e2003-09-30 17:47:41 +000015 goto error;
16
17 b = va_arg(f->args, uchar*);
rsca3add392004-12-26 23:17:03 +000018 if(b == 0)
19 return fmtstrcpy(f, "<nil>");
rscb2cfc4e2003-09-30 17:47:41 +000020
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 }
37
38 if(len > sizeof(obuf)){
39 buf = malloc(len);
40 if(buf == nil)
41 goto error;
42 } else
43 buf = obuf;
44
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);
rsca3add392004-12-26 23:17:03 +000056 if(rv >= 0 && (f->flags & FmtLong))
57 for(p = buf; *p; p++)
58 *p = tolower(*p);
rscb2cfc4e2003-09-30 17:47:41 +000059 break;
60 default:
61 rv = -1;
62 break;
63 }
64 if(rv < 0)
65 goto error;
66
67 fmtstrcpy(f, buf);
68 if(buf != obuf)
69 free(buf);
70 return 0;
71
72error:
73 return fmtstrcpy(f, "<encodefmt>");
74}