encodefmt.c 986 B

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