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