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