zsv 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +36 -0
  3. data/LICENSE +21 -0
  4. data/README.md +311 -0
  5. data/ext/zsv/common.h +34 -0
  6. data/ext/zsv/extconf.rb +137 -0
  7. data/ext/zsv/options.c +126 -0
  8. data/ext/zsv/options.h +31 -0
  9. data/ext/zsv/options_internal.h +8 -0
  10. data/ext/zsv/parser.c +300 -0
  11. data/ext/zsv/parser.h +62 -0
  12. data/ext/zsv/row.c +122 -0
  13. data/ext/zsv/row.h +39 -0
  14. data/ext/zsv/vendor/zsv-1.3.0/app/2db.c +756 -0
  15. data/ext/zsv/vendor/zsv-1.3.0/app/2json.c +381 -0
  16. data/ext/zsv/vendor/zsv-1.3.0/app/2tsv.c +228 -0
  17. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/help.c +123 -0
  18. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/license.c +39 -0
  19. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/register.c +104 -0
  20. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/thirdparty.c +41 -0
  21. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/unregister.c +1 -0
  22. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/version.c +14 -0
  23. data/ext/zsv/vendor/zsv-1.3.0/app/check/simdutf_wrapper.h +19 -0
  24. data/ext/zsv/vendor/zsv-1.3.0/app/check/utf8.c +116 -0
  25. data/ext/zsv/vendor/zsv-1.3.0/app/check.c +194 -0
  26. data/ext/zsv/vendor/zsv-1.3.0/app/cli.c +796 -0
  27. data/ext/zsv/vendor/zsv-1.3.0/app/cli_const.h +41 -0
  28. data/ext/zsv/vendor/zsv-1.3.0/app/cli_export.h +16 -0
  29. data/ext/zsv/vendor/zsv-1.3.0/app/cli_ini.c +280 -0
  30. data/ext/zsv/vendor/zsv-1.3.0/app/cli_internal.h +36 -0
  31. data/ext/zsv/vendor/zsv-1.3.0/app/compare.c +913 -0
  32. data/ext/zsv/vendor/zsv-1.3.0/app/compare.h +23 -0
  33. data/ext/zsv/vendor/zsv-1.3.0/app/compare_added_column.c +20 -0
  34. data/ext/zsv/vendor/zsv-1.3.0/app/compare_internal.h +140 -0
  35. data/ext/zsv/vendor/zsv-1.3.0/app/compare_sort.c +91 -0
  36. data/ext/zsv/vendor/zsv-1.3.0/app/compare_unique_colname.c +81 -0
  37. data/ext/zsv/vendor/zsv-1.3.0/app/count-pull.c +82 -0
  38. data/ext/zsv/vendor/zsv-1.3.0/app/count.c +404 -0
  39. data/ext/zsv/vendor/zsv-1.3.0/app/desc.c +569 -0
  40. data/ext/zsv/vendor/zsv-1.3.0/app/echo.c +365 -0
  41. data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/my_extension.c +366 -0
  42. data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/mysheet_extension.c +341 -0
  43. data/ext/zsv/vendor/zsv-1.3.0/app/ext_template/YOUR_EXTENSION_zsvext.c +263 -0
  44. data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.c +298 -0
  45. data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.h +157 -0
  46. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/json_numeric.c +177 -0
  47. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.c +444 -0
  48. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.h +145 -0
  49. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/utils.c +110 -0
  50. data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/include/memfile.h +15 -0
  51. data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/src/memfile.c +64 -0
  52. data/ext/zsv/vendor/zsv-1.3.0/app/external/sglib/sglib.h +1955 -0
  53. data/ext/zsv/vendor/zsv-1.3.0/app/external/simdutf/simdutf.h +6802 -0
  54. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.c +230517 -0
  55. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.h +12174 -0
  56. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_and_csv_vtab.c +2 -0
  57. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.c +142 -0
  58. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.h +49 -0
  59. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-zsv.c +485 -0
  60. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab.c +1015 -0
  61. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3ext.h +663 -0
  62. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/vtab_helper.c +85 -0
  63. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_common.h +75 -0
  64. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_gen.h +167 -0
  65. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_parse.h +228 -0
  66. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_tree.h +186 -0
  67. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_version.h +23 -0
  68. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_common.h +76 -0
  69. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_gen.h +167 -0
  70. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_parse.h +238 -0
  71. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_tree.h +186 -0
  72. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl.c +184 -0
  73. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.c +52 -0
  74. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.h +34 -0
  75. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.c +103 -0
  76. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.h +57 -0
  77. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_bytestack.h +69 -0
  78. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.c +220 -0
  79. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.h +34 -0
  80. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_gen.c +362 -0
  81. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.c +764 -0
  82. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.h +117 -0
  83. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.c +508 -0
  84. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.h +78 -0
  85. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_tree.c +505 -0
  86. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_version.c +7 -0
  87. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/json_value.h +59 -0
  88. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/yajl_helper.h +208 -0
  89. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper.c +795 -0
  90. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper_internal.h +28 -0
  91. data/ext/zsv/vendor/zsv-1.3.0/app/flatten.c +851 -0
  92. data/ext/zsv/vendor/zsv-1.3.0/app/jq.c +106 -0
  93. data/ext/zsv/vendor/zsv-1.3.0/app/jq.h +6 -0
  94. data/ext/zsv/vendor/zsv-1.3.0/app/mv.c +113 -0
  95. data/ext/zsv/vendor/zsv-1.3.0/app/noop.c +90 -0
  96. data/ext/zsv/vendor/zsv-1.3.0/app/overwrite.c +295 -0
  97. data/ext/zsv/vendor/zsv-1.3.0/app/paste.c +175 -0
  98. data/ext/zsv/vendor/zsv-1.3.0/app/pretty.c +693 -0
  99. data/ext/zsv/vendor/zsv-1.3.0/app/prop.c +980 -0
  100. data/ext/zsv/vendor/zsv-1.3.0/app/rm.c +131 -0
  101. data/ext/zsv/vendor/zsv-1.3.0/app/select/fixed.c +130 -0
  102. data/ext/zsv/vendor/zsv-1.3.0/app/select/internal.h +118 -0
  103. data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.c +45 -0
  104. data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.h +41 -0
  105. data/ext/zsv/vendor/zsv-1.3.0/app/select/processing.c +107 -0
  106. data/ext/zsv/vendor/zsv-1.3.0/app/select/rand.c +20 -0
  107. data/ext/zsv/vendor/zsv-1.3.0/app/select/regex.c +61 -0
  108. data/ext/zsv/vendor/zsv-1.3.0/app/select/search.c +14 -0
  109. data/ext/zsv/vendor/zsv-1.3.0/app/select/selection.c +192 -0
  110. data/ext/zsv/vendor/zsv-1.3.0/app/select/usage.c +72 -0
  111. data/ext/zsv/vendor/zsv-1.3.0/app/select-pull.c +812 -0
  112. data/ext/zsv/vendor/zsv-1.3.0/app/select.c +753 -0
  113. data/ext/zsv/vendor/zsv-1.3.0/app/serialize.c +372 -0
  114. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/curses.h +15 -0
  115. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/cursor.c +119 -0
  116. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/errors.c +45 -0
  117. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.c +63 -0
  118. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.h +12 -0
  119. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/filter.c +166 -0
  120. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers.c +214 -0
  121. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers_internal.h +128 -0
  122. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/help.c +43 -0
  123. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.c +81 -0
  124. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.h +25 -0
  125. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.c +325 -0
  126. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.h +73 -0
  127. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/lexer.c +203 -0
  128. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/newline_handler.c +7 -0
  129. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/pivot.c +318 -0
  130. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.c +134 -0
  131. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.h +119 -0
  132. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/read-data.c +322 -0
  133. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.c +203 -0
  134. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.h +36 -0
  135. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet-sql.c +167 -0
  136. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet_internal.h +36 -0
  137. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sqlfilter.c +153 -0
  138. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/terminfo.c +32 -0
  139. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.c +312 -0
  140. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.h +29 -0
  141. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/ui_buffer.c +266 -0
  142. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/usage.c +9 -0
  143. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/utf8-width.c +60 -0
  144. data/ext/zsv/vendor/zsv-1.3.0/app/sheet.c +1007 -0
  145. data/ext/zsv/vendor/zsv-1.3.0/app/sql.c +453 -0
  146. data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.c +101 -0
  147. data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.h +49 -0
  148. data/ext/zsv/vendor/zsv-1.3.0/app/stack.c +393 -0
  149. data/ext/zsv/vendor/zsv-1.3.0/app/utils/arg.c +322 -0
  150. data/ext/zsv/vendor/zsv-1.3.0/app/utils/cache.c +228 -0
  151. data/ext/zsv/vendor/zsv-1.3.0/app/utils/cat.c +91 -0
  152. data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.c +240 -0
  153. data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.h +63 -0
  154. data/ext/zsv/vendor/zsv-1.3.0/app/utils/clock.c +57 -0
  155. data/ext/zsv/vendor/zsv-1.3.0/app/utils/db.c +148 -0
  156. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs-no-jq.c +2 -0
  157. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs.c +427 -0
  158. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_from_json.c +253 -0
  159. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_to_json.c +121 -0
  160. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dl.c +20 -0
  161. data/ext/zsv/vendor/zsv-1.3.0/app/utils/emcc/fs_api.c +159 -0
  162. data/ext/zsv/vendor/zsv-1.3.0/app/utils/err.c +24 -0
  163. data/ext/zsv/vendor/zsv-1.3.0/app/utils/file-mem.c +180 -0
  164. data/ext/zsv/vendor/zsv-1.3.0/app/utils/file.c +256 -0
  165. data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.c +197 -0
  166. data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.h +49 -0
  167. data/ext/zsv/vendor/zsv-1.3.0/app/utils/jq.c +400 -0
  168. data/ext/zsv/vendor/zsv-1.3.0/app/utils/json.c +120 -0
  169. data/ext/zsv/vendor/zsv-1.3.0/app/utils/mem.c +18 -0
  170. data/ext/zsv/vendor/zsv-1.3.0/app/utils/memmem.c +132 -0
  171. data/ext/zsv/vendor/zsv-1.3.0/app/utils/os.c +178 -0
  172. data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite.c +258 -0
  173. data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite_writer.c +246 -0
  174. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8-test.c +123 -0
  175. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.c +153 -0
  176. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.h +54 -0
  177. data/ext/zsv/vendor/zsv-1.3.0/app/utils/prop.c +267 -0
  178. data/ext/zsv/vendor/zsv-1.3.0/app/utils/signal.c +53 -0
  179. data/ext/zsv/vendor/zsv-1.3.0/app/utils/string.c +357 -0
  180. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dir_exists_longpath.c +83 -0
  181. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dl.c +33 -0
  182. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/fopen_longpath.c +184 -0
  183. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/foreach_dirent_longpath.c +292 -0
  184. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.c +259 -0
  185. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.h +13 -0
  186. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/mkdir_longpath.c +255 -0
  187. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/remove_longpath.c +96 -0
  188. data/ext/zsv/vendor/zsv-1.3.0/app/utils/writer.c +361 -0
  189. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command.h +40 -0
  190. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command_standalone.c +16 -0
  191. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_main.h +44 -0
  192. data/ext/zsv/vendor/zsv-1.3.0/examples/js/zsv_parser_api_dummy.c +3 -0
  193. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/parse_by_chunk.c +100 -0
  194. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/print_my_column.c +143 -0
  195. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/pull.c +89 -0
  196. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/simple.c +123 -0
  197. data/ext/zsv/vendor/zsv-1.3.0/fuzz/fuzz.c +16 -0
  198. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/api.h +336 -0
  199. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/common.h +361 -0
  200. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation.h +62 -0
  201. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation_private.h +113 -0
  202. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/sheet.h +73 -0
  203. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext.h +329 -0
  204. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/arg.h +90 -0
  205. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/cache.h +49 -0
  206. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/clock.h +36 -0
  207. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/compiler.h +58 -0
  208. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/db.h +19 -0
  209. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dirs.h +147 -0
  210. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dl.h +22 -0
  211. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/emcc/fs_api.h +28 -0
  212. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/err.h +22 -0
  213. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file-mem.h +17 -0
  214. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file.h +99 -0
  215. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/jq.h +65 -0
  216. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/json.h +19 -0
  217. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/mem.h +19 -0
  218. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/memmem.h +13 -0
  219. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/os.h +54 -0
  220. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite.h +71 -0
  221. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite_writer.h +53 -0
  222. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/prop.h +107 -0
  223. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/signal.h +18 -0
  224. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/sql.h +11 -0
  225. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/string.h +148 -0
  226. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/utf8.h +41 -0
  227. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/win/dl.h +25 -0
  228. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/writer.h +101 -0
  229. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/zsv_export.h +33 -0
  230. data/ext/zsv/vendor/zsv-1.3.0/include/zsv.h +20 -0
  231. data/ext/zsv/vendor/zsv-1.3.0/src/vector_delim.c +60 -0
  232. data/ext/zsv/vendor/zsv-1.3.0/src/zsv.c +484 -0
  233. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_internal.c +731 -0
  234. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_delim.c +285 -0
  235. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_fixed.c +88 -0
  236. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_strencode.c +51 -0
  237. data/ext/zsv/zsv_ext.c +343 -0
  238. data/lib/zsv/version.rb +5 -0
  239. data/lib/zsv.rb +81 -0
  240. metadata +340 -0
