Mirror of :pserver:cvs@cvs.fefe.de:/cvs libowfat https://www.fefe.de/libowfat/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

72 lines
1.7 KiB

  1. #include "fmt.h"
  2. #ifdef UNITTEST
  3. #undef UNITTEST
  4. #include "fmt_tohex.c"
  5. #define UNITTEST
  6. #endif
  7. static void fmt_hex4(char* dest,uint16_t w) {
  8. dest[3]=fmt_tohex(w&0xf); w>>=4;
  9. dest[2]=fmt_tohex(w&0xf); w>>=4;
  10. dest[1]=fmt_tohex(w&0xf); w>>=4;
  11. dest[0]=fmt_tohex(w&0xf);
  12. }
  13. size_t fmt_escapecharjson(char* dest,uint32_t ch) {
  14. size_t n;
  15. switch (ch) {
  16. case '\b':
  17. ch='b'; goto simple;
  18. case '\n':
  19. ch='n'; goto simple;
  20. case '\r':
  21. ch='r'; goto simple;
  22. case '"':
  23. case '\\':
  24. case '/':
  25. simple:
  26. if (dest) {
  27. dest[0]='\\';
  28. dest[1]=(char)ch;
  29. }
  30. return 2;
  31. }
  32. if (ch>0xffff) {
  33. if (ch>0x10ffff) return 0; // highest representable unicode codepoint
  34. if (dest) {
  35. dest[0]='\\';
  36. dest[1]='u';
  37. fmt_hex4(dest+2,(uint16_t)(0xd800 | (((ch-0x10000)>>10)&0x3ff)));
  38. dest+=6;
  39. }
  40. ch=(ch&0x3ff)|0xdc00;
  41. n=6;
  42. } else
  43. n=0;
  44. if (dest) {
  45. dest[0]='\\';
  46. dest[1]='u';
  47. fmt_hex4(dest+2,(uint16_t)ch);
  48. }
  49. return n+6;
  50. }
  51. #ifdef UNITTEST
  52. #include <assert.h>
  53. #include <string.h>
  54. int main() {
  55. char buf[100];
  56. assert(fmt_escapecharjson(buf,'f')==6 && !memcmp(buf,"\\u0066",6));
  57. assert(fmt_escapecharjson(buf,'\b')==2 && !memcmp(buf,"\\b",2));
  58. assert(fmt_escapecharjson(buf,'\n')==2 && !memcmp(buf,"\\n",2));
  59. assert(fmt_escapecharjson(buf,'\r')==2 && !memcmp(buf,"\\r",2));
  60. assert(fmt_escapecharjson(buf,'"')==2 && !memcmp(buf,"\\\"",2));
  61. assert(fmt_escapecharjson(buf,'\\')==2 && !memcmp(buf,"\\\\",2));
  62. assert(fmt_escapecharjson(buf,'/')==2 && !memcmp(buf,"\\/",2)); /* I'm baffled as well */
  63. assert(fmt_escapecharjson(buf,0x1d11e)==12 && !memcmp(buf,"\\ud834\\udd1e",12)); /* utf-16 surrogate pairs */
  64. return 0;
  65. }
  66. #endif