Advertisement
Guest User

Untitled

a guest
Apr 21st, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.66 KB | None | 0 0
  1. /*
  2. * json-encode.c --
  3. *
  4. * Small module to get native json escape in tcl.
  5. *
  6. * Compile:
  7. * mingw: gcc -O2 -DUSE_TCL_STUBS=1 -I$tcl/win -I$tcl/generic json-encode.c -shared -o json.dll libtclstub87.a
  8. * *nix: gcc -O2 -DUSE_TCL_STUBS=1 -I$tcl/unix -I$tcl/generic json-encode.c -shared -o json.so libtclstub87.a
  9. *
  10. * Usage:
  11. * $ tclsh87
  12. * % load json
  13. * % json-encode "string to encode"
  14. */
  15.  
  16. #include "tcl.h"
  17. #include "stdlib.h"
  18.  
  19. /* tcl-generator for _TJson_TokTab *
  20.  
  21. set m [list "\"" "\\\"" \\ \\\\ \b \\b \f \\f \n \\n \r \\r \t \\t \
  22. \x00 \\u0000 \x01 \\u0001 \x02 \\u0002 \x03 \\u0003 \
  23. \x04 \\u0004 \x05 \\u0005 \x06 \\u0006 \x07 \\u0007 \
  24. \x0b \\u000b \x0e \\u000e \x0f \\u000f \x10 \\u0010 \
  25. \x11 \\u0011 \x12 \\u0012 \x13 \\u0013 \x14 \\u0014 \
  26. \x15 \\u0015 \x16 \\u0016 \x17 \\u0017 \x18 \\u0018 \
  27. \x19 \\u0019 \x1a \\u001a \x1b \\u001b \x1c \\u001c \
  28. \x1d \\u001d \x1e \\u001e \x1f \\u001f \x7f \\u007f \
  29. \x80 \\u0080 \x81 \\u0081 \x82 \\u0082 \x83 \\u0083 \
  30. \x84 \\u0084 \x85 \\u0085 \x86 \\u0086 \x87 \\u0087 \
  31. \x88 \\u0088 \x89 \\u0089 \x8a \\u008a \x8b \\u008b \
  32. \x8c \\u008c \x8d \\u008d \x8e \\u008e \x8f \\u008f \
  33. \x90 \\u0090 \x91 \\u0091 \x92 \\u0092 \x93 \\u0093 \
  34. \x94 \\u0094 \x95 \\u0095 \x96 \\u0096 \x97 \\u0097 \
  35. \x98 \\u0098 \x99 \\u0099 \x9a \\u009a \x9b \\u009b \
  36. \x9c \\u009c \x9d \\u009d \x9e \\u009e \x9f \\u009f ]
  37. for {set c 0} {$c <= 127} {} {
  38. time {
  39. set ch [format %c $c]
  40. if {[set cm [string map $m $ch]] ne $ch} {
  41. if {[string range $cm 0 1] ne "\\u"} {
  42. set cm [string range $cm 1 end]
  43. if {$cm eq "\\"} {
  44. append cm "\\"
  45. }
  46. set cm " '$cm' /\* ESC '$cm' *\/,"
  47. } else {
  48. set cm " 1 /\* SPEC '$cm' *\/,"
  49. }
  50. } else {
  51. set cm " 0 /\* NOTOK '[url_encode -extended $ch]' *\/,"
  52. }
  53. puts -nonewline $cm
  54. incr c
  55. } 8
  56. puts ""
  57. }
  58.  
  59. */
  60.  
  61. const char _TJson_TokTab[] = {
  62. 1 /* SPEC '\u0000' */, 1 /* SPEC '\u0001' */, 1 /* SPEC '\u0002' */, 1 /* SPEC '\u0003' */, 1 /* SPEC '\u0004' */, 1 /* SPEC '\u0005' */, 1 /* SPEC '\u0006' */, 1 /* SPEC '\u0007' */,
  63. 'b' /* ESC 'b' */, 't' /* ESC 't' */, 'n' /* ESC 'n' */, 1 /* SPEC '\u000b' */, 'f' /* ESC 'f' */, 'r' /* ESC 'r' */, 1 /* SPEC '\u000e' */, 1 /* SPEC '\u000f' */,
  64. 1 /* SPEC '\u0010' */, 1 /* SPEC '\u0011' */, 1 /* SPEC '\u0012' */, 1 /* SPEC '\u0013' */, 1 /* SPEC '\u0014' */, 1 /* SPEC '\u0015' */, 1 /* SPEC '\u0016' */, 1 /* SPEC '\u0017' */,
  65. 1 /* SPEC '\u0018' */, 1 /* SPEC '\u0019' */, 1 /* SPEC '\u001a' */, 1 /* SPEC '\u001b' */, 1 /* SPEC '\u001c' */, 1 /* SPEC '\u001d' */, 1 /* SPEC '\u001e' */, 1 /* SPEC '\u001f' */,
  66. 0 /* NOTOK '%20' */, 0 /* NOTOK '%21' */, '"' /* ESC '"' */, 0 /* NOTOK '%23' */, 0 /* NOTOK '%24' */, 0 /* NOTOK '%25' */, 0 /* NOTOK '%26' */, 0 /* NOTOK '%27' */,
  67. 0 /* NOTOK '%28' */, 0 /* NOTOK '%29' */, 0 /* NOTOK '%2a' */, 0 /* NOTOK '%2b' */, 0 /* NOTOK '%2c' */, 0 /* NOTOK '-' */, 0 /* NOTOK '.' */, 0 /* NOTOK '%2f' */,
  68. 0 /* NOTOK '0' */, 0 /* NOTOK '1' */, 0 /* NOTOK '2' */, 0 /* NOTOK '3' */, 0 /* NOTOK '4' */, 0 /* NOTOK '5' */, 0 /* NOTOK '6' */, 0 /* NOTOK '7' */,
  69. 0 /* NOTOK '8' */, 0 /* NOTOK '9' */, 0 /* NOTOK '%3a' */, 0 /* NOTOK '%3b' */, 0 /* NOTOK '%3c' */, 0 /* NOTOK '%3d' */, 0 /* NOTOK '%3e' */, 0 /* NOTOK '%3f' */,
  70. 0 /* NOTOK '@' */, 0 /* NOTOK 'A' */, 0 /* NOTOK 'B' */, 0 /* NOTOK 'C' */, 0 /* NOTOK 'D' */, 0 /* NOTOK 'E' */, 0 /* NOTOK 'F' */, 0 /* NOTOK 'G' */,
  71. 0 /* NOTOK 'H' */, 0 /* NOTOK 'I' */, 0 /* NOTOK 'J' */, 0 /* NOTOK 'K' */, 0 /* NOTOK 'L' */, 0 /* NOTOK 'M' */, 0 /* NOTOK 'N' */, 0 /* NOTOK 'O' */,
  72. 0 /* NOTOK 'P' */, 0 /* NOTOK 'Q' */, 0 /* NOTOK 'R' */, 0 /* NOTOK 'S' */, 0 /* NOTOK 'T' */, 0 /* NOTOK 'U' */, 0 /* NOTOK 'V' */, 0 /* NOTOK 'W' */,
  73. 0 /* NOTOK 'X' */, 0 /* NOTOK 'Y' */, 0 /* NOTOK 'Z' */, 0 /* NOTOK '%5b' */, '\\' /* ESC '\\' */, 0 /* NOTOK '%5d' */, 0 /* NOTOK '%5e' */, 0 /* NOTOK '_' */,
  74. 0 /* NOTOK '%60' */, 0 /* NOTOK 'a' */, 0 /* NOTOK 'b' */, 0 /* NOTOK 'c' */, 0 /* NOTOK 'd' */, 0 /* NOTOK 'e' */, 0 /* NOTOK 'f' */, 0 /* NOTOK 'g' */,
  75. 0 /* NOTOK 'h' */, 0 /* NOTOK 'i' */, 0 /* NOTOK 'j' */, 0 /* NOTOK 'k' */, 0 /* NOTOK 'l' */, 0 /* NOTOK 'm' */, 0 /* NOTOK 'n' */, 0 /* NOTOK 'o' */,
  76. 0 /* NOTOK 'p' */, 0 /* NOTOK 'q' */, 0 /* NOTOK 'r' */, 0 /* NOTOK 's' */, 0 /* NOTOK 't' */, 0 /* NOTOK 'u' */, 0 /* NOTOK 'v' */, 0 /* NOTOK 'w' */,
  77. 0 /* NOTOK 'x' */, 0 /* NOTOK 'y' */, 0 /* NOTOK 'z' */, 0 /* NOTOK '%7b' */, 0 /* NOTOK '|' */, 0 /* NOTOK '%7d' */, 0 /* NOTOK '%7e' */, 1 /* SPEC '\u007f' */,
  78. 0
  79. };
  80.  
  81. static
  82. void _TJson_ObjStrToDString(Tcl_DString *ds, Tcl_Obj *inObj)
  83. {
  84. const char *start, *str = Tcl_GetString(inObj);
  85. int len = inObj->length;
  86. int cl;
  87. Tcl_UniChar ch;
  88. char c, buf[2+8+1] = "\\_";
  89.  
  90. if (!len) {
  91. Tcl_DStringAppend(ds, "\"\"", 2);
  92. return;
  93. }
  94.  
  95. Tcl_DStringAppend(ds, "\"", 1);
  96. start = str;
  97. while (len > 0) {
  98. if ( !((ch = *str) & 0x80) ) {
  99. c = _TJson_TokTab[(unsigned)*str];
  100. if (!c) { len--; str++; continue; };
  101. cl = 1;
  102. } else {
  103. cl = Tcl_UtfToUniChar(str, &ch);
  104. c = 1;
  105. }
  106. if (str > start) {
  107. Tcl_DStringAppend(ds, start, str - start);
  108. }
  109. if (c == 1) { /* SPEC escape \uxxxx */
  110. if (ch <= 0xffff) {
  111. buf[1] = 'u';
  112. sprintf(&buf[2], "%04x", (unsigned)ch);
  113. Tcl_DStringAppend(ds, buf, 2+4);
  114. } else { /* TCL_UTF_MAX > 4, special JSON */
  115. buf[1] = 'U';
  116. sprintf(&buf[2], "%08x", (unsigned)ch);
  117. Tcl_DStringAppend(ds, buf, 2+8);
  118. }
  119. } else { /* ESC char \c */
  120. buf[1] = c;
  121. Tcl_DStringAppend(ds, buf, 2);
  122. }
  123. len -= cl, str += cl;
  124. start = str;
  125. }
  126. if (str > start) {
  127. Tcl_DStringAppend(ds, start, str - start);
  128. }
  129. Tcl_DStringAppend(ds, "\"", 1);
  130. }
  131.  
  132. /* ------------------------------------------------------------- */
  133.  
  134. int JsonEncodeObjCmd(
  135. ClientData dummy,
  136. Tcl_Interp* interp,
  137. int objc,
  138. Tcl_Obj * const objv[]
  139. ) {
  140. Tcl_DString ds;
  141.  
  142. if (objc != 2) {
  143. Tcl_WrongNumArgs(interp, 1, objv, "string");
  144. return TCL_ERROR;
  145. }
  146.  
  147. Tcl_DStringInit(&ds);
  148.  
  149. #if 1
  150. _TJson_ObjStrToDString(&ds, objv[1]);
  151. #else
  152. if (_TJson_ObjToDString(interp, &ds, objv[1]) != TCL_OK) {
  153. Tcl_DStringFree(&ds);
  154. return TCL_ERROR;
  155. }
  156. #endif
  157.  
  158. #if 1
  159. Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)));
  160. #else
  161. Tcl_SetObjResult(interp, Tcl_DStringAsObj(&ds));
  162. #endif
  163. return TCL_OK;
  164. }
  165.  
  166. int Json_Init(Tcl_Interp *interp) {
  167. if (!Tcl_InitStubs(interp, "8.5", 0)) {
  168. return TCL_ERROR;
  169. }
  170. Tcl_CreateObjCommand(interp, "json-encode", JsonEncodeObjCmd, NULL, NULL);
  171. return TCL_OK;
  172. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement