encodefmt.c 1.1 KB

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