@@ -0,0 +1,444 @@
1
+ #include <stdio.h>
2
+ #include <string.h>
3
+ #include <jsonwriter.h>
4
+ #include <math.h>
5
+
6
+ #ifdef INCLUDE_UTILS
7
+ #include "utils.c"
8
+ #else
9
+ unsigned int json_esc1(const unsigned char *s, unsigned int slen, unsigned int *replacelen,
10
+ unsigned char replace[], // replace buff should be at least 8 bytes long
11
+ const unsigned char **new_s, size_t max_output_size);
12
+ #endif
13
+
14
+ struct jsonwriter_output_buff {
15
+ #define JSONWRITER_OUTPUT_BUFF_SIZE 65536
16
+ unsigned char *buff;
17
+ size_t used;
18
+
19
+ size_t (*write)(const void *restrict, size_t, size_t, void *restrict);
20
+ void *write_arg;
21
+ };
22
+
23
+ #define JSONWRITER_MAX_NESTING 256
24
+ struct jsonwriter_data {
25
+ struct jsonwriter_output_buff out;
26
+
27
+ unsigned int depth;
28
+ unsigned char *close_brackets; // length = JSONWRITER_MAX_NESTING
29
+ int *counts; // at each level, the current number of items
30
+ char tmp[128]; // number buffer
31
+
32
+ struct jsonwriter_variant (*to_jsw_variant)(void *);
33
+ void (*after_to_jsw_variant)(void *, struct jsonwriter_variant *);
34
+
35
+ unsigned char just_wrote_key : 1;
36
+ unsigned char compact : 1;
37
+ unsigned char started : 1;
38
+ unsigned char dummy : 5;
39
+ };
40
+
41
+ static inline void jsonwriter_output_buff_flush(struct jsonwriter_output_buff *b) {
42
+ if (b) {
43
+ if (b->used)
44
+ b->write(b->buff, b->used, 1, b->write_arg);
45
+ b->used = 0;
46
+ }
47
+ }
48
+
49
+ #ifndef JSONWRITER_NO_BUFF
50
+ static inline size_t jsonwriter_output_buff_write(struct jsonwriter_output_buff *b, const unsigned char *s, size_t n) {
51
+ if (n) {
52
+ if (n + b->used > JSONWRITER_OUTPUT_BUFF_SIZE) {
53
+ jsonwriter_output_buff_flush(b);
54
+ if (n > JSONWRITER_OUTPUT_BUFF_SIZE) { // n too big, so write directly
55
+ b->write(s, n, 1, b->write_arg);
56
+ return n;
57
+ }
58
+ }
59
+ // n + used < buff size
60
+ memcpy(b->buff + b->used, s, n);
61
+ b->used += n;
62
+ }
63
+ return n;
64
+ }
65
+ #else
66
+
67
+ static inline size_t jsonwriter_output_buff_write(struct jsonwriter_output_buff *b, const unsigned char *s, size_t n) {
68
+ b->write(s, n, 1, b->write_arg);
69
+ }
70
+
71
+ #endif
72
+
73
+ void jsonwriter_set_option(jsonwriter_handle data, enum jsonwriter_option opt) {
74
+ switch (opt) {
75
+ case jsonwriter_option_pretty:
76
+ data->compact = 0;
77
+ break;
78
+ case jsonwriter_option_compact:
79
+ data->compact = 1;
80
+ break;
81
+ }
82
+ }
83
+
84
+ static size_t fwrite2(const void *restrict p, size_t n, size_t size, void *restrict f) {
85
+ return (size_t)fwrite(p, n, size, f);
86
+ }
87
+
88
+ jsonwriter_handle jsonwriter_new(FILE *f) {
89
+ return jsonwriter_new_stream(fwrite2, f);
90
+ }
91
+
92
+ jsonwriter_handle jsonwriter_new_stream(size_t (*write)(const void *restrict, size_t, size_t, void *restrict),
93
+ void *write_arg) {
94
+ struct jsonwriter_data *data = calloc(1, sizeof(*data));
95
+ if (data) {
96
+ data->out.write = write;
97
+ data->out.write_arg = write_arg;
98
+ if (!(data->out.buff = malloc(JSONWRITER_OUTPUT_BUFF_SIZE)) ||
99
+ !(data->close_brackets = malloc(JSONWRITER_MAX_NESTING * sizeof(*data->close_brackets))) ||
100
+ !(data->counts = calloc(JSONWRITER_MAX_NESTING, sizeof(*data->counts)))) {
101
+ // avoid jsonwriter_delete() delete here to suppress compiler warning
102
+ free(data->counts);
103
+ free(data->close_brackets);
104
+ free(data->out.buff);
105
+ free(data);
106
+ data = NULL;
107
+ }
108
+ }
109
+ return data;
110
+ }
111
+
112
+ void jsonwriter_flush(jsonwriter_handle data) {
113
+ if (data->out.used)
114
+ jsonwriter_output_buff_flush(&data->out);
115
+ }
116
+
117
+ void jsonwriter_delete(jsonwriter_handle data) {
118
+ if (!data)
119
+ return;
120
+
121
+ jsonwriter_flush(data);
122
+ if (data->out.buff)
123
+ free(data->out.buff);
124
+ if (data->close_brackets)
125
+ free(data->close_brackets);
126
+ if (data->counts)
127
+ free(data->counts);
128
+ free(data);
129
+ }
130
+
131
+ static size_t jsonwriter_writeln(struct jsonwriter_data *data) {
132
+ if (data->started)
133
+ return jsonwriter_output_buff_write(&data->out, (const unsigned char *)"\n", 1);
134
+ return 0;
135
+ }
136
+
137
+ static int jsonwriter_indent(struct jsonwriter_data *data, unsigned char closing) {
138
+ if (data->just_wrote_key) {
139
+ if (data->compact)
140
+ jsonwriter_output_buff_write(&data->out, (const unsigned char *)":", 1);
141
+ else
142
+ jsonwriter_output_buff_write(&data->out, (const unsigned char *)": ", 2);
143
+ data->just_wrote_key = 0;
144
+ return 0;
145
+ }
146
+
147
+ if (data->depth) {
148
+ if (!closing) { // add a value to the current list
149
+ if (data->counts[data->depth - 1])
150
+ jsonwriter_output_buff_write(&data->out, (const unsigned char *)",", 1);
151
+ data->counts[data->depth - 1]++;
152
+ }
153
+ }
154
+
155
+ if (!data->compact) {
156
+ jsonwriter_writeln(data);
157
+ for (int d = data->depth; d > 0; d--)
158
+ jsonwriter_output_buff_write(&data->out, (const unsigned char *)" ", 2);
159
+ }
160
+ return 0;
161
+ }
162
+
163
+ size_t jsonwriter_write_raw(jsonwriter_handle jsw, const unsigned char *s, size_t len) {
164
+ jsonwriter_indent(jsw, 0);
165
+ return jsonwriter_output_buff_write(&jsw->out, s, len);
166
+ }
167
+
168
+ static enum jsonwriter_status jsonwriter_end_aux(jsonwriter_handle data,
169
+ unsigned char close_bracket) { // return 0 on success
170
+ if (data->depth > 0) {
171
+ if (close_bracket && data->close_brackets[data->depth - 1] != close_bracket)
172
+ return jsonwriter_status_invalid_end;
173
+
174
+ data->depth--;
175
+
176
+ if (data->depth < JSONWRITER_MAX_NESTING - 1) {
177
+ jsonwriter_indent(data, 1);
178
+ jsonwriter_output_buff_write(&data->out, data->close_brackets + data->depth, 1);
179
+ }
180
+ if (data->depth == 0 && !data->compact)
181
+ jsonwriter_writeln(data);
182
+ return jsonwriter_status_ok;
183
+ }
184
+ return jsonwriter_status_invalid_end; // error: nothing to close
185
+ }
186
+
187
+ enum jsonwriter_status jsonwriter_end(jsonwriter_handle data) {
188
+ return jsonwriter_end_aux(data, 0);
189
+ }
190
+
191
+ enum jsonwriter_status jsonwriter_end_array(jsonwriter_handle data) {
192
+ return jsonwriter_end_aux(data, ']');
193
+ }
194
+
195
+ enum jsonwriter_status jsonwriter_end_object(jsonwriter_handle data) {
196
+ return jsonwriter_end_aux(data, '}');
197
+ }
198
+
199
+ int jsonwriter_end_all(jsonwriter_handle data) {
200
+ while (jsonwriter_end(data) == 0)
201
+ ;
202
+ return 0;
203
+ }
204
+
205
+ static int write_json_str(struct jsonwriter_output_buff *b, const unsigned char *s, size_t len,
206
+ unsigned char no_quotes) {
207
+ unsigned int replacelen;
208
+ unsigned char replace[10];
209
+ const unsigned char *end = s + len;
210
+ const unsigned char *new_s;
211
+ size_t written = 0;
212
+ if (!no_quotes)
213
+ jsonwriter_output_buff_write(b, (const unsigned char *)"\"", 1), written++;
214
+
215
+ while (s < end) {
216
+ replacelen = 0;
217
+ unsigned int no_esc = json_esc1((const unsigned char *)s, len, &replacelen, replace, &new_s, len + sizeof(replace));
218
+ if (no_esc)
219
+ jsonwriter_output_buff_write(b, s, no_esc), written += no_esc;
220
+ if (replacelen)
221
+ jsonwriter_output_buff_write(b, replace, replacelen), written += replacelen;
222
+ if (new_s > s) {
223
+ s = new_s;
224
+ len = end - new_s;
225
+ } else
226
+ break;
227
+ }
228
+ if (!no_quotes)
229
+ jsonwriter_output_buff_write(b, (const unsigned char *)"\"", 1), written += 1;
230
+
231
+ return written;
232
+ }
233
+
234
+ static int jsonwriter_str1(jsonwriter_handle data, const unsigned char *s, size_t len) {
235
+ write_json_str(&data->out, s, len, 0);
236
+ return 0;
237
+ }
238
+
239
+ int jsonwriter_null(jsonwriter_handle data) {
240
+ if (data->depth < JSONWRITER_MAX_NESTING) {
241
+ jsonwriter_indent(data, 0);
242
+ jsonwriter_output_buff_write(&data->out, (const unsigned char *)"null", 4);
243
+ return 0;
244
+ }
245
+ return 1;
246
+ }
247
+
248
+ int jsonwriter_bool(jsonwriter_handle data, unsigned char value) {
249
+ if (data->depth < JSONWRITER_MAX_NESTING) {
250
+ jsonwriter_indent(data, 0);
251
+ if (value)
252
+ jsonwriter_output_buff_write(&data->out, (const unsigned char *)"true", 4);
253
+ else
254
+ jsonwriter_output_buff_write(&data->out, (const unsigned char *)"false", 5);
255
+ return 0;
256
+ }
257
+ return 1;
258
+ }
259
+
260
+ int jsonwriter_cstr(jsonwriter_handle data, const char *s) {
261
+ return jsonwriter_str(data, (const unsigned char *)s);
262
+ }
263
+
264
+ int jsonwriter_cstrn(jsonwriter_handle data, const char *s, size_t len) {
265
+ return jsonwriter_strn(data, (const unsigned char *)s, len);
266
+ }
267
+
268
+ int jsonwriter_str(jsonwriter_handle data, const unsigned char *s) {
269
+ if (data->depth < JSONWRITER_MAX_NESTING) {
270
+ jsonwriter_indent(data, 0);
271
+ if (s)
272
+ jsonwriter_str1(data, s, JSW_STRLEN(s));
273
+ else
274
+ jsonwriter_output_buff_write(&data->out, (const unsigned char *)"null", 4);
275
+ return 0;
276
+ }
277
+ return 1;
278
+ }
279
+
280
+ int jsonwriter_strn(jsonwriter_handle data, const unsigned char *s, size_t len) {
281
+ if (data->depth < JSONWRITER_MAX_NESTING) {
282
+ jsonwriter_indent(data, 0);
283
+ jsonwriter_str1(data, s, len);
284
+ return 0;
285
+ }
286
+ return 1;
287
+ }
288
+
289
+ int jsonwriter_object_keyn(jsonwriter_handle data, const char *key, size_t len_or_zero) {
290
+ if (data->depth < JSONWRITER_MAX_NESTING) {
291
+ jsonwriter_indent(data, 0);
292
+ jsonwriter_str1(data, (const unsigned char *)key, len_or_zero == 0 ? JSW_STRLEN(key) : len_or_zero);
293
+ data->just_wrote_key = 1;
294
+ return 0;
295
+ }
296
+ return 1;
297
+ }
298
+
299
+ int jsonwriter_object_key(jsonwriter_handle data, const char *key) {
300
+ return jsonwriter_object_keyn(data, key, strlen(key));
301
+ }
302
+
303
+ int jsonwriter_dblf(jsonwriter_handle data, long double d, const char *format_string,
304
+ unsigned char trim_trailing_zeros_after_dec) {
305
+ if (data->depth < JSONWRITER_MAX_NESTING) {
306
+ jsonwriter_indent(data, 0);
307
+ if (isnan(d)) {
308
+ jsonwriter_output_buff_write(&data->out, (unsigned char *)"\"NaN\"", 5);
309
+ } else {
310
+ if (format_string && !strstr(format_string, "Lf")) // TO DO: return error code
311
+ fprintf(stderr, "Warning: format string passed to jsonwriter_dblf() does not contain Lf: %s\n", format_string);
312
+ format_string = format_string ? format_string : "%0.15Lf";
313
+ int len = snprintf(data->tmp, sizeof(data->tmp), format_string, d);
314
+ // TO DO: check if len < 0 or len > sizeof(data->tmp)
315
+ if (len <= 0 || (size_t)len > sizeof(data->tmp)) { // TO DO: return error code
316
+ fprintf(stderr, "Warning! jsonwriter_dblf failed to print, outputting zero value\n");
317
+ jsonwriter_output_buff_write(&data->out, (const unsigned char *)"0", 1);
318
+ } else {
319
+ if (trim_trailing_zeros_after_dec && memchr(data->tmp, '.', len)) {
320
+ while (len && data->tmp[len - 1] == '0')
321
+ len--;
322
+ if (len && data->tmp[len - 1] == '.')
323
+ len--;
324
+ if (!len) {
325
+ *data->tmp = '0';
326
+ len = 1;
327
+ }
328
+ }
329
+ jsonwriter_output_buff_write(&data->out, (unsigned char *)data->tmp, len);
330
+ }
331
+ }
332
+ return 0;
333
+ }
334
+ return 1;
335
+ }
336
+
337
+ int jsonwriter_dbl(jsonwriter_handle data, long double d) {
338
+ return jsonwriter_dblf(data, d, NULL, 1);
339
+ }
340
+
341
+ int jsonwriter_size_t(jsonwriter_handle data, size_t sz) {
342
+ if (data->depth < JSONWRITER_MAX_NESTING) {
343
+ jsonwriter_indent(data, 0);
344
+ int len = snprintf(data->tmp, sizeof(data->tmp), "%zu", sz);
345
+ if (len < 0 || len >= (int)sizeof(data->tmp))
346
+ jsonwriter_output_buff_write(&data->out, (unsigned char *)"\"NaN\"", 5);
347
+ else
348
+ jsonwriter_output_buff_write(&data->out, (unsigned char *)data->tmp, len);
349
+ return 0;
350
+ }
351
+ return 1;
352
+ }
353
+
354
+ int jsonwriter_int(jsonwriter_handle data, jsw_int64 i) {
355
+ if (data->depth < JSONWRITER_MAX_NESTING) {
356
+ jsonwriter_indent(data, 0);
357
+ int len = snprintf(data->tmp, sizeof(data->tmp), JSW_INT64_PRINTF_FMT, i);
358
+ if (len < 0 || len >= (int)sizeof(data->tmp))
359
+ jsonwriter_output_buff_write(&data->out, (unsigned char *)"\"NaN\"", 5);
360
+ else
361
+ jsonwriter_output_buff_write(&data->out, (unsigned char *)data->tmp, len);
362
+ return 0;
363
+ }
364
+ return 1;
365
+ }
366
+
367
+ static int jsonwriter_go_deeper(struct jsonwriter_data *data, unsigned char open, unsigned char close) {
368
+ if (data->depth < JSONWRITER_MAX_NESTING - 1) {
369
+ jsonwriter_indent(data, 0);
370
+ data->started = 1;
371
+ jsonwriter_output_buff_write(&data->out, &open, 1);
372
+ data->close_brackets[data->depth] = close;
373
+ data->depth++;
374
+ data->counts[data->depth - 1] = 0;
375
+ return 0;
376
+ }
377
+ return 1;
378
+ }
379
+
380
+ int jsonwriter_start_object(jsonwriter_handle data) {
381
+ return jsonwriter_go_deeper((struct jsonwriter_data *)data, '{', '}');
382
+ }
383
+
384
+ int jsonwriter_start_array(jsonwriter_handle data) {
385
+ return jsonwriter_go_deeper((struct jsonwriter_data *)data, '[', ']');
386
+ }
387
+
388
+ enum jsonwriter_status jsonwriter_set_variant_handler(jsonwriter_handle d,
389
+ struct jsonwriter_variant (*to_jsw_variant)(void *),
390
+ void (*cleanup)(void *, struct jsonwriter_variant *)) {
391
+ d->after_to_jsw_variant = cleanup;
392
+ if (!(d->to_jsw_variant = to_jsw_variant))
393
+ return jsonwriter_status_invalid_value;
394
+
395
+ return jsonwriter_status_ok;
396
+ }
397
+
398
+ enum jsonwriter_status jsonwriter_variant(jsonwriter_handle d, void *data) {
399
+ if (!d->to_jsw_variant)
400
+ return jsonwriter_status_misconfiguration;
401
+ struct jsonwriter_variant jv = d->to_jsw_variant(data);
402
+
403
+ int rc = jsonwriter_status_unrecognized_variant_type;
404
+ switch (jv.type) {
405
+ case jsonwriter_datatype_null:
406
+ rc = jsonwriter_null(d);
407
+ break;
408
+ case jsonwriter_datatype_string:
409
+ rc = jsonwriter_str(d, jv.value.str);
410
+ break;
411
+ case jsonwriter_datatype_integer:
412
+ rc = jsonwriter_int(d, jv.value.i);
413
+ break;
414
+ case jsonwriter_datatype_float:
415
+ rc = jsonwriter_dbl(d, jv.value.dbl);
416
+ break;
417
+ case jsonwriter_datatype_bool:
418
+ rc = jsonwriter_bool(d, jv.value.i ? 1 : 0);
419
+ break;
420
+ case jsonwriter_datatype_raw:
421
+ if (jv.value.str)
422
+ rc = jsonwriter_write_raw(d, jv.value.str, strlen((const char *)jv.value.str));
423
+ else
424
+ rc = jsonwriter_null(d);
425
+ break;
426
+ }
427
+ if (d->after_to_jsw_variant)
428
+ d->after_to_jsw_variant(data, &jv);
429
+ return rc;
430
+ }
431
+
432
+ /*
433
+ * Write a value of unknown datatype. If it is numeric or bool
434
+ * conforming to RFC 8259, write it as-is; otherwise treat it
435
+ * as a string and write the stringified value
436
+ */
437
+ #include "json_numeric.c"
438
+ int jsonwriter_unknown(jsonwriter_handle h, const unsigned char *s, size_t len, jsw_uint32 flags) {
439
+ (void)(flags); // reserved
440
+ if (is_valid_json_number((const char *)s, len) || (len == 4 && !memcmp(s, "true", len)) ||
441
+ (len == 5 && !memcmp(s, "false", len)))
442
+ return jsonwriter_write_raw(h, s, len);
443
+ return jsonwriter_strn(h, s, len);
444
+ }
@@ -0,0 +1,145 @@
1
+ #ifndef JSONWRITER_H
2
+ #define JSONWRITER_H
3
+
4
+ #include <stdlib.h>
5
+ #include <stdint.h>
6
+ #include <stdio.h>
7
+ #include <inttypes.h>
8
+
9
+ #define JSW_STRLEN(x) strlen((const char *)x)
10
+
11
+ #ifdef __cplusplus
12
+ extern "C" {
13
+ #endif
14
+
15
+ # ifdef _WIN32
16
+ # define jsw_int64 __int64
17
+ # define JSW_INT64_MIN _I64_MIN
18
+ # define JSW_INT64_MAX _I64_MAX
19
+ # define JSW_INT64_PRINTF_FMT "%"PRId64
20
+ # define jsw_uint32 uint32_t
21
+ # else // not WIN
22
+ # define jsw_int64 int64_t
23
+ # define JSW_INT64_MIN INT64_MIN
24
+ # define JSW_INT64_MAX INT64_MAX
25
+ # define JSW_INT64_PRINTF_FMT "%" PRId64
26
+ # define jsw_uint32 uint32_t
27
+ # endif
28
+
29
+ enum jsonwriter_option {
30
+ jsonwriter_option_pretty = 0,
31
+ jsonwriter_option_compact = 1
32
+ };
33
+
34
+ enum jsonwriter_status {
35
+ jsonwriter_status_ok = 0, // no error
36
+ jsonwriter_status_out_of_memory = 1,
37
+ jsonwriter_status_invalid_value,
38
+ jsonwriter_status_misconfiguration,
39
+ jsonwriter_status_unrecognized_variant_type,
40
+ jsonwriter_status_invalid_end
41
+ };
42
+
43
+ struct jsonwriter_data;
44
+
45
+ typedef struct jsonwriter_data * jsonwriter_handle;
46
+
47
+ jsonwriter_handle jsonwriter_new(FILE *f);
48
+ jsonwriter_handle jsonwriter_new_stream(size_t (*write)(const void *restrict, size_t, size_t, void *restrict),
49
+ void *write_arg);
50
+
51
+ void jsonwriter_set_option(jsonwriter_handle h, enum jsonwriter_option opt);
52
+ void jsonwriter_flush(jsonwriter_handle h);
53
+ void jsonwriter_delete(jsonwriter_handle h);
54
+
55
+ int jsonwriter_start_object(jsonwriter_handle h);
56
+ int jsonwriter_start_array(jsonwriter_handle h);
57
+
58
+ enum jsonwriter_status jsonwriter_end_array(jsonwriter_handle h); // end an error, or return err
59
+ enum jsonwriter_status jsonwriter_end_object(jsonwriter_handle h); // end an object, or return err
60
+ enum jsonwriter_status jsonwriter_end(jsonwriter_handle h); // end either an array or an object, or return err
61
+
62
+ // to do: jsonwriter_end_array() and jsonwriter_end_object(): same as jsonwriter_end, but
63
+ // return an error if no matching open array/obj
64
+ int jsonwriter_end_all(jsonwriter_handle h);
65
+
66
+ int jsonwriter_object_keyn(jsonwriter_handle data, const char *key, size_t len_or_zero);
67
+ int jsonwriter_object_key(jsonwriter_handle h, const char *key);
68
+ #define jsonwriter_object_str(h, key, v) jsonwriter_object_key(h, key), jsonwriter_str(h, v)
69
+ #define jsonwriter_object_strn(h, key, v, len) jsonwriter_object_key(h, key), jsonwriter_strn(h, v, len)
70
+ #define jsonwriter_object_cstr(h, key, v) jsonwriter_object_key(h, key), jsonwriter_cstr(h, v)
71
+ #define jsonwriter_object_cstrn(h, key, v, len) jsonwriter_object_key(h, key), jsonwriter_cstrn(h, v, len)
72
+ #define jsonwriter_object_bool(h, key, v) jsonwriter_object_key(h, key), jsonwriter_bool(h, v)
73
+ #define jsonwriter_object_dbl(h, key, v) jsonwriter_object_key(h, key), jsonwriter_dbl(h, v)
74
+ #define jsonwriter_object_dblf(h, key, v, fmt, t) jsonwriter_object_key(h, key), jsonwriter_dblf(h, v, fmt, t)
75
+ #define jsonwriter_object_int(h, key, v) jsonwriter_object_key(h, key), jsonwriter_int(h, v)
76
+ #define jsonwriter_object_size_t(h, key, v) jsonwriter_object_key(h, key), jsonwriter_size_t(h, v)
77
+ #define jsonwriter_object_null(h, key) jsonwriter_object_key(h, key), jsonwriter_null(h)
78
+ #define jsonwriter_object_array(h, key) jsonwriter_object_key(h, key), jsonwriter_start_array(h)
79
+ #define jsonwriter_object_object(h, key) jsonwriter_object_key(h, key), jsonwriter_start_object(h)
80
+
81
+ int jsonwriter_str(jsonwriter_handle h, const unsigned char *s);
82
+ int jsonwriter_strn(jsonwriter_handle h, const unsigned char *s, size_t len);
83
+ int jsonwriter_cstr(jsonwriter_handle data, const char *s);
84
+ int jsonwriter_cstrn(jsonwriter_handle data, const char *s, size_t len);
85
+ int jsonwriter_bool(jsonwriter_handle h, unsigned char value);
86
+ int jsonwriter_dbl(jsonwriter_handle h, long double d);
87
+ int jsonwriter_dblf(jsonwriter_handle h, long double d, const char *format_string, unsigned char trim_trailing_zeros_after_dec);
88
+
89
+ int jsonwriter_size_t(jsonwriter_handle data, size_t sz);
90
+ int jsonwriter_int(jsonwriter_handle h, jsw_int64 i);
91
+ int jsonwriter_null(jsonwriter_handle h);
92
+
93
+ // optionally, you can configure jsonwriter to handle custom variant types
94
+ enum jsonwriter_datatype {
95
+ jsonwriter_datatype_null = 0,
96
+ jsonwriter_datatype_string = 1,
97
+ jsonwriter_datatype_integer = 2,
98
+ jsonwriter_datatype_float = 3,
99
+ jsonwriter_datatype_bool = 4,
100
+ jsonwriter_datatype_raw = 5, // already stringified, output verbatim
101
+ // possible to do:
102
+ // array
103
+ // object
104
+ };
105
+
106
+ struct jsonwriter_variant {
107
+ enum jsonwriter_datatype type;
108
+ union {
109
+ unsigned char b; // bool
110
+ long int i; // integer
111
+ long double dbl; // double
112
+ unsigned char *str; // string
113
+ // possible to do:
114
+ // void *array; // will require corresponding function pointers to get array size and elements
115
+ // void *object; // will require corresponding function pointers to get object keys and elements
116
+ } value;
117
+ };
118
+
119
+ // jsonwriter_set_variant_handler(): provide jsonwriter with a custom function that converts your data to a jsonwriter_variant
120
+ // with an optional cleanup callback
121
+ // returns 0 on success, nonzero on error
122
+ enum jsonwriter_status
123
+ jsonwriter_set_variant_handler(jsonwriter_handle h,
124
+ struct jsonwriter_variant (*to_jsw_variant)(void *),
125
+ void (*cleanup)(void *, struct jsonwriter_variant *));
126
+
127
+ // write a variant. will use custom to_jsw_variant() to convert data to jsonwriter_variant
128
+ enum jsonwriter_status jsonwriter_variant(jsonwriter_handle h, void *data);
129
+
130
+ // write raw data to the output stream. Note: caller is responsible for ensuring that
131
+ // the raw data is valid JSON
132
+ size_t jsonwriter_write_raw(jsonwriter_handle jsw, const unsigned char *s, size_t len);
133
+
134
+ /*
135
+ * Write a value of unknown datatype. If it is numeric or bool
136
+ * conforming to RFC 8259, write it as-is; otherwise treat it
137
+ * as a string and write the stringified value
138
+ */
139
+ int jsonwriter_unknown(jsonwriter_handle h, const unsigned char *s, size_t len, jsw_uint32 flags);
140
+
141
+ #ifdef __cplusplus
142
+ }
143
+ #endif
144
+
145
+ #endif // #ifndef JSONWRITER_H
@@ -0,0 +1,110 @@
1
+ void str2hex(unsigned char *to, const unsigned char *p, size_t len) {
2
+ static const char *hex = "0123456789abcdef";
3
+
4
+ for (; len--; p++) {
5
+ *to++ = hex[p[0] >> 4];
6
+ *to++ = hex[p[0] & 0x0f];
7
+ }
8
+ }
9
+
10
+ static char UTF8_charLenC(int firstChar) { /* return 0 on eof, -1 on error, > 0 if char read) */
11
+ char len;
12
+ if(firstChar == EOF) len = 0;
13
+ else if(!(firstChar & 128)) len = 1;
14
+ else if((firstChar & 224) == 192) len = 2; /* 110xxxxx */
15
+ else if((firstChar & 240) == 224) len = 3; /* 1110xxxx */
16
+ else if((firstChar & 248) == 240) len = 4; /* 11110xxx */
17
+ else if((firstChar & 252) == 248) len = 5; /* 111110xx */
18
+ else if((firstChar & 254) == 252) len = 6; /* 1111110x */
19
+ else len = -1; /* error */
20
+ return len;
21
+ }
22
+
23
+ #define JSON_ESC_CHAR(c) (c == '"' || c == '\\' || c < 32)
24
+
25
+ static unsigned int json_esc1(const unsigned char *s, unsigned int slen,
26
+ unsigned int *replacelen,
27
+ unsigned char replace[], // replace buff should be at least 8 bytes long
28
+ const unsigned char **new_s,
29
+ size_t max_output_size) {
30
+ unsigned char c;
31
+ char c_len;
32
+ const unsigned char *orig_s = s;
33
+ *replacelen = 0;
34
+
35
+ if(!max_output_size) {
36
+ *new_s = s + slen;
37
+ return 0;
38
+ }
39
+
40
+ while(slen && (c = *s) && (size_t)(s - orig_s) < max_output_size) {
41
+ c_len = UTF8_charLenC(*s);
42
+
43
+ if(c_len > 0 && ((unsigned char)c_len > slen || (size_t)((s - orig_s) + c_len) > max_output_size))
44
+ break; // roll back and return
45
+
46
+ if(c_len > 1) {
47
+ s += c_len;
48
+ slen -= c_len;
49
+ continue;
50
+ } else if(c_len < 0) { // bad utf8
51
+ *replacelen = 0;
52
+ *new_s = s + 1;
53
+ return (unsigned int)(s - orig_s);
54
+ } else if(JSON_ESC_CHAR(c)) {
55
+ char hex = 0;
56
+ switch(c) {
57
+ case '"':
58
+ replace[1] = '"';
59
+ break;
60
+ case '\\':
61
+ replace[1] = '\\';
62
+ break;
63
+ case '\b':
64
+ replace[1] = 'b';
65
+ break;
66
+ case '\f':
67
+ replace[1] = 'f';
68
+ break;
69
+ case '\n':
70
+ replace[1] = 'n';
71
+ break;
72
+ case '\r':
73
+ replace[1] = 'r';
74
+ break;
75
+ case '\t':
76
+ replace[1] = 't';
77
+ break;
78
+ default:
79
+ hex=1;
80
+ }
81
+
82
+ replace[0] = '\\';
83
+ if(hex) {
84
+ // unicode-hex: but 2/3 are not always zeroes...
85
+ replace[1] = 'u';
86
+ replace[2] = '0';
87
+ replace[3] = '0';
88
+ str2hex(replace+4, &c, 1);
89
+ *replacelen = 6;
90
+ replace[6] = '\0';
91
+ } else {
92
+ *replacelen = 2;
93
+ replace[2] = '\0';
94
+ }
95
+
96
+ if((size_t)((s - orig_s) + *replacelen) > max_output_size) {
97
+ *replacelen = 0; // roll back and return
98
+ break;
99
+ }
100
+
101
+ *new_s = s+1;
102
+ return (unsigned int)(s - orig_s);
103
+ }
104
+ s++, slen--;
105
+ }
106
+
107
+ *replacelen = 0;
108
+ *new_s = s;
109
+ return (unsigned int)(s - orig_s);
110
+ }