enclave 0.1.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 (739) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +182 -0
  3. data/Rakefile +30 -0
  4. data/ext/enclave/enclave.c +390 -0
  5. data/ext/enclave/extconf.rb +33 -0
  6. data/ext/enclave/mruby/Makefile +63 -0
  7. data/ext/enclave/mruby/Rakefile +102 -0
  8. data/ext/enclave/mruby/benchmark/bm_ao_render.rb +309 -0
  9. data/ext/enclave/mruby/benchmark/bm_app_lc_fizzbuzz.rb +51 -0
  10. data/ext/enclave/mruby/benchmark/bm_fib.rb +6 -0
  11. data/ext/enclave/mruby/benchmark/bm_mandel_term.rb +34 -0
  12. data/ext/enclave/mruby/benchmark/bm_so_lists.rb +49 -0
  13. data/ext/enclave/mruby/benchmark/bm_so_mandelbrot.rb +65 -0
  14. data/ext/enclave/mruby/benchmark/vm_dispatch_bench.c +197 -0
  15. data/ext/enclave/mruby/benchmark/vm_optimization_bench.rb +513 -0
  16. data/ext/enclave/mruby/build/host/include/mrbconf.h +230 -0
  17. data/ext/enclave/mruby/build/host/include/mruby/array.h +303 -0
  18. data/ext/enclave/mruby/build/host/include/mruby/boxing_nan.h +169 -0
  19. data/ext/enclave/mruby/build/host/include/mruby/boxing_no.h +59 -0
  20. data/ext/enclave/mruby/build/host/include/mruby/boxing_word.h +248 -0
  21. data/ext/enclave/mruby/build/host/include/mruby/class.h +157 -0
  22. data/ext/enclave/mruby/build/host/include/mruby/common.h +127 -0
  23. data/ext/enclave/mruby/build/host/include/mruby/compile.h +187 -0
  24. data/ext/enclave/mruby/build/host/include/mruby/data.h +76 -0
  25. data/ext/enclave/mruby/build/host/include/mruby/debug.h +75 -0
  26. data/ext/enclave/mruby/build/host/include/mruby/dump.h +159 -0
  27. data/ext/enclave/mruby/build/host/include/mruby/endian.h +44 -0
  28. data/ext/enclave/mruby/build/host/include/mruby/error.h +168 -0
  29. data/ext/enclave/mruby/build/host/include/mruby/gc.h +77 -0
  30. data/ext/enclave/mruby/build/host/include/mruby/hash.h +234 -0
  31. data/ext/enclave/mruby/build/host/include/mruby/internal.h +278 -0
  32. data/ext/enclave/mruby/build/host/include/mruby/irep.h +142 -0
  33. data/ext/enclave/mruby/build/host/include/mruby/istruct.h +50 -0
  34. data/ext/enclave/mruby/build/host/include/mruby/khash.h +455 -0
  35. data/ext/enclave/mruby/build/host/include/mruby/mempool.h +19 -0
  36. data/ext/enclave/mruby/build/host/include/mruby/numeric.h +174 -0
  37. data/ext/enclave/mruby/build/host/include/mruby/object.h +44 -0
  38. data/ext/enclave/mruby/build/host/include/mruby/opcode.h +73 -0
  39. data/ext/enclave/mruby/build/host/include/mruby/ops.h +133 -0
  40. data/ext/enclave/mruby/build/host/include/mruby/presym/id.h +895 -0
  41. data/ext/enclave/mruby/build/host/include/mruby/presym/scanning.h +82 -0
  42. data/ext/enclave/mruby/build/host/include/mruby/presym/table.h +1787 -0
  43. data/ext/enclave/mruby/build/host/include/mruby/presym.h +65 -0
  44. data/ext/enclave/mruby/build/host/include/mruby/proc.h +184 -0
  45. data/ext/enclave/mruby/build/host/include/mruby/range.h +77 -0
  46. data/ext/enclave/mruby/build/host/include/mruby/re.h +16 -0
  47. data/ext/enclave/mruby/build/host/include/mruby/string.h +428 -0
  48. data/ext/enclave/mruby/build/host/include/mruby/throw.h +81 -0
  49. data/ext/enclave/mruby/build/host/include/mruby/value.h +471 -0
  50. data/ext/enclave/mruby/build/host/include/mruby/variable.h +108 -0
  51. data/ext/enclave/mruby/build/host/include/mruby/version.h +143 -0
  52. data/ext/enclave/mruby/build/host/include/mruby.h +1632 -0
  53. data/ext/enclave/mruby/build/host/mrbc/include/mruby/presym/id.h +281 -0
  54. data/ext/enclave/mruby/build/host/mrbc/include/mruby/presym/table.h +559 -0
  55. data/ext/enclave/mruby/build/host/mrbgems/gem_init.c +164 -0
  56. data/ext/enclave/mruby/build/host/mrbgems/mruby-array-ext/gem_init.c +650 -0
  57. data/ext/enclave/mruby/build/host/mrbgems/mruby-binding/gem_init.c +21 -0
  58. data/ext/enclave/mruby/build/host/mrbgems/mruby-catch/gem_init.c +86 -0
  59. data/ext/enclave/mruby/build/host/mrbgems/mruby-class-ext/gem_init.c +21 -0
  60. data/ext/enclave/mruby/build/host/mrbgems/mruby-compar-ext/gem_init.c +99 -0
  61. data/ext/enclave/mruby/build/host/mrbgems/mruby-complex/gem_init.c +362 -0
  62. data/ext/enclave/mruby/build/host/mrbgems/mruby-data/gem_init.c +21 -0
  63. data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-chain/gem_init.c +229 -0
  64. data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-ext/gem_init.c +1420 -0
  65. data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-lazy/gem_init.c +602 -0
  66. data/ext/enclave/mruby/build/host/mrbgems/mruby-enumerator/gem_init.c +822 -0
  67. data/ext/enclave/mruby/build/host/mrbgems/mruby-eval/gem_init.c +21 -0
  68. data/ext/enclave/mruby/build/host/mrbgems/mruby-fiber/gem_init.c +21 -0
  69. data/ext/enclave/mruby/build/host/mrbgems/mruby-hash-ext/gem_init.c +591 -0
  70. data/ext/enclave/mruby/build/host/mrbgems/mruby-kernel-ext/gem_init.c +21 -0
  71. data/ext/enclave/mruby/build/host/mrbgems/mruby-math/gem_init.c +21 -0
  72. data/ext/enclave/mruby/build/host/mrbgems/mruby-metaprog/gem_init.c +21 -0
  73. data/ext/enclave/mruby/build/host/mrbgems/mruby-method/gem_init.c +153 -0
  74. data/ext/enclave/mruby/build/host/mrbgems/mruby-numeric-ext/gem_init.c +211 -0
  75. data/ext/enclave/mruby/build/host/mrbgems/mruby-object-ext/gem_init.c +94 -0
  76. data/ext/enclave/mruby/build/host/mrbgems/mruby-objectspace/gem_init.c +21 -0
  77. data/ext/enclave/mruby/build/host/mrbgems/mruby-pack/gem_init.c +21 -0
  78. data/ext/enclave/mruby/build/host/mrbgems/mruby-proc-binding/gem_init.c +21 -0
  79. data/ext/enclave/mruby/build/host/mrbgems/mruby-proc-ext/gem_init.c +237 -0
  80. data/ext/enclave/mruby/build/host/mrbgems/mruby-random/gem_init.c +21 -0
  81. data/ext/enclave/mruby/build/host/mrbgems/mruby-range-ext/gem_init.c +205 -0
  82. data/ext/enclave/mruby/build/host/mrbgems/mruby-rational/gem_init.c +147 -0
  83. data/ext/enclave/mruby/build/host/mrbgems/mruby-set/gem_init.c +487 -0
  84. data/ext/enclave/mruby/build/host/mrbgems/mruby-sprintf/gem_init.c +83 -0
  85. data/ext/enclave/mruby/build/host/mrbgems/mruby-string-ext/gem_init.c +220 -0
  86. data/ext/enclave/mruby/build/host/mrbgems/mruby-struct/gem_init.c +175 -0
  87. data/ext/enclave/mruby/build/host/mrbgems/mruby-symbol-ext/gem_init.c +153 -0
  88. data/ext/enclave/mruby/build/host/mrbgems/mruby-time/gem_init.c +21 -0
  89. data/ext/enclave/mruby/build/host/mrbgems/mruby-toplevel-ext/gem_init.c +78 -0
  90. data/ext/enclave/mruby/build/host/mrblib/mrblib.c +1758 -0
  91. data/ext/enclave/mruby/build_config/ArduinoDue.rb +72 -0
  92. data/ext/enclave/mruby/build_config/IntelEdison.rb +69 -0
  93. data/ext/enclave/mruby/build_config/IntelGalileo.rb +88 -0
  94. data/ext/enclave/mruby/build_config/RX630.rb +63 -0
  95. data/ext/enclave/mruby/build_config/android_arm64_v8a.rb +11 -0
  96. data/ext/enclave/mruby/build_config/android_armeabi_v7a_neon_hard.rb +13 -0
  97. data/ext/enclave/mruby/build_config/bench.rb +11 -0
  98. data/ext/enclave/mruby/build_config/boxing.rb +19 -0
  99. data/ext/enclave/mruby/build_config/chipKITMax32.rb +68 -0
  100. data/ext/enclave/mruby/build_config/ci/gcc-clang.rb +40 -0
  101. data/ext/enclave/mruby/build_config/ci/msvc.rb +20 -0
  102. data/ext/enclave/mruby/build_config/clang-asan.rb +11 -0
  103. data/ext/enclave/mruby/build_config/cosmopolitan.rb +86 -0
  104. data/ext/enclave/mruby/build_config/cross-32bit.rb +14 -0
  105. data/ext/enclave/mruby/build_config/cross-mingw-winetest.rb +90 -0
  106. data/ext/enclave/mruby/build_config/cross-mingw.rb +14 -0
  107. data/ext/enclave/mruby/build_config/default.rb +83 -0
  108. data/ext/enclave/mruby/build_config/dreamcast_shelf.rb +81 -0
  109. data/ext/enclave/mruby/build_config/emscripten-cxx.rb +12 -0
  110. data/ext/enclave/mruby/build_config/emscripten.rb +10 -0
  111. data/ext/enclave/mruby/build_config/gameboyadvance.rb +72 -0
  112. data/ext/enclave/mruby/build_config/helpers/wine_runner.rb +71 -0
  113. data/ext/enclave/mruby/build_config/host-cxx.rb +12 -0
  114. data/ext/enclave/mruby/build_config/host-debug.rb +20 -0
  115. data/ext/enclave/mruby/build_config/host-f32.rb +14 -0
  116. data/ext/enclave/mruby/build_config/host-gprof.rb +14 -0
  117. data/ext/enclave/mruby/build_config/host-m32.rb +15 -0
  118. data/ext/enclave/mruby/build_config/host-nofloat.rb +22 -0
  119. data/ext/enclave/mruby/build_config/host-shared.rb +36 -0
  120. data/ext/enclave/mruby/build_config/i586-pc-msdosdjgpp.rb +76 -0
  121. data/ext/enclave/mruby/build_config/luckfox_pico.rb +106 -0
  122. data/ext/enclave/mruby/build_config/milkv_duo.rb +106 -0
  123. data/ext/enclave/mruby/build_config/minimal.rb +4 -0
  124. data/ext/enclave/mruby/build_config/mrbc.rb +10 -0
  125. data/ext/enclave/mruby/build_config/nintendo_switch.rb +73 -0
  126. data/ext/enclave/mruby/build_config/nintendo_wii.rb +95 -0
  127. data/ext/enclave/mruby/build_config/no-float.rb +17 -0
  128. data/ext/enclave/mruby/build_config/playstationportable.rb +78 -0
  129. data/ext/enclave/mruby/build_config/serenity.rb +26 -0
  130. data/ext/enclave/mruby/build_config.rb +9 -0
  131. data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb +5 -0
  132. data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/src/example.c +23 -0
  133. data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/test/example.rb +7 -0
  134. data/ext/enclave/mruby/examples/mrbgems/c_extension_example/src/example.c +23 -0
  135. data/ext/enclave/mruby/examples/mrbgems/c_extension_example/test/example.c +7 -0
  136. data/ext/enclave/mruby/examples/mrbgems/c_extension_example/test/example.rb +3 -0
  137. data/ext/enclave/mruby/examples/mrbgems/cdata_extension_example/src/example.c +77 -0
  138. data/ext/enclave/mruby/examples/mrbgems/cdata_extension_example/test/example.c +7 -0
  139. data/ext/enclave/mruby/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c +70 -0
  140. data/ext/enclave/mruby/examples/mrbgems/ruby_extension_example/mrblib/example.rb +5 -0
  141. data/ext/enclave/mruby/examples/mrbgems/ruby_extension_example/test/example.rb +3 -0
  142. data/ext/enclave/mruby/include/mrbconf.h +230 -0
  143. data/ext/enclave/mruby/include/mruby/array.h +303 -0
  144. data/ext/enclave/mruby/include/mruby/boxing_nan.h +169 -0
  145. data/ext/enclave/mruby/include/mruby/boxing_no.h +59 -0
  146. data/ext/enclave/mruby/include/mruby/boxing_word.h +248 -0
  147. data/ext/enclave/mruby/include/mruby/class.h +157 -0
  148. data/ext/enclave/mruby/include/mruby/common.h +127 -0
  149. data/ext/enclave/mruby/include/mruby/compile.h +187 -0
  150. data/ext/enclave/mruby/include/mruby/data.h +76 -0
  151. data/ext/enclave/mruby/include/mruby/debug.h +75 -0
  152. data/ext/enclave/mruby/include/mruby/dump.h +159 -0
  153. data/ext/enclave/mruby/include/mruby/endian.h +44 -0
  154. data/ext/enclave/mruby/include/mruby/error.h +168 -0
  155. data/ext/enclave/mruby/include/mruby/gc.h +77 -0
  156. data/ext/enclave/mruby/include/mruby/hash.h +234 -0
  157. data/ext/enclave/mruby/include/mruby/internal.h +278 -0
  158. data/ext/enclave/mruby/include/mruby/irep.h +142 -0
  159. data/ext/enclave/mruby/include/mruby/istruct.h +50 -0
  160. data/ext/enclave/mruby/include/mruby/khash.h +455 -0
  161. data/ext/enclave/mruby/include/mruby/mempool.h +19 -0
  162. data/ext/enclave/mruby/include/mruby/numeric.h +174 -0
  163. data/ext/enclave/mruby/include/mruby/object.h +44 -0
  164. data/ext/enclave/mruby/include/mruby/opcode.h +73 -0
  165. data/ext/enclave/mruby/include/mruby/ops.h +133 -0
  166. data/ext/enclave/mruby/include/mruby/presym/scanning.h +82 -0
  167. data/ext/enclave/mruby/include/mruby/presym.h +65 -0
  168. data/ext/enclave/mruby/include/mruby/proc.h +184 -0
  169. data/ext/enclave/mruby/include/mruby/range.h +77 -0
  170. data/ext/enclave/mruby/include/mruby/re.h +16 -0
  171. data/ext/enclave/mruby/include/mruby/string.h +428 -0
  172. data/ext/enclave/mruby/include/mruby/throw.h +81 -0
  173. data/ext/enclave/mruby/include/mruby/value.h +471 -0
  174. data/ext/enclave/mruby/include/mruby/variable.h +108 -0
  175. data/ext/enclave/mruby/include/mruby/version.h +143 -0
  176. data/ext/enclave/mruby/include/mruby.h +1632 -0
  177. data/ext/enclave/mruby/lib/mruby/amalgam.rb +568 -0
  178. data/ext/enclave/mruby/lib/mruby/build/command.rb +383 -0
  179. data/ext/enclave/mruby/lib/mruby/build/load_gems.rb +383 -0
  180. data/ext/enclave/mruby/lib/mruby/build.rb +616 -0
  181. data/ext/enclave/mruby/lib/mruby/core_ext.rb +61 -0
  182. data/ext/enclave/mruby/lib/mruby/doc.rb +51 -0
  183. data/ext/enclave/mruby/lib/mruby/gem.rb +585 -0
  184. data/ext/enclave/mruby/lib/mruby/lockfile.rb +81 -0
  185. data/ext/enclave/mruby/lib/mruby/presym.rb +167 -0
  186. data/ext/enclave/mruby/lib/mruby/source.rb +32 -0
  187. data/ext/enclave/mruby/mrbgems/default-no-fpu.gembox +3 -0
  188. data/ext/enclave/mruby/mrbgems/default-no-stdio.gembox +4 -0
  189. data/ext/enclave/mruby/mrbgems/default.gembox +25 -0
  190. data/ext/enclave/mruby/mrbgems/full-core.gembox +6 -0
  191. data/ext/enclave/mruby/mrbgems/hal-posix-dir/mrbgem.rake +7 -0
  192. data/ext/enclave/mruby/mrbgems/hal-posix-dir/src/dir_hal.c +193 -0
  193. data/ext/enclave/mruby/mrbgems/hal-posix-io/mrbgem.rake +8 -0
  194. data/ext/enclave/mruby/mrbgems/hal-posix-io/src/io_hal.c +602 -0
  195. data/ext/enclave/mruby/mrbgems/hal-posix-socket/mrbgem.rake +8 -0
  196. data/ext/enclave/mruby/mrbgems/hal-posix-socket/src/socket_hal.c +158 -0
  197. data/ext/enclave/mruby/mrbgems/hal-posix-task/README.md +102 -0
  198. data/ext/enclave/mruby/mrbgems/hal-posix-task/mrbgem.rake +8 -0
  199. data/ext/enclave/mruby/mrbgems/hal-posix-task/src/task_hal.c +252 -0
  200. data/ext/enclave/mruby/mrbgems/hal-win-dir/mrbgem.rake +7 -0
  201. data/ext/enclave/mruby/mrbgems/hal-win-dir/src/dir_hal.c +249 -0
  202. data/ext/enclave/mruby/mrbgems/hal-win-io/mrbgem.rake +11 -0
  203. data/ext/enclave/mruby/mrbgems/hal-win-io/src/io_hal.c +646 -0
  204. data/ext/enclave/mruby/mrbgems/hal-win-socket/mrbgem.rake +12 -0
  205. data/ext/enclave/mruby/mrbgems/hal-win-socket/src/socket_hal.c +177 -0
  206. data/ext/enclave/mruby/mrbgems/hal-win-task/README.md +109 -0
  207. data/ext/enclave/mruby/mrbgems/hal-win-task/mrbgem.rake +11 -0
  208. data/ext/enclave/mruby/mrbgems/hal-win-task/src/task_hal.c +187 -0
  209. data/ext/enclave/mruby/mrbgems/math.gembox +12 -0
  210. data/ext/enclave/mruby/mrbgems/metaprog.gembox +21 -0
  211. data/ext/enclave/mruby/mrbgems/mruby-array-ext/README.md +87 -0
  212. data/ext/enclave/mruby/mrbgems/mruby-array-ext/mrbgem.rake +5 -0
  213. data/ext/enclave/mruby/mrbgems/mruby-array-ext/mrblib/array.rb +784 -0
  214. data/ext/enclave/mruby/mrbgems/mruby-array-ext/src/array.c +1583 -0
  215. data/ext/enclave/mruby/mrbgems/mruby-array-ext/test/array.rb +849 -0
  216. data/ext/enclave/mruby/mrbgems/mruby-benchmark/README.md +257 -0
  217. data/ext/enclave/mruby/mrbgems/mruby-benchmark/mrbgem.rake +10 -0
  218. data/ext/enclave/mruby/mrbgems/mruby-benchmark/mrblib/benchmark.rb +131 -0
  219. data/ext/enclave/mruby/mrbgems/mruby-benchmark/test/benchmark.rb +244 -0
  220. data/ext/enclave/mruby/mrbgems/mruby-bigint/README-fgmp.md +154 -0
  221. data/ext/enclave/mruby/mrbgems/mruby-bigint/README.md +44 -0
  222. data/ext/enclave/mruby/mrbgems/mruby-bigint/core/bigint.c +6335 -0
  223. data/ext/enclave/mruby/mrbgems/mruby-bigint/core/bigint.h +117 -0
  224. data/ext/enclave/mruby/mrbgems/mruby-bigint/mrbgem.rake +10 -0
  225. data/ext/enclave/mruby/mrbgems/mruby-bigint/test/bigint.rb +157 -0
  226. data/ext/enclave/mruby/mrbgems/mruby-bin-config/README.md +46 -0
  227. data/ext/enclave/mruby/mrbgems/mruby-bin-config/mrbgem.rake +49 -0
  228. data/ext/enclave/mruby/mrbgems/mruby-bin-config/mruby-config +46 -0
  229. data/ext/enclave/mruby/mrbgems/mruby-bin-config/mruby-config.bat +92 -0
  230. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/README.md +63 -0
  231. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/bintest/mrdb.rb +283 -0
  232. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/bintest/print.rb +703 -0
  233. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake +10 -0
  234. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +523 -0
  235. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h +26 -0
  236. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c +238 -0
  237. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h +14 -0
  238. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c +88 -0
  239. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h +13 -0
  240. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.c +34 -0
  241. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.h +14 -0
  242. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c +436 -0
  243. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c +509 -0
  244. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c +71 -0
  245. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c +64 -0
  246. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +768 -0
  247. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h +159 -0
  248. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h +24 -0
  249. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h +19 -0
  250. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/README.md +94 -0
  251. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb +58 -0
  252. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake +7 -0
  253. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +808 -0
  254. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_buffer.c +1035 -0
  255. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_buffer.h +185 -0
  256. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_completion.c +797 -0
  257. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_completion.h +132 -0
  258. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_editor.c +1118 -0
  259. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_editor.h +153 -0
  260. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_highlight.c +516 -0
  261. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_highlight.h +95 -0
  262. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_history.c +185 -0
  263. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_history.h +76 -0
  264. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_term.c +491 -0
  265. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_term.h +137 -0
  266. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/README.md +58 -0
  267. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/bintest/mrbc.rb +30 -0
  268. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/mrbgem.rake +15 -0
  269. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +362 -0
  270. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c +104 -0
  271. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/README.md +47 -0
  272. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb +178 -0
  273. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/mrbgem.rake +7 -0
  274. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +380 -0
  275. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/README.md +38 -0
  276. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/bintest/mruby_strip.rb +73 -0
  277. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/mrbgem.rake +7 -0
  278. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby_strip.c +139 -0
  279. data/ext/enclave/mruby/mrbgems/mruby-binding/README.md +256 -0
  280. data/ext/enclave/mruby/mrbgems/mruby-binding/mrbgem.rake +7 -0
  281. data/ext/enclave/mruby/mrbgems/mruby-binding/src/binding.c +518 -0
  282. data/ext/enclave/mruby/mrbgems/mruby-binding/test/binding.c +14 -0
  283. data/ext/enclave/mruby/mrbgems/mruby-binding/test/binding.rb +64 -0
  284. data/ext/enclave/mruby/mrbgems/mruby-catch/README.md +94 -0
  285. data/ext/enclave/mruby/mrbgems/mruby-catch/mrbgem.rake +5 -0
  286. data/ext/enclave/mruby/mrbgems/mruby-catch/mrblib/catch.rb +29 -0
  287. data/ext/enclave/mruby/mrbgems/mruby-catch/src/catch.c +149 -0
  288. data/ext/enclave/mruby/mrbgems/mruby-catch/test/catch.rb +86 -0
  289. data/ext/enclave/mruby/mrbgems/mruby-class-ext/README.md +81 -0
  290. data/ext/enclave/mruby/mrbgems/mruby-class-ext/mrbgem.rake +5 -0
  291. data/ext/enclave/mruby/mrbgems/mruby-class-ext/src/class.c +377 -0
  292. data/ext/enclave/mruby/mrbgems/mruby-class-ext/test/class.rb +46 -0
  293. data/ext/enclave/mruby/mrbgems/mruby-class-ext/test/module.rb +109 -0
  294. data/ext/enclave/mruby/mrbgems/mruby-cmath/README.md +45 -0
  295. data/ext/enclave/mruby/mrbgems/mruby-cmath/mrbgem.rake +8 -0
  296. data/ext/enclave/mruby/mrbgems/mruby-cmath/src/cmath.c +426 -0
  297. data/ext/enclave/mruby/mrbgems/mruby-cmath/test/cmath.rb +41 -0
  298. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/README.md +65 -0
  299. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/mrbgem.rake +5 -0
  300. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb +75 -0
  301. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/test/compar.rb +21 -0
  302. data/ext/enclave/mruby/mrbgems/mruby-compiler/README.md +28 -0
  303. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/codegen.c +7316 -0
  304. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/keywords +52 -0
  305. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/lex.def +207 -0
  306. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/node.h +784 -0
  307. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/parse.y +8977 -0
  308. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/y.tab.c +16136 -0
  309. data/ext/enclave/mruby/mrbgems/mruby-compiler/mrbgem.rake +42 -0
  310. data/ext/enclave/mruby/mrbgems/mruby-complex/README.md +55 -0
  311. data/ext/enclave/mruby/mrbgems/mruby-complex/mrbgem.rake +7 -0
  312. data/ext/enclave/mruby/mrbgems/mruby-complex/mrblib/complex.rb +259 -0
  313. data/ext/enclave/mruby/mrbgems/mruby-complex/src/complex.c +597 -0
  314. data/ext/enclave/mruby/mrbgems/mruby-complex/test/complex.rb +174 -0
  315. data/ext/enclave/mruby/mrbgems/mruby-data/README.md +126 -0
  316. data/ext/enclave/mruby/mrbgems/mruby-data/mrbgem.rake +5 -0
  317. data/ext/enclave/mruby/mrbgems/mruby-data/src/data.c +550 -0
  318. data/ext/enclave/mruby/mrbgems/mruby-data/test/data.rb +76 -0
  319. data/ext/enclave/mruby/mrbgems/mruby-dir/README.md +53 -0
  320. data/ext/enclave/mruby/mrbgems/mruby-dir/include/dir_hal.h +79 -0
  321. data/ext/enclave/mruby/mrbgems/mruby-dir/mrbgem.rake +35 -0
  322. data/ext/enclave/mruby/mrbgems/mruby-dir/mrblib/dir.rb +124 -0
  323. data/ext/enclave/mruby/mrbgems/mruby-dir/src/dir.c +493 -0
  324. data/ext/enclave/mruby/mrbgems/mruby-dir/test/dir.rb +138 -0
  325. data/ext/enclave/mruby/mrbgems/mruby-dir/test/dirtest.c +125 -0
  326. data/ext/enclave/mruby/mrbgems/mruby-encoding/README.md +96 -0
  327. data/ext/enclave/mruby/mrbgems/mruby-encoding/mrbgem.rake +8 -0
  328. data/ext/enclave/mruby/mrbgems/mruby-encoding/src/encoding.c +128 -0
  329. data/ext/enclave/mruby/mrbgems/mruby-encoding/test/numeric.rb +27 -0
  330. data/ext/enclave/mruby/mrbgems/mruby-encoding/test/string.rb +30 -0
  331. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/README.md +80 -0
  332. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/mrbgem.rake +6 -0
  333. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/mrblib/chain.rb +149 -0
  334. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/test/enum_chain.rb +108 -0
  335. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/README.md +487 -0
  336. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/mrbgem.rake +5 -0
  337. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb +938 -0
  338. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/test/enum.rb +223 -0
  339. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/README.md +91 -0
  340. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/mrbgem.rake +7 -0
  341. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/mrblib/lazy.rb +363 -0
  342. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/test/lazy.rb +59 -0
  343. data/ext/enclave/mruby/mrbgems/mruby-enumerator/README.md +89 -0
  344. data/ext/enclave/mruby/mrbgems/mruby-enumerator/mrbgem.rake +6 -0
  345. data/ext/enclave/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +861 -0
  346. data/ext/enclave/mruby/mrbgems/mruby-enumerator/test/enumerator.rb +664 -0
  347. data/ext/enclave/mruby/mrbgems/mruby-errno/README.md +83 -0
  348. data/ext/enclave/mruby/mrbgems/mruby-errno/mrbgem.rake +5 -0
  349. data/ext/enclave/mruby/mrbgems/mruby-errno/mrblib/errno.rb +50 -0
  350. data/ext/enclave/mruby/mrbgems/mruby-errno/src/errno.c +335 -0
  351. data/ext/enclave/mruby/mrbgems/mruby-errno/src/gen.rb +18 -0
  352. data/ext/enclave/mruby/mrbgems/mruby-errno/src/known_errors.def +156 -0
  353. data/ext/enclave/mruby/mrbgems/mruby-errno/src/known_errors_def.cstub +780 -0
  354. data/ext/enclave/mruby/mrbgems/mruby-errno/test/errno.rb +57 -0
  355. data/ext/enclave/mruby/mrbgems/mruby-error/README.md +103 -0
  356. data/ext/enclave/mruby/mrbgems/mruby-error/mrbgem.rake +5 -0
  357. data/ext/enclave/mruby/mrbgems/mruby-error/src/exception.c +143 -0
  358. data/ext/enclave/mruby/mrbgems/mruby-error/test/exception.c +60 -0
  359. data/ext/enclave/mruby/mrbgems/mruby-error/test/exception.rb +55 -0
  360. data/ext/enclave/mruby/mrbgems/mruby-eval/README.md +26 -0
  361. data/ext/enclave/mruby/mrbgems/mruby-eval/mrbgem.rake +10 -0
  362. data/ext/enclave/mruby/mrbgems/mruby-eval/src/eval.c +437 -0
  363. data/ext/enclave/mruby/mrbgems/mruby-eval/test/binding.rb +81 -0
  364. data/ext/enclave/mruby/mrbgems/mruby-eval/test/eval.rb +185 -0
  365. data/ext/enclave/mruby/mrbgems/mruby-exit/mrbgem.rake +5 -0
  366. data/ext/enclave/mruby/mrbgems/mruby-exit/src/mruby_exit.c +83 -0
  367. data/ext/enclave/mruby/mrbgems/mruby-fiber/mrbgem.rake +5 -0
  368. data/ext/enclave/mruby/mrbgems/mruby-fiber/src/fiber.c +575 -0
  369. data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fiber.rb +210 -0
  370. data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fiber2.rb +155 -0
  371. data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fibertest.c +87 -0
  372. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/README.md +392 -0
  373. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/mrbgem.rake +6 -0
  374. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb +408 -0
  375. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/src/hash_ext.c +392 -0
  376. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/test/hash.rb +317 -0
  377. data/ext/enclave/mruby/mrbgems/mruby-io/README.md +198 -0
  378. data/ext/enclave/mruby/mrbgems/mruby-io/include/io_hal.h +451 -0
  379. data/ext/enclave/mruby/mrbgems/mruby-io/include/mruby/io.h +76 -0
  380. data/ext/enclave/mruby/mrbgems/mruby-io/mrbgem.rake +34 -0
  381. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/file.rb +109 -0
  382. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/file_constants.rb +24 -0
  383. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/io.rb +303 -0
  384. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/kernel.rb +175 -0
  385. data/ext/enclave/mruby/mrbgems/mruby-io/src/file.c +1192 -0
  386. data/ext/enclave/mruby/mrbgems/mruby-io/src/file_test.c +403 -0
  387. data/ext/enclave/mruby/mrbgems/mruby-io/src/io.c +2260 -0
  388. data/ext/enclave/mruby/mrbgems/mruby-io/src/mruby_io_gem.c +21 -0
  389. data/ext/enclave/mruby/mrbgems/mruby-io/test/file.rb +415 -0
  390. data/ext/enclave/mruby/mrbgems/mruby-io/test/file_test.rb +112 -0
  391. data/ext/enclave/mruby/mrbgems/mruby-io/test/io.rb +668 -0
  392. data/ext/enclave/mruby/mrbgems/mruby-io/test/mruby_io_test.c +293 -0
  393. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/README.md +165 -0
  394. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/mrbgem.rake +5 -0
  395. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/src/kernel.c +316 -0
  396. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/test/kernel.rb +134 -0
  397. data/ext/enclave/mruby/mrbgems/mruby-math/README.md +77 -0
  398. data/ext/enclave/mruby/mrbgems/mruby-math/mrbgem.rake +5 -0
  399. data/ext/enclave/mruby/mrbgems/mruby-math/src/math.c +753 -0
  400. data/ext/enclave/mruby/mrbgems/mruby-math/test/math.rb +201 -0
  401. data/ext/enclave/mruby/mrbgems/mruby-metaprog/README.md +123 -0
  402. data/ext/enclave/mruby/mrbgems/mruby-metaprog/mrbgem.rake +5 -0
  403. data/ext/enclave/mruby/mrbgems/mruby-metaprog/src/metaprog.c +739 -0
  404. data/ext/enclave/mruby/mrbgems/mruby-metaprog/test/metaprog.rb +465 -0
  405. data/ext/enclave/mruby/mrbgems/mruby-method/README.md +66 -0
  406. data/ext/enclave/mruby/mrbgems/mruby-method/mrbgem.rake +7 -0
  407. data/ext/enclave/mruby/mrbgems/mruby-method/mrblib/method.rb +73 -0
  408. data/ext/enclave/mruby/mrbgems/mruby-method/src/method.c +890 -0
  409. data/ext/enclave/mruby/mrbgems/mruby-method/test/method.rb +514 -0
  410. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/README.md +78 -0
  411. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/mrbgem.rake +5 -0
  412. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb +125 -0
  413. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +527 -0
  414. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb +137 -0
  415. data/ext/enclave/mruby/mrbgems/mruby-object-ext/README.md +144 -0
  416. data/ext/enclave/mruby/mrbgems/mruby-object-ext/mrbgem.rake +5 -0
  417. data/ext/enclave/mruby/mrbgems/mruby-object-ext/mrblib/object.rb +33 -0
  418. data/ext/enclave/mruby/mrbgems/mruby-object-ext/src/object.c +128 -0
  419. data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/nil.rb +16 -0
  420. data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/object.rb +67 -0
  421. data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/object_ext.c +17 -0
  422. data/ext/enclave/mruby/mrbgems/mruby-objectspace/README.md +59 -0
  423. data/ext/enclave/mruby/mrbgems/mruby-objectspace/mrbgem.rake +5 -0
  424. data/ext/enclave/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c +188 -0
  425. data/ext/enclave/mruby/mrbgems/mruby-objectspace/test/objectspace.rb +60 -0
  426. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/README.md +75 -0
  427. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/mrbgem.rake +10 -0
  428. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/src/memsize.c +271 -0
  429. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/test/memsize.rb +63 -0
  430. data/ext/enclave/mruby/mrbgems/mruby-pack/README.md +140 -0
  431. data/ext/enclave/mruby/mrbgems/mruby-pack/mrbgem.rake +5 -0
  432. data/ext/enclave/mruby/mrbgems/mruby-pack/src/pack.c +2129 -0
  433. data/ext/enclave/mruby/mrbgems/mruby-pack/test/pack.rb +202 -0
  434. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/README.md +140 -0
  435. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/mrbgem.rake +10 -0
  436. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/src/proc_binding.c +76 -0
  437. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/test/proc_binding.c +14 -0
  438. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/test/proc_binding.rb +22 -0
  439. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/README.md +107 -0
  440. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/mrbgem.rake +5 -0
  441. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/mrblib/proc.rb +130 -0
  442. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/src/proc.c +267 -0
  443. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/test/proc.c +62 -0
  444. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/test/proc.rb +130 -0
  445. data/ext/enclave/mruby/mrbgems/mruby-random/README.md +272 -0
  446. data/ext/enclave/mruby/mrbgems/mruby-random/mrbgem.rake +5 -0
  447. data/ext/enclave/mruby/mrbgems/mruby-random/src/random.c +608 -0
  448. data/ext/enclave/mruby/mrbgems/mruby-random/test/random.rb +151 -0
  449. data/ext/enclave/mruby/mrbgems/mruby-range-ext/README.md +93 -0
  450. data/ext/enclave/mruby/mrbgems/mruby-range-ext/mrbgem.rake +5 -0
  451. data/ext/enclave/mruby/mrbgems/mruby-range-ext/mrblib/range.rb +155 -0
  452. data/ext/enclave/mruby/mrbgems/mruby-range-ext/src/range.c +236 -0
  453. data/ext/enclave/mruby/mrbgems/mruby-range-ext/test/range.rb +211 -0
  454. data/ext/enclave/mruby/mrbgems/mruby-rational/README.md +61 -0
  455. data/ext/enclave/mruby/mrbgems/mruby-rational/mrbgem.rake +7 -0
  456. data/ext/enclave/mruby/mrbgems/mruby-rational/mrblib/rational.rb +66 -0
  457. data/ext/enclave/mruby/mrbgems/mruby-rational/src/rational.c +1269 -0
  458. data/ext/enclave/mruby/mrbgems/mruby-rational/test/rational.rb +316 -0
  459. data/ext/enclave/mruby/mrbgems/mruby-set/LICENSE +24 -0
  460. data/ext/enclave/mruby/mrbgems/mruby-set/README.md +260 -0
  461. data/ext/enclave/mruby/mrbgems/mruby-set/mrbgem.rake +9 -0
  462. data/ext/enclave/mruby/mrbgems/mruby-set/mrblib/set.rb +325 -0
  463. data/ext/enclave/mruby/mrbgems/mruby-set/mruby-set.gem +6 -0
  464. data/ext/enclave/mruby/mrbgems/mruby-set/src/set.c +1535 -0
  465. data/ext/enclave/mruby/mrbgems/mruby-set/test/set.rb +764 -0
  466. data/ext/enclave/mruby/mrbgems/mruby-sleep/README.md +29 -0
  467. data/ext/enclave/mruby/mrbgems/mruby-sleep/example/sleep.rb +2 -0
  468. data/ext/enclave/mruby/mrbgems/mruby-sleep/mrbgem.rake +5 -0
  469. data/ext/enclave/mruby/mrbgems/mruby-sleep/src/sleep.c +187 -0
  470. data/ext/enclave/mruby/mrbgems/mruby-sleep/test/sleep_test.rb +29 -0
  471. data/ext/enclave/mruby/mrbgems/mruby-socket/README.md +56 -0
  472. data/ext/enclave/mruby/mrbgems/mruby-socket/include/socket_hal.h +83 -0
  473. data/ext/enclave/mruby/mrbgems/mruby-socket/mrbgem.rake +37 -0
  474. data/ext/enclave/mruby/mrbgems/mruby-socket/mrblib/socket.rb +1131 -0
  475. data/ext/enclave/mruby/mrbgems/mruby-socket/src/const.cstub +480 -0
  476. data/ext/enclave/mruby/mrbgems/mruby-socket/src/const.def +172 -0
  477. data/ext/enclave/mruby/mrbgems/mruby-socket/src/gen.rb +17 -0
  478. data/ext/enclave/mruby/mrbgems/mruby-socket/src/socket.c +1374 -0
  479. data/ext/enclave/mruby/mrbgems/mruby-socket/test/addrinfo.rb +91 -0
  480. data/ext/enclave/mruby/mrbgems/mruby-socket/test/basicsocket.rb +17 -0
  481. data/ext/enclave/mruby/mrbgems/mruby-socket/test/ipsocket.rb +44 -0
  482. data/ext/enclave/mruby/mrbgems/mruby-socket/test/socket.rb +38 -0
  483. data/ext/enclave/mruby/mrbgems/mruby-socket/test/sockettest.c +84 -0
  484. data/ext/enclave/mruby/mrbgems/mruby-socket/test/tcpsocket.rb +4 -0
  485. data/ext/enclave/mruby/mrbgems/mruby-socket/test/udpsocket.rb +16 -0
  486. data/ext/enclave/mruby/mrbgems/mruby-socket/test/unix.rb +130 -0
  487. data/ext/enclave/mruby/mrbgems/mruby-sprintf/README.md +235 -0
  488. data/ext/enclave/mruby/mrbgems/mruby-sprintf/mrbgem.rake +5 -0
  489. data/ext/enclave/mruby/mrbgems/mruby-sprintf/mrblib/string.rb +24 -0
  490. data/ext/enclave/mruby/mrbgems/mruby-sprintf/src/sprintf.c +1195 -0
  491. data/ext/enclave/mruby/mrbgems/mruby-sprintf/test/sprintf.rb +92 -0
  492. data/ext/enclave/mruby/mrbgems/mruby-strftime/README.md +140 -0
  493. data/ext/enclave/mruby/mrbgems/mruby-strftime/mrbgem.rake +7 -0
  494. data/ext/enclave/mruby/mrbgems/mruby-strftime/src/strftime.c +119 -0
  495. data/ext/enclave/mruby/mrbgems/mruby-strftime/test/strftime.rb +152 -0
  496. data/ext/enclave/mruby/mrbgems/mruby-string-ext/README.md +886 -0
  497. data/ext/enclave/mruby/mrbgems/mruby-string-ext/mrbgem.rake +5 -0
  498. data/ext/enclave/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +166 -0
  499. data/ext/enclave/mruby/mrbgems/mruby-string-ext/src/string.c +2290 -0
  500. data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/numeric.rb +27 -0
  501. data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/range.rb +26 -0
  502. data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/string.rb +765 -0
  503. data/ext/enclave/mruby/mrbgems/mruby-struct/README.md +105 -0
  504. data/ext/enclave/mruby/mrbgems/mruby-struct/mrbgem.rake +5 -0
  505. data/ext/enclave/mruby/mrbgems/mruby-struct/mrblib/struct.rb +69 -0
  506. data/ext/enclave/mruby/mrbgems/mruby-struct/src/struct.c +812 -0
  507. data/ext/enclave/mruby/mrbgems/mruby-struct/test/struct.rb +303 -0
  508. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/README.md +50 -0
  509. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/mrbgem.rake +5 -0
  510. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/mrblib/symbol.rb +72 -0
  511. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/src/symbol.c +79 -0
  512. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb +55 -0
  513. data/ext/enclave/mruby/mrbgems/mruby-task/README.md +770 -0
  514. data/ext/enclave/mruby/mrbgems/mruby-task/examples/inspection.rb +65 -0
  515. data/ext/enclave/mruby/mrbgems/mruby-task/examples/priority.rb +41 -0
  516. data/ext/enclave/mruby/mrbgems/mruby-task/examples/producer_consumer.rb +58 -0
  517. data/ext/enclave/mruby/mrbgems/mruby-task/examples/simple.rb +27 -0
  518. data/ext/enclave/mruby/mrbgems/mruby-task/examples/statistics.rb +59 -0
  519. data/ext/enclave/mruby/mrbgems/mruby-task/examples/suspend_resume.rb +47 -0
  520. data/ext/enclave/mruby/mrbgems/mruby-task/examples/task_pass.rb +21 -0
  521. data/ext/enclave/mruby/mrbgems/mruby-task/include/task.h +143 -0
  522. data/ext/enclave/mruby/mrbgems/mruby-task/include/task_hal.h +162 -0
  523. data/ext/enclave/mruby/mrbgems/mruby-task/mrbgem.rake +36 -0
  524. data/ext/enclave/mruby/mrbgems/mruby-task/src/task.c +1573 -0
  525. data/ext/enclave/mruby/mrbgems/mruby-task/test/task.rb +185 -0
  526. data/ext/enclave/mruby/mrbgems/mruby-test/README.md +7 -0
  527. data/ext/enclave/mruby/mrbgems/mruby-test/driver.c +315 -0
  528. data/ext/enclave/mruby/mrbgems/mruby-test/mrbgem.rake +173 -0
  529. data/ext/enclave/mruby/mrbgems/mruby-test/vformat.c +151 -0
  530. data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/mrbgem.rake +5 -0
  531. data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/test/inline.c +92 -0
  532. data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/test/inline.rb +118 -0
  533. data/ext/enclave/mruby/mrbgems/mruby-time/README.md +102 -0
  534. data/ext/enclave/mruby/mrbgems/mruby-time/include/mruby/time.h +27 -0
  535. data/ext/enclave/mruby/mrbgems/mruby-time/mrbgem.rake +5 -0
  536. data/ext/enclave/mruby/mrbgems/mruby-time/src/time.c +1739 -0
  537. data/ext/enclave/mruby/mrbgems/mruby-time/test/time.rb +313 -0
  538. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/README.md +32 -0
  539. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/mrbgem.rake +5 -0
  540. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb +24 -0
  541. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/test/toplevel.rb +23 -0
  542. data/ext/enclave/mruby/mrbgems/stdlib-ext.gembox +21 -0
  543. data/ext/enclave/mruby/mrbgems/stdlib-io.gembox +15 -0
  544. data/ext/enclave/mruby/mrbgems/stdlib.gembox +63 -0
  545. data/ext/enclave/mruby/mrblib/10error.rb +23 -0
  546. data/ext/enclave/mruby/mrblib/array.rb +102 -0
  547. data/ext/enclave/mruby/mrblib/compar.rb +102 -0
  548. data/ext/enclave/mruby/mrblib/enum.rb +358 -0
  549. data/ext/enclave/mruby/mrblib/hash.rb +276 -0
  550. data/ext/enclave/mruby/mrblib/kernel.rb +45 -0
  551. data/ext/enclave/mruby/mrblib/numeric.rb +160 -0
  552. data/ext/enclave/mruby/mrblib/range.rb +98 -0
  553. data/ext/enclave/mruby/mrblib/string.rb +173 -0
  554. data/ext/enclave/mruby/mrblib/symbol.rb +8 -0
  555. data/ext/enclave/mruby/oss-fuzz/mruby_fuzzer.c +18 -0
  556. data/ext/enclave/mruby/oss-fuzz/proto_to_ruby.h +55 -0
  557. data/ext/enclave/mruby/src/allocf.c +37 -0
  558. data/ext/enclave/mruby/src/array.c +2302 -0
  559. data/ext/enclave/mruby/src/backtrace.c +294 -0
  560. data/ext/enclave/mruby/src/cdump.c +498 -0
  561. data/ext/enclave/mruby/src/class.c +4394 -0
  562. data/ext/enclave/mruby/src/codedump.c +693 -0
  563. data/ext/enclave/mruby/src/debug.c +290 -0
  564. data/ext/enclave/mruby/src/dump.c +998 -0
  565. data/ext/enclave/mruby/src/enum.c +30 -0
  566. data/ext/enclave/mruby/src/error.c +937 -0
  567. data/ext/enclave/mruby/src/etc.c +421 -0
  568. data/ext/enclave/mruby/src/fmt_fp.c +372 -0
  569. data/ext/enclave/mruby/src/gc.c +1610 -0
  570. data/ext/enclave/mruby/src/hash.c +2355 -0
  571. data/ext/enclave/mruby/src/init.c +50 -0
  572. data/ext/enclave/mruby/src/kernel.c +718 -0
  573. data/ext/enclave/mruby/src/load.c +760 -0
  574. data/ext/enclave/mruby/src/mempool.c +225 -0
  575. data/ext/enclave/mruby/src/numeric.c +2420 -0
  576. data/ext/enclave/mruby/src/numops.c +112 -0
  577. data/ext/enclave/mruby/src/object.c +883 -0
  578. data/ext/enclave/mruby/src/print.c +136 -0
  579. data/ext/enclave/mruby/src/proc.c +572 -0
  580. data/ext/enclave/mruby/src/range.c +597 -0
  581. data/ext/enclave/mruby/src/readfloat.c +228 -0
  582. data/ext/enclave/mruby/src/readint.c +27 -0
  583. data/ext/enclave/mruby/src/readnum.c +43 -0
  584. data/ext/enclave/mruby/src/state.c +247 -0
  585. data/ext/enclave/mruby/src/string.c +3577 -0
  586. data/ext/enclave/mruby/src/symbol.c +1023 -0
  587. data/ext/enclave/mruby/src/value_array.h +28 -0
  588. data/ext/enclave/mruby/src/variable.c +1475 -0
  589. data/ext/enclave/mruby/src/version.c +17 -0
  590. data/ext/enclave/mruby/src/vm.c +3696 -0
  591. data/ext/enclave/mruby/tasks/amalgam.rake +34 -0
  592. data/ext/enclave/mruby/tasks/benchmark.rake +93 -0
  593. data/ext/enclave/mruby/tasks/bin.rake +23 -0
  594. data/ext/enclave/mruby/tasks/core.rake +12 -0
  595. data/ext/enclave/mruby/tasks/doc.rake +118 -0
  596. data/ext/enclave/mruby/tasks/install.rake +40 -0
  597. data/ext/enclave/mruby/tasks/libmruby.rake +90 -0
  598. data/ext/enclave/mruby/tasks/mrbgems.rake +152 -0
  599. data/ext/enclave/mruby/tasks/mrblib.rake +29 -0
  600. data/ext/enclave/mruby/tasks/presym.rake +57 -0
  601. data/ext/enclave/mruby/tasks/test.rake +84 -0
  602. data/ext/enclave/mruby/tasks/toolchains/android.rake +228 -0
  603. data/ext/enclave/mruby/tasks/toolchains/clang.rake +8 -0
  604. data/ext/enclave/mruby/tasks/toolchains/emscripten.rake +57 -0
  605. data/ext/enclave/mruby/tasks/toolchains/gcc.rake +74 -0
  606. data/ext/enclave/mruby/tasks/toolchains/openwrt.rake +32 -0
  607. data/ext/enclave/mruby/tasks/toolchains/visualcpp.rake +48 -0
  608. data/ext/enclave/mruby/test/assert.rb +404 -0
  609. data/ext/enclave/mruby/test/bintest.rb +55 -0
  610. data/ext/enclave/mruby/test/t/argumenterror.rb +37 -0
  611. data/ext/enclave/mruby/test/t/array.rb +478 -0
  612. data/ext/enclave/mruby/test/t/basicobject.rb +10 -0
  613. data/ext/enclave/mruby/test/t/bs_block.rb +621 -0
  614. data/ext/enclave/mruby/test/t/bs_literal.rb +38 -0
  615. data/ext/enclave/mruby/test/t/class.rb +505 -0
  616. data/ext/enclave/mruby/test/t/codegen.rb +196 -0
  617. data/ext/enclave/mruby/test/t/comparable.rb +79 -0
  618. data/ext/enclave/mruby/test/t/ensure.rb +36 -0
  619. data/ext/enclave/mruby/test/t/enumerable.rb +134 -0
  620. data/ext/enclave/mruby/test/t/exception.rb +425 -0
  621. data/ext/enclave/mruby/test/t/false.rb +31 -0
  622. data/ext/enclave/mruby/test/t/float.rb +296 -0
  623. data/ext/enclave/mruby/test/t/gc.rb +45 -0
  624. data/ext/enclave/mruby/test/t/hash.rb +976 -0
  625. data/ext/enclave/mruby/test/t/indexerror.rb +6 -0
  626. data/ext/enclave/mruby/test/t/integer.rb +247 -0
  627. data/ext/enclave/mruby/test/t/iterations.rb +61 -0
  628. data/ext/enclave/mruby/test/t/kernel.rb +462 -0
  629. data/ext/enclave/mruby/test/t/lang.rb +74 -0
  630. data/ext/enclave/mruby/test/t/literals.rb +386 -0
  631. data/ext/enclave/mruby/test/t/localjumperror.rb +13 -0
  632. data/ext/enclave/mruby/test/t/methods.rb +138 -0
  633. data/ext/enclave/mruby/test/t/module.rb +931 -0
  634. data/ext/enclave/mruby/test/t/nameerror.rb +28 -0
  635. data/ext/enclave/mruby/test/t/nil.rb +39 -0
  636. data/ext/enclave/mruby/test/t/nomethoderror.rb +22 -0
  637. data/ext/enclave/mruby/test/t/numeric.rb +114 -0
  638. data/ext/enclave/mruby/test/t/object.rb +10 -0
  639. data/ext/enclave/mruby/test/t/proc.rb +198 -0
  640. data/ext/enclave/mruby/test/t/range.rb +194 -0
  641. data/ext/enclave/mruby/test/t/rangeerror.rb +6 -0
  642. data/ext/enclave/mruby/test/t/regexperror.rb +4 -0
  643. data/ext/enclave/mruby/test/t/runtimeerror.rb +6 -0
  644. data/ext/enclave/mruby/test/t/standarderror.rb +6 -0
  645. data/ext/enclave/mruby/test/t/string.rb +981 -0
  646. data/ext/enclave/mruby/test/t/superclass.rb +46 -0
  647. data/ext/enclave/mruby/test/t/symbol.rb +30 -0
  648. data/ext/enclave/mruby/test/t/syntax.rb +1296 -0
  649. data/ext/enclave/mruby/test/t/true.rb +31 -0
  650. data/ext/enclave/mruby/test/t/typeerror.rb +6 -0
  651. data/ext/enclave/mruby/test/t/unicode.rb +39 -0
  652. data/ext/enclave/mruby/test/t/vformat.rb +57 -0
  653. data/ext/enclave/mruby/tools/lrama/LEGAL.md +12 -0
  654. data/ext/enclave/mruby/tools/lrama/MIT +21 -0
  655. data/ext/enclave/mruby/tools/lrama/NEWS.md +696 -0
  656. data/ext/enclave/mruby/tools/lrama/exe/lrama +7 -0
  657. data/ext/enclave/mruby/tools/lrama/lib/lrama/bitmap.rb +34 -0
  658. data/ext/enclave/mruby/tools/lrama/lib/lrama/command.rb +68 -0
  659. data/ext/enclave/mruby/tools/lrama/lib/lrama/context.rb +499 -0
  660. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/derivation.rb +66 -0
  661. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/example.rb +129 -0
  662. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/path.rb +29 -0
  663. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/production_path.rb +19 -0
  664. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/start_path.rb +23 -0
  665. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/state_item.rb +8 -0
  666. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/transition_path.rb +19 -0
  667. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/triple.rb +23 -0
  668. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples.rb +298 -0
  669. data/ext/enclave/mruby/tools/lrama/lib/lrama/diagnostics.rb +36 -0
  670. data/ext/enclave/mruby/tools/lrama/lib/lrama/digraph.rb +83 -0
  671. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/auxiliary.rb +9 -0
  672. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/binding.rb +67 -0
  673. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/destructor_code.rb +42 -0
  674. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/initial_action_code.rb +36 -0
  675. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/no_reference_code.rb +30 -0
  676. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/printer_code.rb +42 -0
  677. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/rule_action.rb +92 -0
  678. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code.rb +53 -0
  679. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/counter.rb +17 -0
  680. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/destructor.rb +11 -0
  681. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/error_token.rb +11 -0
  682. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb +62 -0
  683. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb +40 -0
  684. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb +24 -0
  685. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule.rb +5 -0
  686. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/percent_code.rb +14 -0
  687. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/precedence.rb +13 -0
  688. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/printer.rb +11 -0
  689. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/reference.rb +16 -0
  690. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/rule.rb +75 -0
  691. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/rule_builder.rb +255 -0
  692. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/stdlib.y +122 -0
  693. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbol.rb +105 -0
  694. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbols/resolver.rb +301 -0
  695. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbols.rb +3 -0
  696. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/type.rb +20 -0
  697. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/union.rb +12 -0
  698. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar.rb +407 -0
  699. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar_validator.rb +37 -0
  700. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/grammar_file.rb +40 -0
  701. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/location.rb +115 -0
  702. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/char.rb +11 -0
  703. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/ident.rb +11 -0
  704. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/instantiate_rule.rb +30 -0
  705. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/tag.rb +16 -0
  706. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/user_code.rb +83 -0
  707. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token.rb +70 -0
  708. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer.rb +191 -0
  709. data/ext/enclave/mruby/tools/lrama/lib/lrama/logger.rb +21 -0
  710. data/ext/enclave/mruby/tools/lrama/lib/lrama/option_parser.rb +169 -0
  711. data/ext/enclave/mruby/tools/lrama/lib/lrama/options.rb +28 -0
  712. data/ext/enclave/mruby/tools/lrama/lib/lrama/output.rb +459 -0
  713. data/ext/enclave/mruby/tools/lrama/lib/lrama/parser.rb +2144 -0
  714. data/ext/enclave/mruby/tools/lrama/lib/lrama/report/duration.rb +27 -0
  715. data/ext/enclave/mruby/tools/lrama/lib/lrama/report/profile.rb +16 -0
  716. data/ext/enclave/mruby/tools/lrama/lib/lrama/report.rb +4 -0
  717. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/reduce.rb +37 -0
  718. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/reduce_reduce_conflict.rb +11 -0
  719. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/resolved_conflict.rb +31 -0
  720. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/shift.rb +15 -0
  721. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/shift_reduce_conflict.rb +11 -0
  722. data/ext/enclave/mruby/tools/lrama/lib/lrama/state.rb +433 -0
  723. data/ext/enclave/mruby/tools/lrama/lib/lrama/states/item.rb +91 -0
  724. data/ext/enclave/mruby/tools/lrama/lib/lrama/states.rb +595 -0
  725. data/ext/enclave/mruby/tools/lrama/lib/lrama/states_reporter.rb +362 -0
  726. data/ext/enclave/mruby/tools/lrama/lib/lrama/trace_reporter.rb +45 -0
  727. data/ext/enclave/mruby/tools/lrama/lib/lrama/version.rb +5 -0
  728. data/ext/enclave/mruby/tools/lrama/lib/lrama.rb +22 -0
  729. data/ext/enclave/mruby/tools/lrama/template/bison/_yacc.h +71 -0
  730. data/ext/enclave/mruby/tools/lrama/template/bison/yacc.c +2068 -0
  731. data/ext/enclave/mruby/tools/lrama/template/bison/yacc.h +40 -0
  732. data/ext/enclave/sandbox_build_config.rb +15 -0
  733. data/ext/enclave/sandbox_core.c +722 -0
  734. data/ext/enclave/sandbox_core.h +87 -0
  735. data/lib/enclave/result.rb +29 -0
  736. data/lib/enclave/tool.rb +38 -0
  737. data/lib/enclave/version.rb +3 -0
  738. data/lib/enclave.rb +73 -0
  739. metadata +819 -0
@@ -0,0 +1,2129 @@
1
+ /*
2
+ ** pack.c - Array#pack, String#unpack
3
+ */
4
+
5
+ #include <mruby.h>
6
+ #include <mruby/error.h>
7
+ #include <mruby/array.h>
8
+ #include <mruby/class.h>
9
+ #include <mruby/numeric.h>
10
+ #include <mruby/string.h>
11
+ #include <mruby/variable.h>
12
+ #include <mruby/endian.h>
13
+ #include <mruby/internal.h>
14
+ #include <mruby/presym.h>
15
+
16
+ #include <ctype.h>
17
+ #include <string.h>
18
+
19
+ #define INT_OVERFLOW_P(n) ((n) < MRB_INT_MIN || (n) > MRB_INT_MAX)
20
+ #define UINT_OVERFLOW_P(n) ((n) > MRB_INT_MAX)
21
+
22
+ #ifndef EOF
23
+ # define EOF (-1) /* for MRB_NO_STDIO */
24
+ #endif
25
+
26
+ struct tmpl {
27
+ mrb_value str;
28
+ int idx;
29
+ };
30
+
31
+ enum pack_dir {
32
+ PACK_DIR_CHAR, /* C */
33
+ PACK_DIR_SHORT, /* S */
34
+ PACK_DIR_LONG, /* L */
35
+ PACK_DIR_QUAD, /* Q */
36
+ //PACK_DIR_INT, /* i */
37
+ //PACK_DIR_VAX,
38
+ PACK_DIR_BER, /* w */
39
+ PACK_DIR_UTF8, /* U */
40
+ PACK_DIR_DOUBLE, /* E */
41
+ PACK_DIR_FLOAT, /* f */
42
+ PACK_DIR_STR, /* A */
43
+ PACK_DIR_HEX, /* h */
44
+ PACK_DIR_BSTR, /* b */
45
+ PACK_DIR_BASE64, /* m */
46
+ PACK_DIR_UU, /* u */
47
+ PACK_DIR_QENC, /* M */
48
+ PACK_DIR_NUL, /* x */
49
+ PACK_DIR_BACK, /* X */
50
+ PACK_DIR_ABS, /* @ */
51
+ PACK_DIR_NONE, /* - */
52
+ };
53
+
54
+ enum pack_type {
55
+ PACK_TYPE_INTEGER,
56
+ PACK_TYPE_FLOAT,
57
+ PACK_TYPE_STRING,
58
+ PACK_TYPE_NONE
59
+ };
60
+
61
+ #define PACK_FLAG_s 0x00000001 /* native size ("_" "!") */
62
+ #define PACK_FLAG_a 0x00000002 /* null padding ("a") */
63
+ #define PACK_FLAG_Z 0x00000004 /* append nul char ("z") */
64
+ #define PACK_FLAG_SIGNED 0x00000008 /* native size ("_" "!") */
65
+ #define PACK_FLAG_GT 0x00000010 /* big endian (">") */
66
+ #define PACK_FLAG_LT 0x00000020 /* little endian ("<") */
67
+ #define PACK_FLAG_WIDTH 0x00000040 /* "count" is "width" */
68
+ #define PACK_FLAG_LSB 0x00000080 /* LSB / low nibble first */
69
+ #define PACK_FLAG_COUNT2 0x00000100 /* "count" is special... */
70
+ #define PACK_FLAG_LITTLEENDIAN 0x00000200 /* little endian actually */
71
+
72
+ #define PACK_BASE64_IGNORE 0xff
73
+ #define PACK_BASE64_PADDING 0xfe
74
+ #define IGN PACK_BASE64_IGNORE
75
+ #define PAD PACK_BASE64_PADDING
76
+
77
+ static const unsigned char base64chars[64] = {
78
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
79
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
80
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
81
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
82
+ };
83
+ static const unsigned char base64_dec_tab[128] = {
84
+ IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN,
85
+ IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN,
86
+ IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN, 62, IGN, IGN, IGN, 63,
87
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, IGN, IGN, IGN, PAD, IGN, IGN,
88
+ IGN, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
89
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, IGN, IGN, IGN, IGN, IGN,
90
+ IGN, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
91
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, IGN, IGN, IGN, IGN, IGN,
92
+ };
93
+
94
+ /* lookup table for hex character to integer conversion */
95
+ static const signed char hex_lookup[256] = {
96
+ /* 0x00-0x0F */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
97
+ /* 0x10-0x1F */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
98
+ /* 0x20-0x2F */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
99
+ /* 0x30-0x3F */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
100
+ /* 0x40-0x4F */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
101
+ /* 0x50-0x5F */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
102
+ /* 0x60-0x6F */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
103
+ /* 0x70-0x7F */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
104
+ /* 0x80-0x8F */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
105
+ /* 0x90-0x9F */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
106
+ /* 0xA0-0xAF */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
107
+ /* 0xB0-0xBF */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
108
+ /* 0xC0-0xCF */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
109
+ /* 0xD0-0xDF */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
110
+ /* 0xE0-0xEF */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
111
+ /* 0xF0-0xFF */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
112
+ };
113
+ /* byte index arrays for endianness optimization */
114
+ static const int be_idx16[2] = {1, 0}; /* big-endian 16-bit: MSB, LSB */
115
+ static const int le_idx16[2] = {0, 1}; /* little-endian 16-bit: LSB, MSB */
116
+ static const int be_idx32[4] = {3, 2, 1, 0}; /* big-endian 32-bit: MSB...LSB */
117
+ static const int le_idx32[4] = {0, 1, 2, 3}; /* little-endian 32-bit: LSB...MSB */
118
+ static const int be_idx64[8] = {7, 6, 5, 4, 3, 2, 1, 0}; /* big-endian 64-bit: MSB...LSB */
119
+ static const int le_idx64[8] = {0, 1, 2, 3, 4, 5, 6, 7}; /* little-endian 64-bit: LSB...MSB */
120
+ /* lookup tables for binary string optimization */
121
+ /* Convert character to bit value (0 or 1) */
122
+ static inline uint8_t char_to_bit(unsigned char c) {
123
+ switch (c) {
124
+ case '0': return 0;
125
+ case '1': return 1;
126
+ default: return 0;
127
+ }
128
+ }
129
+
130
+ static const char bit_to_char[2] = {'0', '1'};
131
+
132
+ /* 8-bit batch processing functions for binary strings */
133
+ static inline uint8_t
134
+ pack_8_bits_msb(const char *src)
135
+ {
136
+ uint8_t result = 0;
137
+ result |= char_to_bit((uint8_t)src[0]) << 7;
138
+ result |= char_to_bit((uint8_t)src[1]) << 6;
139
+ result |= char_to_bit((uint8_t)src[2]) << 5;
140
+ result |= char_to_bit((uint8_t)src[3]) << 4;
141
+ result |= char_to_bit((uint8_t)src[4]) << 3;
142
+ result |= char_to_bit((uint8_t)src[5]) << 2;
143
+ result |= char_to_bit((uint8_t)src[6]) << 1;
144
+ result |= char_to_bit((uint8_t)src[7]);
145
+ return result;
146
+ }
147
+
148
+ static inline uint8_t
149
+ pack_8_bits_lsb(const char *src)
150
+ {
151
+ uint8_t result = 0;
152
+ result |= char_to_bit((uint8_t)src[0]);
153
+ result |= char_to_bit((uint8_t)src[1]) << 1;
154
+ result |= char_to_bit((uint8_t)src[2]) << 2;
155
+ result |= char_to_bit((uint8_t)src[3]) << 3;
156
+ result |= char_to_bit((uint8_t)src[4]) << 4;
157
+ result |= char_to_bit((uint8_t)src[5]) << 5;
158
+ result |= char_to_bit((uint8_t)src[6]) << 6;
159
+ result |= char_to_bit((uint8_t)src[7]) << 7;
160
+ return result;
161
+ }
162
+
163
+ static inline void
164
+ unpack_8_bits_msb(uint8_t byte, char *dst)
165
+ {
166
+ dst[0] = bit_to_char[(byte >> 7) & 1];
167
+ dst[1] = bit_to_char[(byte >> 6) & 1];
168
+ dst[2] = bit_to_char[(byte >> 5) & 1];
169
+ dst[3] = bit_to_char[(byte >> 4) & 1];
170
+ dst[4] = bit_to_char[(byte >> 3) & 1];
171
+ dst[5] = bit_to_char[(byte >> 2) & 1];
172
+ dst[6] = bit_to_char[(byte >> 1) & 1];
173
+ dst[7] = bit_to_char[byte & 1];
174
+ }
175
+
176
+ static inline void
177
+ unpack_8_bits_lsb(uint8_t byte, char *dst)
178
+ {
179
+ dst[0] = bit_to_char[byte & 1];
180
+ dst[1] = bit_to_char[(byte >> 1) & 1];
181
+ dst[2] = bit_to_char[(byte >> 2) & 1];
182
+ dst[3] = bit_to_char[(byte >> 3) & 1];
183
+ dst[4] = bit_to_char[(byte >> 4) & 1];
184
+ dst[5] = bit_to_char[(byte >> 5) & 1];
185
+ dst[6] = bit_to_char[(byte >> 6) & 1];
186
+ dst[7] = bit_to_char[(byte >> 7) & 1];
187
+ }
188
+
189
+ /* character classification for string format optimization */
190
+ #define CHAR_NULL 0x01
191
+ #define CHAR_SPACE 0x02
192
+
193
+ /* Character classification function */
194
+ static inline uint8_t char_class(unsigned char c) {
195
+ switch (c) {
196
+ case '\0': return CHAR_NULL;
197
+ case ' ':
198
+ case '\t':
199
+ case '\n':
200
+ case '\v':
201
+ case '\f':
202
+ case '\r': return CHAR_SPACE;
203
+ default: return 0;
204
+ }
205
+ }
206
+ /* UTF-8 optimization lookup tables */
207
+ /* UTF-8 sequence length lookup table for non-ASCII bytes (0x80-0xFF) */
208
+ /* Index = byte_value - 0x80, so table[0] = info for byte 0x80 */
209
+ static const uint8_t utf8_seq_len_high[128] = {
210
+ /* 0x80-0xBF: Invalid start bytes (continuation bytes) - return 0 for error */
211
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
212
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
213
+
214
+ /* 0xC0-0xDF: 2-byte sequences */
215
+ 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,
216
+
217
+ /* 0xE0-0xEF: 3-byte sequences */
218
+ 3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,
219
+
220
+ /* 0xF0-0xF7: 4-byte sequences */
221
+ 4,4,4,4,4,4,4,4,
222
+
223
+ /* 0xF8-0xFF: Invalid start bytes - return 0 for error */
224
+ 0,0,0,0,0,0,0,0
225
+ };
226
+
227
+ /* Fast validation for UTF-8 continuation bytes (0x80-0xBF) */
228
+ /* Index = byte_value - 0x80 */
229
+ static const uint8_t utf8_is_continuation[128] = {
230
+ /* 0x80-0xBF: Valid continuation bytes */
231
+ 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
232
+ 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
233
+
234
+ /* 0xC0-0xFF: Invalid continuation bytes */
235
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
236
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0
237
+ };
238
+
239
+ /* Helper macro for continuation byte validation */
240
+ #define IS_UTF8_CONTINUATION(byte) \
241
+ ((byte) >= 0x80 && utf8_is_continuation[(byte) - 0x80])
242
+
243
+ /* Quoted-printable optimization lookup table */
244
+ /* 0=literal, 1=encode, 2=special (newline) */
245
+ static const uint8_t qprint_encode_type[256] = {
246
+ /* 0x00-0x1F: Control characters - encode */
247
+ 1,1,1,1,1,1,1,1, 1,0,2,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
248
+ /* \t \n */
249
+
250
+ /* 0x20-0x3F: Printable ASCII */
251
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,1,0,0,
252
+ /* = */
253
+
254
+ /* 0x40-0x5F: Printable ASCII */
255
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
256
+
257
+ /* 0x60-0x7F: Printable ASCII */
258
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,
259
+ /* DEL*/
260
+
261
+ /* 0x80-0xFF: High-bit characters - encode */
262
+ 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
263
+ 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
264
+ 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
265
+ 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1
266
+ };
267
+
268
+ /* UU-encoding optimization lookup tables */
269
+ /* UU-encoding uses 6-bit values mapped to ASCII 32-95, but space (32) -> backtick (96) */
270
+ static const char uu_encode_table[64] = {
271
+ '`', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
272
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
273
+ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
274
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_'
275
+ };
276
+
277
+ /* UU-decoding lookup table for ASCII 32-127 */
278
+ static const int8_t uu_decode_table[96] = {
279
+ /* ASCII 32-47: ` ! " # $ % & ' ( ) * + , - . / */
280
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
281
+ /* ASCII 48-63: 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
282
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
283
+ /* ASCII 64-79: @ A B C D E F G H I J K L M N O */
284
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
285
+ /* ASCII 80-95: P Q R S T U V W X Y Z [ \ ] ^ _ */
286
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
287
+ /* ASCII 96-127: ` a b c... (invalid for UU, but ` = 0 for decoding) */
288
+ 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
289
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
290
+ };
291
+
292
+ /* template parsing optimization structures */
293
+ typedef struct {
294
+ enum pack_dir dir;
295
+ enum pack_type type;
296
+ int size;
297
+ unsigned int base_flags;
298
+ } format_info_t;
299
+
300
+ /* Format character lookup function */
301
+ static inline format_info_t pack_format_info(unsigned char c) {
302
+ switch (c) {
303
+ case 'A': return (format_info_t){PACK_DIR_STR, PACK_TYPE_STRING, 0, PACK_FLAG_WIDTH | PACK_FLAG_COUNT2};
304
+ case 'a': return (format_info_t){PACK_DIR_STR, PACK_TYPE_STRING, 0, PACK_FLAG_WIDTH | PACK_FLAG_COUNT2 | PACK_FLAG_a};
305
+ case 'B': return (format_info_t){PACK_DIR_BSTR, PACK_TYPE_STRING, 0, PACK_FLAG_COUNT2};
306
+ case 'b': return (format_info_t){PACK_DIR_BSTR, PACK_TYPE_STRING, 0, PACK_FLAG_COUNT2 | PACK_FLAG_LSB};
307
+ case 'C': return (format_info_t){PACK_DIR_CHAR, PACK_TYPE_INTEGER, 1, 0};
308
+ case 'c': return (format_info_t){PACK_DIR_CHAR, PACK_TYPE_INTEGER, 1, PACK_FLAG_SIGNED};
309
+ case 'D': return (format_info_t){PACK_DIR_DOUBLE, PACK_TYPE_FLOAT, 8, PACK_FLAG_SIGNED};
310
+ case 'd': return (format_info_t){PACK_DIR_DOUBLE, PACK_TYPE_FLOAT, 8, PACK_FLAG_SIGNED};
311
+ case 'E': return (format_info_t){PACK_DIR_DOUBLE, PACK_TYPE_FLOAT, 8, PACK_FLAG_SIGNED | PACK_FLAG_LT};
312
+ case 'e': return (format_info_t){PACK_DIR_FLOAT, PACK_TYPE_FLOAT, 4, PACK_FLAG_SIGNED | PACK_FLAG_LT};
313
+ case 'F': return (format_info_t){PACK_DIR_FLOAT, PACK_TYPE_FLOAT, 4, PACK_FLAG_SIGNED};
314
+ case 'f': return (format_info_t){PACK_DIR_FLOAT, PACK_TYPE_FLOAT, 4, PACK_FLAG_SIGNED};
315
+ case 'G': return (format_info_t){PACK_DIR_DOUBLE, PACK_TYPE_FLOAT, 8, PACK_FLAG_SIGNED | PACK_FLAG_GT};
316
+ case 'g': return (format_info_t){PACK_DIR_FLOAT, PACK_TYPE_FLOAT, 4, PACK_FLAG_SIGNED | PACK_FLAG_GT};
317
+ case 'H': return (format_info_t){PACK_DIR_HEX, PACK_TYPE_STRING, 0, PACK_FLAG_COUNT2};
318
+ case 'h': return (format_info_t){PACK_DIR_HEX, PACK_TYPE_STRING, 0, PACK_FLAG_COUNT2 | PACK_FLAG_LSB};
319
+ /* I, i, J, j are handled specially based on sizeof() */
320
+ case 'L': return (format_info_t){PACK_DIR_LONG, PACK_TYPE_INTEGER, 4, 0};
321
+ case 'l': return (format_info_t){PACK_DIR_LONG, PACK_TYPE_INTEGER, 4, PACK_FLAG_SIGNED};
322
+ case 'M': return (format_info_t){PACK_DIR_QENC, PACK_TYPE_STRING, 0, PACK_FLAG_WIDTH | PACK_FLAG_COUNT2};
323
+ case 'm': return (format_info_t){PACK_DIR_BASE64, PACK_TYPE_STRING, 0, PACK_FLAG_WIDTH | PACK_FLAG_COUNT2};
324
+ case 'N': return (format_info_t){PACK_DIR_LONG, PACK_TYPE_INTEGER, 4, PACK_FLAG_GT};
325
+ case 'n': return (format_info_t){PACK_DIR_SHORT, PACK_TYPE_INTEGER, 2, PACK_FLAG_GT};
326
+ case 'Q': return (format_info_t){PACK_DIR_QUAD, PACK_TYPE_INTEGER, 8, 0};
327
+ case 'q': return (format_info_t){PACK_DIR_QUAD, PACK_TYPE_INTEGER, 8, PACK_FLAG_SIGNED};
328
+ case 'S': return (format_info_t){PACK_DIR_SHORT, PACK_TYPE_INTEGER, 2, 0};
329
+ case 's': return (format_info_t){PACK_DIR_SHORT, PACK_TYPE_INTEGER, 2, PACK_FLAG_SIGNED};
330
+ case 'u': return (format_info_t){PACK_DIR_UU, PACK_TYPE_STRING, 0, PACK_FLAG_WIDTH | PACK_FLAG_COUNT2};
331
+ case 'U': return (format_info_t){PACK_DIR_UTF8, PACK_TYPE_INTEGER, 0, 0};
332
+ case 'V': return (format_info_t){PACK_DIR_LONG, PACK_TYPE_INTEGER, 4, PACK_FLAG_LT};
333
+ case 'v': return (format_info_t){PACK_DIR_SHORT, PACK_TYPE_INTEGER, 2, PACK_FLAG_LT};
334
+ case 'w': return (format_info_t){PACK_DIR_BER, PACK_TYPE_INTEGER, 0, PACK_FLAG_SIGNED};
335
+ case 'x': return (format_info_t){PACK_DIR_NUL, PACK_TYPE_NONE, 0, 0};
336
+ case 'X': return (format_info_t){PACK_DIR_BACK, PACK_TYPE_NONE, 0, 0};
337
+ case '@': return (format_info_t){PACK_DIR_ABS, PACK_TYPE_NONE, 0, 0};
338
+ case 'Z': return (format_info_t){PACK_DIR_STR, PACK_TYPE_STRING, 0, PACK_FLAG_WIDTH | PACK_FLAG_COUNT2 | PACK_FLAG_Z};
339
+ default: return (format_info_t){PACK_DIR_NONE, PACK_TYPE_NONE, 0, 0};
340
+ }
341
+ }
342
+
343
+
344
+ #define IS_PADDING_CHAR_A(c) (char_class((unsigned char)(c)) & (CHAR_NULL | CHAR_SPACE))
345
+ #define IS_PADDING_CHAR_Z(c) (char_class((unsigned char)(c)) & CHAR_NULL)
346
+
347
+ static int
348
+ hex2int(unsigned char ch)
349
+ {
350
+ return hex_lookup[ch];
351
+ }
352
+
353
+ static mrb_value
354
+ str_len_ensure(mrb_state *mrb, mrb_value str, mrb_int len)
355
+ {
356
+ mrb_int n = RSTRING_LEN(str);
357
+ if (len < 0) {
358
+ mrb_raise(mrb, E_RANGE_ERROR, "negative (or overflowed) integer");
359
+ }
360
+ if (len > n) {
361
+ do {
362
+ n *= 2;
363
+ } while (len > n);
364
+ str = mrb_str_resize(mrb, str, n);
365
+ }
366
+ return str;
367
+ }
368
+
369
+
370
+ static int
371
+ pack_char(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags)
372
+ {
373
+ str = str_len_ensure(mrb, str, sidx + 1);
374
+ RSTRING_PTR(str)[sidx] = (char)mrb_integer(o);
375
+ return 1;
376
+ }
377
+
378
+ static int
379
+ unpack_char(mrb_state *mrb, const void *src, mrb_int srclen, mrb_value ary, unsigned int flags)
380
+ {
381
+ if (flags & PACK_FLAG_SIGNED)
382
+ mrb_ary_push(mrb, ary, mrb_fixnum_value(*(signed char*)src));
383
+ else
384
+ mrb_ary_push(mrb, ary, mrb_fixnum_value(*(unsigned char*)src));
385
+ return 1;
386
+ }
387
+
388
+ static int
389
+ pack_short(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags)
390
+ {
391
+ str = str_len_ensure(mrb, str, sidx + 2);
392
+ uint16_t n = (uint16_t)mrb_integer(o);
393
+ char *dptr = RSTRING_PTR(str) + sidx;
394
+
395
+ /* use lookup tables to eliminate branching */
396
+ const int *idx = (flags & PACK_FLAG_LITTLEENDIAN) ? le_idx16 : be_idx16;
397
+ dptr[idx[0]] = (char)(n & 0xff);
398
+ dptr[idx[1]] = (char)(n >> 8);
399
+
400
+ return 2;
401
+ }
402
+
403
+ static int
404
+ unpack_short(mrb_state *mrb, const unsigned char *src, mrb_int srclen, mrb_value ary, unsigned int flags)
405
+ {
406
+ /* use lookup tables to eliminate branching */
407
+ const int *idx = (flags & PACK_FLAG_LITTLEENDIAN) ? le_idx16 : be_idx16;
408
+ int n = (src[idx[1]] << 8) | src[idx[0]];
409
+
410
+ if ((flags & PACK_FLAG_SIGNED) && (n >= 0x8000)) {
411
+ n -= 0x10000;
412
+ }
413
+ mrb_ary_push(mrb, ary, mrb_fixnum_value(n));
414
+ return 2;
415
+ }
416
+
417
+ static int
418
+ pack_long(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags)
419
+ {
420
+ str = str_len_ensure(mrb, str, sidx + 4);
421
+ uint32_t n = (uint32_t)mrb_integer(o);
422
+ char *dptr = RSTRING_PTR(str) + sidx;
423
+
424
+ /* use lookup tables to eliminate branching */
425
+ const int *idx = (flags & PACK_FLAG_LITTLEENDIAN) ? le_idx32 : be_idx32;
426
+ dptr[idx[0]] = (char)(n & 0xff);
427
+ dptr[idx[1]] = (char)(n >> 8);
428
+ dptr[idx[2]] = (char)(n >> 16);
429
+ dptr[idx[3]] = (char)(n >> 24);
430
+
431
+ return 4;
432
+ }
433
+
434
+ #ifndef MRB_INT64
435
+ static void
436
+ u32tostr(char *buf, size_t len, uint32_t n)
437
+ {
438
+ #ifdef MRB_NO_STDIO
439
+ char *bufend = buf + len;
440
+ char *p = bufend - 1;
441
+
442
+ if (len < 1) {
443
+ return;
444
+ }
445
+
446
+ *p-- = '\0';
447
+ len--;
448
+
449
+ if (n > 0) {
450
+ for (; len > 0 && n > 0; len --, n /= 10) {
451
+ *p -- = '0' + (n % 10);
452
+ }
453
+ p++;
454
+ }
455
+ else if (len > 0) {
456
+ *p = '0';
457
+ len--;
458
+ }
459
+
460
+ memmove(buf, p, bufend - p);
461
+ #else
462
+ snprintf(buf, len, "%" PRIu32, n);
463
+ #endif /* MRB_NO_STDIO */
464
+ }
465
+ #endif /* MRB_INT64 */
466
+
467
+ static int
468
+ unpack_long(mrb_state *mrb, const unsigned char *src, mrb_int srclen, mrb_value ary, unsigned int flags)
469
+ {
470
+ #ifndef MRB_INT64
471
+ char msg[60];
472
+ #endif
473
+ uint32_t ul;
474
+ mrb_int n;
475
+
476
+ /* use lookup tables to eliminate branching */
477
+ const int *idx = (flags & PACK_FLAG_LITTLEENDIAN) ? le_idx32 : be_idx32;
478
+ ul = ((uint32_t)src[idx[3]] << 24) |
479
+ ((uint32_t)src[idx[2]] << 16) |
480
+ ((uint32_t)src[idx[1]] << 8) |
481
+ (uint32_t)src[idx[0]];
482
+
483
+ if (flags & PACK_FLAG_SIGNED) {
484
+ n = (int32_t)ul;
485
+ }
486
+ else {
487
+ #ifndef MRB_INT64
488
+ if (UINT_OVERFLOW_P(ul)) {
489
+ u32tostr(msg, sizeof(msg), ul);
490
+ mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg);
491
+ }
492
+ #endif
493
+ n = ul;
494
+ }
495
+ mrb_ary_push(mrb, ary, mrb_int_value(mrb, n));
496
+ return 4;
497
+ }
498
+
499
+ static int
500
+ pack_quad(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags)
501
+ {
502
+ str = str_len_ensure(mrb, str, sidx + 8);
503
+ uint64_t n = (uint64_t)mrb_integer(o);
504
+ char *dptr = RSTRING_PTR(str) + sidx;
505
+
506
+ /* use lookup tables to eliminate branching */
507
+ const int *idx = (flags & PACK_FLAG_LITTLEENDIAN) ? le_idx64 : be_idx64;
508
+ dptr[idx[0]] = (char)(n & 0xff);
509
+ dptr[idx[1]] = (char)(n >> 8);
510
+ dptr[idx[2]] = (char)(n >> 16);
511
+ dptr[idx[3]] = (char)(n >> 24);
512
+ dptr[idx[4]] = (char)(n >> 32);
513
+ dptr[idx[5]] = (char)(n >> 40);
514
+ dptr[idx[6]] = (char)(n >> 48);
515
+ dptr[idx[7]] = (char)(n >> 56);
516
+
517
+ return 8;
518
+ }
519
+
520
+ static void
521
+ u64tostr(char *buf, size_t len, uint64_t n)
522
+ {
523
+ #ifdef MRB_NO_STDIO
524
+ mrb_assert(len > 0);
525
+
526
+ if (n < 10) {
527
+ buf[0] = '0' + n;
528
+ buf[1] = '\0';
529
+ return;
530
+ }
531
+
532
+ char *bufend = buf + len;
533
+ char *p = bufend - 1;
534
+
535
+ *p-- = '\0';
536
+ len--;
537
+
538
+ for (; len > 0 && n > 0; len--, n /= 10) {
539
+ *p-- = '0' + (n % 10);
540
+ }
541
+ p++;
542
+ memmove(buf, p, bufend - p);
543
+ #else
544
+ snprintf(buf, len, "%" PRIu64, n);
545
+ #endif /* MRB_NO_STDIO */
546
+ }
547
+
548
+ #ifndef MRB_INT64
549
+ static void
550
+ i64tostr(char *buf, size_t len, int64_t n)
551
+ {
552
+ #ifdef MRB_NO_STDIO
553
+ mrb_assert(len > 0);
554
+
555
+ if (n < 0) {
556
+ *buf++ = '-';
557
+ len--;
558
+ n = -n;
559
+ }
560
+
561
+ u64tostr(buf, len, (uint64_t)n);
562
+ #else
563
+ snprintf(buf, len, "%" PRId64, n);
564
+ #endif /* MRB_NO_STDIO */
565
+ }
566
+ #endif /* MRB_INT64 */
567
+
568
+ static int
569
+ unpack_quad(mrb_state *mrb, const unsigned char *src, mrb_int srclen, mrb_value ary, unsigned int flags)
570
+ {
571
+ char msg[60];
572
+ mrb_int n;
573
+
574
+ /* use lookup tables to eliminate branching */
575
+ const int *idx = (flags & PACK_FLAG_LITTLEENDIAN) ? le_idx64 : be_idx64;
576
+ uint64_t ull = ((uint64_t)src[idx[7]] << 56) |
577
+ ((uint64_t)src[idx[6]] << 48) |
578
+ ((uint64_t)src[idx[5]] << 40) |
579
+ ((uint64_t)src[idx[4]] << 32) |
580
+ ((uint64_t)src[idx[3]] << 24) |
581
+ ((uint64_t)src[idx[2]] << 16) |
582
+ ((uint64_t)src[idx[1]] << 8) |
583
+ (uint64_t)src[idx[0]];
584
+
585
+ if (flags & PACK_FLAG_SIGNED) {
586
+ int64_t sll = ull;
587
+ #ifndef MRB_INT64
588
+ if (INT_OVERFLOW_P(sll)) {
589
+ i64tostr(msg, sizeof(msg), sll);
590
+ mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg);
591
+ }
592
+ #endif
593
+ n = (mrb_int)sll;
594
+ }
595
+ else {
596
+ if (UINT_OVERFLOW_P(ull)) {
597
+ u64tostr(msg, sizeof(msg), ull);
598
+ mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg);
599
+ }
600
+ n = (mrb_int)ull;
601
+ }
602
+ mrb_ary_push(mrb, ary, mrb_int_value(mrb, n));
603
+ return 8;
604
+ }
605
+
606
+ static int
607
+ pack_BER(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags)
608
+ {
609
+ mrb_int n = mrb_integer(o);
610
+
611
+ if (n < 0) {
612
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "can't compress negative numbers");
613
+ }
614
+
615
+ /* fast path for 1-byte values (0-127) */
616
+ if (n < 128) {
617
+ str = str_len_ensure(mrb, str, sidx + 1);
618
+ RSTRING_PTR(str)[sidx] = (char)n;
619
+ return 1;
620
+ }
621
+
622
+ /* fast path for 2-byte values (128-16383) */
623
+ if (n < 16384) {
624
+ str = str_len_ensure(mrb, str, sidx + 2);
625
+ char *p = RSTRING_PTR(str) + sidx;
626
+ *p++ = (char)((n >> 7) | 0x80);
627
+ *p = (char)(n & 0x7f);
628
+ return 2;
629
+ }
630
+
631
+ /* original algorithm for larger values */
632
+ int i;
633
+ for (i = 1; i < (int)sizeof(mrb_int) + 1; i++) {
634
+ mrb_int mask = ~((1L << (7 * i)) - 1);
635
+ if ((n & mask) == 0) break;
636
+ }
637
+
638
+ str = str_len_ensure(mrb, str, sidx + i);
639
+ char *p = RSTRING_PTR(str) + sidx;
640
+
641
+ for (size_t j = i; j > 0; p++, j--) {
642
+ mrb_int x = (n >> (7 * (j - 1))) & 0x7f;
643
+ *p = (char)x;
644
+ if (j > 1) *p |= 0x80;
645
+ }
646
+
647
+ return i;
648
+ }
649
+
650
+ static int
651
+ unpack_BER(mrb_state *mrb, const unsigned char *src, mrb_int srclen, mrb_value ary, unsigned int flags)
652
+ {
653
+ mrb_int n = 0;
654
+ const unsigned char *p = src;
655
+ const unsigned char *e = p + srclen;
656
+
657
+ if (srclen == 0) return 0;
658
+
659
+ /* calculate maximum safe bytes before potential overflow */
660
+ const int max_safe_bytes = (sizeof(mrb_int) * 8 - 1) / 7; /* conservative estimate */
661
+
662
+ int i;
663
+ for (i = 1; p < e; p++, i++) {
664
+ /* check overflow before we might exceed safe limits */
665
+ if (i > max_safe_bytes || n > (MRB_INT_MAX >> 7)) {
666
+ mrb_raise(mrb, E_RANGE_ERROR, "BER unpacking 'w' overflow");
667
+ }
668
+
669
+ n <<= 7;
670
+ n |= *p & 0x7f;
671
+ if ((*p & 0x80) == 0) break;
672
+ }
673
+
674
+ mrb_ary_push(mrb, ary, mrb_int_value(mrb, n));
675
+ return i;
676
+ }
677
+
678
+ #ifndef MRB_NO_FLOAT
679
+ static int
680
+ pack_double(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags)
681
+ {
682
+ union {
683
+ double d;
684
+ uint64_t u;
685
+ } converter;
686
+
687
+ str = str_len_ensure(mrb, str, sidx + 8);
688
+ converter.d = mrb_float(o);
689
+ char *dptr = RSTRING_PTR(str) + sidx;
690
+
691
+ /* Use bit shifts for endian-independent byte extraction (same as pack_quad) */
692
+ uint64_t n = converter.u;
693
+ const int *idx = (flags & PACK_FLAG_LITTLEENDIAN) ? le_idx64 : be_idx64;
694
+ dptr[idx[0]] = (char)(n & 0xff);
695
+ dptr[idx[1]] = (char)((n >> 8) & 0xff);
696
+ dptr[idx[2]] = (char)((n >> 16) & 0xff);
697
+ dptr[idx[3]] = (char)((n >> 24) & 0xff);
698
+ dptr[idx[4]] = (char)((n >> 32) & 0xff);
699
+ dptr[idx[5]] = (char)((n >> 40) & 0xff);
700
+ dptr[idx[6]] = (char)((n >> 48) & 0xff);
701
+ dptr[idx[7]] = (char)((n >> 56) & 0xff);
702
+
703
+ return 8;
704
+ }
705
+
706
+ static int
707
+ unpack_double(mrb_state *mrb, const unsigned char * src, mrb_int srclen, mrb_value ary, unsigned int flags)
708
+ {
709
+ union {
710
+ double d;
711
+ uint64_t u;
712
+ } converter;
713
+
714
+ /* Use bit shifts for endian-independent byte assembly (same as unpack_quad) */
715
+ const int *idx = (flags & PACK_FLAG_LITTLEENDIAN) ? le_idx64 : be_idx64;
716
+ converter.u = ((uint64_t)src[idx[7]] << 56) |
717
+ ((uint64_t)src[idx[6]] << 48) |
718
+ ((uint64_t)src[idx[5]] << 40) |
719
+ ((uint64_t)src[idx[4]] << 32) |
720
+ ((uint64_t)src[idx[3]] << 24) |
721
+ ((uint64_t)src[idx[2]] << 16) |
722
+ ((uint64_t)src[idx[1]] << 8) |
723
+ ((uint64_t)src[idx[0]]);
724
+
725
+ mrb_ary_push(mrb, ary, mrb_float_value(mrb, converter.d));
726
+
727
+ return 8;
728
+ }
729
+
730
+ static int
731
+ pack_float(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags)
732
+ {
733
+ union {
734
+ float f;
735
+ uint32_t u;
736
+ } converter;
737
+
738
+ str = str_len_ensure(mrb, str, sidx + 4);
739
+ converter.f = (float)mrb_float(o);
740
+ char *dptr = RSTRING_PTR(str) + sidx;
741
+
742
+ /* Use bit shifts for endian-independent byte extraction (same as pack_long) */
743
+ uint32_t n = converter.u;
744
+ const int *idx = (flags & PACK_FLAG_LITTLEENDIAN) ? le_idx32 : be_idx32;
745
+ dptr[idx[0]] = (char)(n & 0xff);
746
+ dptr[idx[1]] = (char)((n >> 8) & 0xff);
747
+ dptr[idx[2]] = (char)((n >> 16) & 0xff);
748
+ dptr[idx[3]] = (char)((n >> 24) & 0xff);
749
+
750
+ return 4;
751
+ }
752
+
753
+ static int
754
+ unpack_float(mrb_state *mrb, const unsigned char * src, mrb_int srclen, mrb_value ary, unsigned int flags)
755
+ {
756
+ union {
757
+ float f;
758
+ uint32_t u;
759
+ } converter;
760
+
761
+ /* Use bit shifts for endian-independent byte assembly (same as unpack_long) */
762
+ const int *idx = (flags & PACK_FLAG_LITTLEENDIAN) ? le_idx32 : be_idx32;
763
+ converter.u = ((uint32_t)src[idx[3]] << 24) |
764
+ ((uint32_t)src[idx[2]] << 16) |
765
+ ((uint32_t)src[idx[1]] << 8) |
766
+ ((uint32_t)src[idx[0]]);
767
+
768
+ mrb_ary_push(mrb, ary, mrb_float_value(mrb, converter.f));
769
+
770
+ return 4;
771
+ }
772
+ #endif
773
+
774
+ static int
775
+ pack_utf8(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, int count, unsigned int flags)
776
+ {
777
+ char utf8[4];
778
+ int len;
779
+ uint32_t c = (uint32_t)mrb_integer(o);
780
+
781
+ len = (int)mrb_utf8_to_buf(utf8, c);
782
+ if (len == 0) {
783
+ mrb_raise(mrb, E_RANGE_ERROR, "pack(U): value out of range");
784
+ }
785
+
786
+ str = str_len_ensure(mrb, str, sidx + len);
787
+ memcpy(RSTRING_PTR(str) + sidx, utf8, len);
788
+
789
+ return len;
790
+ }
791
+
792
+
793
+
794
+ static int
795
+ unpack_utf8(mrb_state *mrb, const unsigned char * src, mrb_int srclen, mrb_value ary, unsigned int flags)
796
+ {
797
+ if (srclen == 0) {
798
+ return 1;
799
+ }
800
+
801
+ const unsigned char *p = src;
802
+ uint8_t first_byte = *p;
803
+
804
+ /* ASCII fast path - most common case */
805
+ if (first_byte < 0x80) {
806
+ mrb_ary_push(mrb, ary, mrb_fixnum_value(first_byte));
807
+ return 1;
808
+ }
809
+
810
+ /* Multi-byte UTF-8 with optimized lookup table */
811
+ uint8_t seq_len = utf8_seq_len_high[first_byte - 0x80];
812
+ if (seq_len == 0 || seq_len > srclen) {
813
+ goto malformed;
814
+ }
815
+
816
+ /* Inline 2-byte sequence optimization - common case */
817
+ if (seq_len == 2) {
818
+ if (!IS_UTF8_CONTINUATION(p[1])) {
819
+ goto malformed;
820
+ }
821
+ uint32_t uv = ((first_byte & 0x1F) << 6) | (p[1] & 0x3F);
822
+ /* validate minimum value for 2-byte sequence */
823
+ if (uv >= 0x80) {
824
+ mrb_ary_push(mrb, ary, mrb_fixnum_value((mrb_int)uv));
825
+ return 2;
826
+ }
827
+ goto redundant;
828
+ }
829
+
830
+ /* Inline 3-byte sequence optimization */
831
+ if (seq_len == 3) {
832
+ if (!IS_UTF8_CONTINUATION(p[1]) || !IS_UTF8_CONTINUATION(p[2])) {
833
+ goto malformed;
834
+ }
835
+ uint32_t uv = ((first_byte & 0x0F) << 12) |
836
+ ((p[1] & 0x3F) << 6) |
837
+ (p[2] & 0x3F);
838
+ /* validate minimum value for 3-byte sequence */
839
+ if (uv >= 0x800) {
840
+ mrb_ary_push(mrb, ary, mrb_fixnum_value((mrb_int)uv));
841
+ return 3;
842
+ }
843
+ goto redundant;
844
+ }
845
+
846
+ /* 4-byte sequence - less common, use original implementation */
847
+ if (seq_len == 4) {
848
+ if (!IS_UTF8_CONTINUATION(p[1]) || !IS_UTF8_CONTINUATION(p[2]) || !IS_UTF8_CONTINUATION(p[3])) {
849
+ goto malformed;
850
+ }
851
+ uint32_t uv = ((first_byte & 0x07) << 18) |
852
+ ((p[1] & 0x3F) << 12) |
853
+ ((p[2] & 0x3F) << 6) |
854
+ (p[3] & 0x3F);
855
+ /* validate minimum value and maximum valid Unicode */
856
+ if (uv >= 0x10000 && uv <= 0x10FFFF) {
857
+ mrb_ary_push(mrb, ary, mrb_fixnum_value((mrb_int)uv));
858
+ return 4;
859
+ }
860
+ if (uv < 0x10000) goto redundant;
861
+ goto malformed;
862
+ }
863
+
864
+ malformed:
865
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character");
866
+
867
+ redundant:
868
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "redundant UTF-8 sequence");
869
+ }
870
+
871
+ static int
872
+ pack_str(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, unsigned int flags)
873
+ {
874
+ const char *sptr = RSTRING_PTR(src);
875
+ mrb_int slen = RSTRING_LEN(src);
876
+ mrb_int copylen, padlen;
877
+ char pad;
878
+
879
+ /* determine padding character based on format */
880
+ if ((flags & PACK_FLAG_a) || (flags & PACK_FLAG_Z))
881
+ pad = '\0';
882
+ else
883
+ pad = ' ';
884
+
885
+ if (count == 0) {
886
+ return 0;
887
+ }
888
+ else if (count == -1) {
889
+ copylen = slen;
890
+ padlen = (flags & PACK_FLAG_Z) ? 1 : 0;
891
+ }
892
+ else if (count < slen) {
893
+ copylen = count;
894
+ padlen = 0;
895
+ }
896
+ else {
897
+ copylen = slen;
898
+ padlen = count - slen;
899
+ }
900
+
901
+ /* pre-allocate exact buffer size */
902
+ dst = str_len_ensure(mrb, dst, didx + copylen + padlen);
903
+ char *dptr = RSTRING_PTR(dst) + didx;
904
+ char *dptr0 = dptr;
905
+
906
+ /* copy string data */
907
+ if (copylen > 0) {
908
+ memcpy(dptr, sptr, copylen);
909
+ dptr += copylen;
910
+ }
911
+
912
+ /* bulk padding using memset instead of loop */
913
+ if (padlen > 0) {
914
+ memset(dptr, pad, padlen);
915
+ dptr += padlen;
916
+ }
917
+
918
+ return (int)(dptr - dptr0);
919
+ }
920
+
921
+ #define CHECK_UNPACK_LEN(mrb, slen, ary) do {\
922
+ if ((slen) <= 0) {\
923
+ mrb_ary_push(mrb, ary, mrb_str_new(mrb, 0, 0));\
924
+ return 0;\
925
+ }\
926
+ } while (0)
927
+
928
+ static int
929
+ unpack_str(mrb_state *mrb, const void *src, mrb_int slen, mrb_value ary, int count, unsigned int flags)
930
+ {
931
+ CHECK_UNPACK_LEN(mrb, slen, ary);
932
+
933
+ const char *sptr = (const char*)src;
934
+ int copylen;
935
+
936
+ if (count != -1 && count < slen) {
937
+ slen = count;
938
+ }
939
+ copylen = (int)slen;
940
+
941
+ if (slen >= 0 && flags & PACK_FLAG_Z) { /* "Z" format */
942
+ const char *cp = (const char*)memchr(sptr, '\0', slen);
943
+ if (cp != NULL) {
944
+ copylen = (int)(cp - sptr);
945
+ if (count == -1) {
946
+ slen = copylen + 1;
947
+ }
948
+ }
949
+ }
950
+ else if (!(flags & PACK_FLAG_a)) { /* "A" format - trim spaces and nulls */
951
+ /* optimized reverse trimming using lookup table */
952
+ while (copylen > 0 && IS_PADDING_CHAR_A(sptr[copylen - 1])) {
953
+ copylen--;
954
+ }
955
+ }
956
+ /* "a" format does no trimming */
957
+
958
+ if (copylen < 0) copylen = 0;
959
+
960
+ mrb_value dst = mrb_str_new(mrb, sptr, (mrb_int)copylen);
961
+ mrb_ary_push(mrb, ary, dst);
962
+ return (int)slen;
963
+ }
964
+
965
+
966
+ static int
967
+ pack_hex(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, unsigned int flags)
968
+ {
969
+ char *sptr = RSTRING_PTR(src);
970
+ long slen = (long)RSTRING_LEN(src);
971
+
972
+ unsigned int ashift, bshift;
973
+ if (flags & PACK_FLAG_LSB) {
974
+ ashift = 0;
975
+ bshift = 4;
976
+ }
977
+ else {
978
+ ashift = 4;
979
+ bshift = 0;
980
+ }
981
+
982
+ if (count == -1) {
983
+ count = slen;
984
+ }
985
+ else if (slen > count) {
986
+ slen = count;
987
+ }
988
+
989
+ /* calculate output buffer size needed - one byte per two hex chars */
990
+ /* use count/2 + (count&1) to avoid overflow when count == INT_MAX */
991
+ int output_bytes = count / 2 + (count & 1);
992
+ dst = str_len_ensure(mrb, dst, didx + output_bytes);
993
+ char *dptr = RSTRING_PTR(dst) + didx;
994
+ char *dptr0 = dptr;
995
+
996
+ /* process pairs of hex characters */
997
+ while (slen >= 2) {
998
+ int a = hex2int((unsigned char)*sptr++);
999
+ if (a < 0) break;
1000
+ int b = hex2int((unsigned char)*sptr++);
1001
+ if (b < 0) break;
1002
+
1003
+ *dptr++ = (a << ashift) + (b << bshift);
1004
+ slen -= 2;
1005
+ }
1006
+
1007
+ /* handle odd remaining character */
1008
+ if (slen > 0) {
1009
+ int a = hex2int((unsigned char)*sptr);
1010
+ if (a >= 0) {
1011
+ *dptr++ = (a << ashift);
1012
+ }
1013
+ }
1014
+
1015
+ return (int)(dptr - dptr0);
1016
+ }
1017
+
1018
+ static int
1019
+ unpack_hex(mrb_state *mrb, const void *src, mrb_int slen, mrb_value ary, int count, unsigned int flags)
1020
+ {
1021
+ CHECK_UNPACK_LEN(mrb, slen, ary);
1022
+
1023
+ int ashift, bshift;
1024
+ if (flags & PACK_FLAG_LSB) {
1025
+ ashift = 0;
1026
+ bshift = 4;
1027
+ }
1028
+ else {
1029
+ ashift = 4;
1030
+ bshift = 0;
1031
+ }
1032
+
1033
+ const char *sptr = (const char*)src;
1034
+ const char *sptr0 = sptr;
1035
+
1036
+ if (count == -1)
1037
+ count = (int)(slen * 2);
1038
+
1039
+ mrb_value dst = mrb_str_new(mrb, NULL, count);
1040
+ char *dptr = RSTRING_PTR(dst);
1041
+ char *dptr0 = dptr;
1042
+
1043
+ const char hexadecimal[] = "0123456789abcdef";
1044
+
1045
+ /* process full bytes when we need pairs of hex characters */
1046
+ while (slen > 0 && count >= 2) {
1047
+ unsigned char byte = *sptr++;
1048
+ slen--;
1049
+
1050
+ *dptr++ = hexadecimal[(byte >> ashift) & 0x0f];
1051
+ *dptr++ = hexadecimal[(byte >> bshift) & 0x0f];
1052
+ count -= 2;
1053
+ }
1054
+
1055
+ /* handle remaining single character if count is odd */
1056
+ if (slen > 0 && count > 0) {
1057
+ unsigned char byte = *sptr++;
1058
+ *dptr++ = hexadecimal[(byte >> ashift) & 0x0f];
1059
+ }
1060
+
1061
+ dst = mrb_str_resize(mrb, dst, (mrb_int)(dptr - dptr0));
1062
+ mrb_ary_push(mrb, ary, dst);
1063
+ return (int)(sptr - sptr0);
1064
+ }
1065
+
1066
+ static int
1067
+ pack_bstr(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, unsigned int flags)
1068
+ {
1069
+ const char *sptr = RSTRING_PTR(src);
1070
+ int slen = (int)RSTRING_LEN(src);
1071
+
1072
+ if (count == -1) {
1073
+ count = slen;
1074
+ }
1075
+ else if (slen > count) {
1076
+ slen = count;
1077
+ }
1078
+
1079
+ /* calculate exact output size: (slen + 7) / 8 */
1080
+ int output_bytes = (slen + 7) / 8;
1081
+ dst = str_len_ensure(mrb, dst, didx + output_bytes);
1082
+ char *dptr = RSTRING_PTR(dst) + didx;
1083
+ char *dptr0 = dptr;
1084
+
1085
+ /* select batch processing function based on bit order */
1086
+ uint8_t (*pack_func)(const char *) = (flags & PACK_FLAG_LSB) ? pack_8_bits_lsb : pack_8_bits_msb;
1087
+
1088
+ /* process 8 characters at a time */
1089
+ int full_bytes = slen / 8;
1090
+ for (int i = 0; i < full_bytes; i++) {
1091
+ *dptr++ = (char)pack_func(sptr);
1092
+ sptr += 8;
1093
+ }
1094
+
1095
+ /* handle remaining bits (partial byte) */
1096
+ int remaining_bits = slen % 8;
1097
+ if (remaining_bits > 0) {
1098
+ char temp_chars[8] = {'0', '0', '0', '0', '0', '0', '0', '0'};
1099
+ /* copy remaining characters, padding with '0' */
1100
+ for (int i = 0; i < remaining_bits; i++) {
1101
+ temp_chars[i] = sptr[i];
1102
+ }
1103
+ *dptr++ = (char)pack_func(temp_chars);
1104
+ }
1105
+
1106
+ return (int)(dptr - dptr0);
1107
+ }
1108
+
1109
+ static int
1110
+ unpack_bstr(mrb_state *mrb, const void *src, mrb_int slen, mrb_value ary, int count, unsigned int flags)
1111
+ {
1112
+ CHECK_UNPACK_LEN(mrb, slen, ary);
1113
+
1114
+ const char *sptr0 = (const char*)src;
1115
+ const char *sptr = sptr0;
1116
+
1117
+ if (count == -1 || count > slen * 8)
1118
+ count = (int)(slen * 8);
1119
+
1120
+ /* pre-allocate exact output size */
1121
+ mrb_value dst = mrb_str_new(mrb, NULL, count);
1122
+ char *dptr = RSTRING_PTR(dst);
1123
+ char *dptr0 = dptr;
1124
+
1125
+ /* select batch processing function based on bit order */
1126
+ void (*unpack_func)(uint8_t, char *) = (flags & PACK_FLAG_LSB) ? unpack_8_bits_lsb : unpack_8_bits_msb;
1127
+
1128
+ /* process 8 bits (1 byte) at a time */
1129
+ int full_bytes = count / 8;
1130
+ for (int i = 0; i < full_bytes; i++) {
1131
+ unpack_func((uint8_t)*sptr++, dptr);
1132
+ dptr += 8;
1133
+ }
1134
+
1135
+ /* handle remaining bits (partial byte) */
1136
+ int remaining_bits = count % 8;
1137
+ if (remaining_bits > 0) {
1138
+ char temp_chars[8];
1139
+ unpack_func((uint8_t)*sptr++, temp_chars);
1140
+ /* copy only the required number of characters */
1141
+ for (int i = 0; i < remaining_bits; i++) {
1142
+ *dptr++ = temp_chars[i];
1143
+ }
1144
+ }
1145
+
1146
+ /* ensure string is properly sized */
1147
+ dst = mrb_str_resize(mrb, dst, (mrb_int)(dptr - dptr0));
1148
+ mrb_ary_push(mrb, ary, dst);
1149
+ return (int)(sptr - sptr0);
1150
+ }
1151
+
1152
+ static int
1153
+ pack_base64(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count)
1154
+ {
1155
+ char *srcptr = RSTRING_PTR(src);
1156
+ mrb_int srclen = RSTRING_LEN(src);
1157
+
1158
+ if (srclen == 0) {
1159
+ return 0;
1160
+ }
1161
+
1162
+ if (count != 0 && count < 3) {
1163
+ count = 45;
1164
+ }
1165
+ else if (count >= 3) {
1166
+ count -= count % 3;
1167
+ }
1168
+
1169
+ /* precise memory allocation */
1170
+ mrb_int dstlen = (srclen + 2) / 3 * 4;
1171
+ if (count > 0) {
1172
+ dstlen += (srclen / count) + ((srclen % count) == 0 ? 0 : 1);
1173
+ }
1174
+ dst = str_len_ensure(mrb, dst, didx + dstlen);
1175
+ char *dstptr = RSTRING_PTR(dst) + didx;
1176
+ char *dstptr0 = dstptr;
1177
+
1178
+ if (count == 0) {
1179
+ /* fast path: no line wrapping */
1180
+ while (srclen >= 3) {
1181
+ unsigned long l = (unsigned char)*srcptr++ << 16;
1182
+ l += (unsigned char)*srcptr++ << 8;
1183
+ l += (unsigned char)*srcptr++;
1184
+ srclen -= 3;
1185
+
1186
+ *dstptr++ = base64chars[(l >> 18) & 0x3f];
1187
+ *dstptr++ = base64chars[(l >> 12) & 0x3f];
1188
+ *dstptr++ = base64chars[(l >> 6) & 0x3f];
1189
+ *dstptr++ = base64chars[l & 0x3f];
1190
+ }
1191
+ }
1192
+ else {
1193
+ /* line wrapping path */
1194
+ mrb_int column = 3;
1195
+ while (srclen >= 3) {
1196
+ unsigned long l = (unsigned char)*srcptr++ << 16;
1197
+ l += (unsigned char)*srcptr++ << 8;
1198
+ l += (unsigned char)*srcptr++;
1199
+ srclen -= 3;
1200
+
1201
+ *dstptr++ = base64chars[(l >> 18) & 0x3f];
1202
+ *dstptr++ = base64chars[(l >> 12) & 0x3f];
1203
+ *dstptr++ = base64chars[(l >> 6) & 0x3f];
1204
+ *dstptr++ = base64chars[l & 0x3f];
1205
+
1206
+ if (column == count) {
1207
+ *dstptr++ = '\n';
1208
+ column = 0;
1209
+ }
1210
+ column += 3;
1211
+ }
1212
+
1213
+ /* handle remaining 1-2 bytes */
1214
+ if (srclen == 1) {
1215
+ unsigned long l = (unsigned char)*srcptr << 16;
1216
+ *dstptr++ = base64chars[(l >> 18) & 0x3f];
1217
+ *dstptr++ = base64chars[(l >> 12) & 0x3f];
1218
+ *dstptr++ = '=';
1219
+ *dstptr++ = '=';
1220
+ column += 3;
1221
+ }
1222
+ else if (srclen == 2) {
1223
+ unsigned long l = (unsigned char)*srcptr++ << 16;
1224
+ l += (unsigned char)*srcptr << 8;
1225
+ *dstptr++ = base64chars[(l >> 18) & 0x3f];
1226
+ *dstptr++ = base64chars[(l >> 12) & 0x3f];
1227
+ *dstptr++ = base64chars[(l >> 6) & 0x3f];
1228
+ *dstptr++ = '=';
1229
+ column += 3;
1230
+ }
1231
+
1232
+ if (column > 0) {
1233
+ *dstptr++ = '\n';
1234
+ }
1235
+ return (int)(dstptr - dstptr0);
1236
+ }
1237
+
1238
+ /* handle remaining 1-2 bytes for fast path */
1239
+ if (srclen == 1) {
1240
+ unsigned long l = (unsigned char)*srcptr << 16;
1241
+ *dstptr++ = base64chars[(l >> 18) & 0x3f];
1242
+ *dstptr++ = base64chars[(l >> 12) & 0x3f];
1243
+ *dstptr++ = '=';
1244
+ *dstptr++ = '=';
1245
+ }
1246
+ else if (srclen == 2) {
1247
+ unsigned long l = (unsigned char)*srcptr++ << 16;
1248
+ l += (unsigned char)*srcptr << 8;
1249
+ *dstptr++ = base64chars[(l >> 18) & 0x3f];
1250
+ *dstptr++ = base64chars[(l >> 12) & 0x3f];
1251
+ *dstptr++ = base64chars[(l >> 6) & 0x3f];
1252
+ *dstptr++ = '=';
1253
+ }
1254
+
1255
+ return (int)(dstptr - dstptr0);
1256
+ }
1257
+
1258
+ static int
1259
+ unpack_base64(mrb_state *mrb, const void *src, mrb_int slen, mrb_value ary)
1260
+ {
1261
+ CHECK_UNPACK_LEN(mrb, slen, ary);
1262
+
1263
+ const char *sptr0 = (const char*)src;
1264
+ const char *sptr = sptr0;
1265
+
1266
+ /* estimate buffer size - may be shorter due to padding/whitespace */
1267
+ int dlen = (int)(slen / 4 * 3);
1268
+ mrb_value dst = mrb_str_new(mrb, NULL, dlen);
1269
+ char *dptr0 = RSTRING_PTR(dst);
1270
+ char *dptr = dptr0;
1271
+
1272
+ int padding = 0;
1273
+ while (slen >= 4) {
1274
+ unsigned char ch[4];
1275
+
1276
+ /* collect 4 valid base64 characters */
1277
+ for (int i = 0; i < 4; i++) {
1278
+ unsigned char c;
1279
+ do {
1280
+ if (slen-- == 0)
1281
+ goto done;
1282
+ c = *sptr++;
1283
+ if (c >= sizeof(base64_dec_tab))
1284
+ continue;
1285
+ ch[i] = base64_dec_tab[c];
1286
+ if (ch[i] == PACK_BASE64_PADDING) {
1287
+ ch[i] = 0;
1288
+ padding++;
1289
+ }
1290
+ } while (c >= sizeof(base64_dec_tab) || ch[i] == PACK_BASE64_IGNORE);
1291
+ }
1292
+
1293
+ /* decode 4 characters to 3 bytes */
1294
+ unsigned long l = (ch[0] << 18) + (ch[1] << 12) + (ch[2] << 6) + ch[3];
1295
+
1296
+ if (padding == 0) {
1297
+ *dptr++ = (l >> 16) & 0xff;
1298
+ *dptr++ = (l >> 8) & 0xff;
1299
+ *dptr++ = l & 0xff;
1300
+ }
1301
+ else if (padding == 1) {
1302
+ *dptr++ = (l >> 16) & 0xff;
1303
+ *dptr++ = (l >> 8) & 0xff;
1304
+ break;
1305
+ }
1306
+ else {
1307
+ *dptr++ = (l >> 16) & 0xff;
1308
+ break;
1309
+ }
1310
+ }
1311
+
1312
+ done:
1313
+ dst = mrb_str_resize(mrb, dst, (mrb_int)(dptr - dptr0));
1314
+ mrb_ary_push(mrb, ary, dst);
1315
+ return (int)(sptr - sptr0);
1316
+ }
1317
+
1318
+ static int
1319
+ pack_qenc(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count)
1320
+ {
1321
+ static const char hex_table[] = "0123456789ABCDEF";
1322
+ char buff[1024];
1323
+ char *s = RSTRING_PTR(src);
1324
+ char *send = s + RSTRING_LEN(src);
1325
+ int i = 0, n = 0, prev = EOF;
1326
+ int dlen = 0;
1327
+
1328
+ if (count <= 1) count = 72;
1329
+
1330
+ while (s < send) {
1331
+ unsigned char byte = (unsigned char)*s;
1332
+ uint8_t encode_type = qprint_encode_type[byte];
1333
+
1334
+ /* ASCII printable fast path - most common case */
1335
+ if (encode_type == 0) {
1336
+ /* Handle space/tab at line end special case */
1337
+ if ((byte == ' ' || byte == '\t') && s + 1 < send && *(s + 1) == '\n') {
1338
+ /* Space/tab before newline needs encoding */
1339
+ buff[i++] = '=';
1340
+ buff[i++] = hex_table[(byte & 0xf0) >> 4];
1341
+ buff[i++] = hex_table[byte & 0x0f];
1342
+ n += 3;
1343
+ prev = EOF;
1344
+ }
1345
+ else {
1346
+ /* Regular printable character - direct copy */
1347
+ buff[i++] = byte;
1348
+ n++;
1349
+ prev = byte;
1350
+ }
1351
+ }
1352
+ /* Newline special handling */
1353
+ else if (encode_type == 2) {
1354
+ if (prev == ' ' || prev == '\t') {
1355
+ buff[i++] = '=';
1356
+ buff[i++] = byte;
1357
+ }
1358
+ buff[i++] = byte;
1359
+ n = 0;
1360
+ prev = byte;
1361
+ }
1362
+ /* Character needs encoding */
1363
+ else {
1364
+ buff[i++] = '=';
1365
+ buff[i++] = hex_table[(byte & 0xf0) >> 4];
1366
+ buff[i++] = hex_table[byte & 0x0f];
1367
+ n += 3;
1368
+ prev = EOF;
1369
+ }
1370
+
1371
+ /* Check line length limit */
1372
+ if (n > count) {
1373
+ buff[i++] = '=';
1374
+ buff[i++] = '\n';
1375
+ n = 0;
1376
+ prev = '\n';
1377
+ }
1378
+
1379
+ /* Flush buffer if getting full */
1380
+ if (i > 1024 - 5) {
1381
+ str_len_ensure(mrb, dst, didx+dlen+i);
1382
+ memcpy(RSTRING_PTR(dst)+didx+dlen, buff, i);
1383
+ dlen += i;
1384
+ i = 0;
1385
+ }
1386
+ s++;
1387
+ }
1388
+
1389
+ /* Add final soft line break if needed */
1390
+ if (n > 0) {
1391
+ buff[i++] = '=';
1392
+ buff[i++] = '\n';
1393
+ }
1394
+
1395
+ /* Flush remaining buffer */
1396
+ if (i > 0) {
1397
+ str_len_ensure(mrb, dst, didx+dlen+i);
1398
+ memcpy(RSTRING_PTR(dst)+didx+dlen, buff, i);
1399
+ dlen += i;
1400
+ }
1401
+
1402
+ return dlen;
1403
+ }
1404
+
1405
+ static int
1406
+ unpack_qenc(mrb_state *mrb, const void *src, mrb_int slen, mrb_value ary)
1407
+ {
1408
+ CHECK_UNPACK_LEN(mrb, slen, ary);
1409
+
1410
+ mrb_value buf = mrb_str_new(mrb, 0, slen);
1411
+ const char *s = (const char*)src;
1412
+ const char *send = s + slen;
1413
+ char *ptr = RSTRING_PTR(buf);
1414
+ int c1, c2;
1415
+
1416
+ while (s < send) {
1417
+ /* Fast path for non-encoded characters - most common case */
1418
+ if (*s != '=') {
1419
+ *ptr++ = *s;
1420
+ s++;
1421
+ continue;
1422
+ }
1423
+
1424
+ /* Handle =XX encoded sequences */
1425
+ if (++s == send) break;
1426
+
1427
+ /* Handle soft line breaks: =\r\n or =\n */
1428
+ if (s + 1 < send && *s == '\r' && *(s + 1) == '\n') {
1429
+ s += 2; /* Skip \r\n */
1430
+ continue;
1431
+ }
1432
+ if (*s == '\n') {
1433
+ s++; /* Skip \n */
1434
+ continue;
1435
+ }
1436
+
1437
+ /* Decode =XX hex sequence */
1438
+ if ((c1 = hex2int(*s)) == -1) break;
1439
+ if (++s == send) break;
1440
+ if ((c2 = hex2int(*s)) == -1) break;
1441
+ *ptr++ = (char)(c1 << 4 | c2);
1442
+ s++;
1443
+ }
1444
+
1445
+ buf = mrb_str_resize(mrb, buf, (mrb_int)(ptr - RSTRING_PTR(buf)));
1446
+ mrb_ary_push(mrb, ary, buf);
1447
+ return (int)slen;
1448
+ }
1449
+
1450
+ static int
1451
+ pack_uu(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count)
1452
+ {
1453
+ char *s = RSTRING_PTR(src);
1454
+ int slen = (int)RSTRING_LEN(src);
1455
+ int lines_written = 0;
1456
+ int dlen = 0;
1457
+
1458
+ if (count <= 1) count = 45; /* default line length for UU-encoding */
1459
+
1460
+ /* Calculate buffer size by accounting for per-line encoding
1461
+ * Each line encodes separately, so padding happens per line, not globally
1462
+ */
1463
+ mrb_int num_lines = (slen + count - 1) / count; /* Number of lines */
1464
+ mrb_int total_encoded = 0;
1465
+ mrb_int temp_slen = slen;
1466
+
1467
+ /* Calculate actual encoded size line by line */
1468
+ while (temp_slen > 0) {
1469
+ mrb_int line_len = (temp_slen > count) ? count : temp_slen;
1470
+ total_encoded += ((line_len + 2) / 3) * 4; /* Each line's encoded size */
1471
+ temp_slen -= line_len;
1472
+ }
1473
+
1474
+ /* Total buffer = encoded data + (length char + newline) per line + terminating line */
1475
+ mrb_int buffer_size = total_encoded + num_lines * 2 + 2;
1476
+ str_len_ensure(mrb, dst, didx + buffer_size);
1477
+ char *dptr = RSTRING_PTR(dst) + didx;
1478
+
1479
+ while (slen > 0) {
1480
+ int line_len = (slen > count) ? count : slen;
1481
+
1482
+ /* Write line length character */
1483
+ *dptr++ = uu_encode_table[line_len & 0x3F];
1484
+ dlen++;
1485
+
1486
+ int processed = 0;
1487
+ while (processed < line_len) {
1488
+ /* Process groups of 3 bytes -> 4 characters */
1489
+ uint32_t group = 0;
1490
+ int bytes_in_group = 0;
1491
+
1492
+ /* Read up to 3 bytes */
1493
+ for (int i = 0; i < 3 && processed < line_len; i++) {
1494
+ group = (group << 8) | (unsigned char)s[processed++];
1495
+ bytes_in_group++;
1496
+ }
1497
+
1498
+ /* Pad incomplete group with zeros */
1499
+ group <<= (3 - bytes_in_group) * 8;
1500
+
1501
+ /* Extract 4 groups of 6 bits and encode */
1502
+ *dptr++ = uu_encode_table[(group >> 18) & 0x3F];
1503
+ *dptr++ = uu_encode_table[(group >> 12) & 0x3F];
1504
+ *dptr++ = uu_encode_table[(group >> 6) & 0x3F];
1505
+ *dptr++ = uu_encode_table[group & 0x3F];
1506
+ dlen += 4;
1507
+ }
1508
+
1509
+ /* Add newline */
1510
+ *dptr++ = '\n';
1511
+ dlen++;
1512
+
1513
+ s += line_len;
1514
+ slen -= line_len;
1515
+ lines_written++;
1516
+ }
1517
+
1518
+ /* Add terminating line if data was processed */
1519
+ if (lines_written > 0) {
1520
+ *dptr++ = uu_encode_table[0]; /* length 0 */
1521
+ *dptr++ = '\n';
1522
+ dlen += 2;
1523
+ }
1524
+
1525
+ return dlen;
1526
+ }
1527
+
1528
+ static int
1529
+ unpack_uu(mrb_state *mrb, const void *src, mrb_int slen, mrb_value ary)
1530
+ {
1531
+ const unsigned char *s = (const unsigned char*)src;
1532
+ const unsigned char *send = s + slen;
1533
+ mrb_value result = mrb_str_new(mrb, 0, slen * 3 / 4); /* estimate result size */
1534
+ char *dptr = RSTRING_PTR(result);
1535
+ char *dptr_start = dptr;
1536
+
1537
+ while (s < send) {
1538
+ /* Skip empty lines and whitespace */
1539
+ while (s < send && (*s == '\n' || *s == '\r' || *s == ' ' || *s == '\t')) {
1540
+ s++;
1541
+ }
1542
+ if (s >= send) break;
1543
+
1544
+ /* Read line length */
1545
+ int line_len = 0;
1546
+ if (*s >= 32 && *s < 128 && uu_decode_table[*s - 32] >= 0) {
1547
+ line_len = uu_decode_table[*s - 32];
1548
+ s++;
1549
+ }
1550
+ else {
1551
+ break; /* Invalid length character */
1552
+ }
1553
+
1554
+ /* Empty line indicates end */
1555
+ if (line_len == 0) {
1556
+ break;
1557
+ }
1558
+
1559
+ /* Decode line data */
1560
+ int bytes_decoded = 0;
1561
+ while (bytes_decoded < line_len && s + 3 < send) {
1562
+ /* Decode 4 characters to 3 bytes */
1563
+ int c[4];
1564
+ int valid = 1;
1565
+
1566
+ for (int i = 0; i < 4; i++) {
1567
+ if (s >= send || *s < 32 || *s >= 128 || uu_decode_table[*s - 32] < 0) {
1568
+ valid = 0;
1569
+ break;
1570
+ }
1571
+ c[i] = uu_decode_table[*s++ - 32];
1572
+ }
1573
+
1574
+ if (!valid) break;
1575
+
1576
+ /* Combine 4 x 6-bit values into 3 x 8-bit values */
1577
+ uint32_t group = (c[0] << 18) | (c[1] << 12) | (c[2] << 6) | c[3];
1578
+
1579
+ /* Extract up to 3 bytes, don't exceed line length */
1580
+ int bytes_to_extract = (line_len - bytes_decoded > 3) ? 3 : (line_len - bytes_decoded);
1581
+
1582
+ for (int i = 0; i < bytes_to_extract; i++) {
1583
+ *dptr++ = (group >> (16 - i * 8)) & 0xFF;
1584
+ bytes_decoded++;
1585
+ }
1586
+ }
1587
+
1588
+ /* Skip to end of line */
1589
+ while (s < send && *s != '\n' && *s != '\r') {
1590
+ s++;
1591
+ }
1592
+ }
1593
+
1594
+ result = mrb_str_resize(mrb, result, (mrb_int)(dptr - dptr_start));
1595
+ mrb_ary_push(mrb, ary, result);
1596
+ return (int)slen;
1597
+ }
1598
+
1599
+ static int
1600
+ pack_nul(mrb_state *mrb, mrb_value dst, mrb_int didx, int count)
1601
+ {
1602
+ long i;
1603
+
1604
+ dst = str_len_ensure(mrb, dst, didx + count);
1605
+ for (i = 0; i < count; i++) {
1606
+ RSTRING_PTR(dst)[didx + i] = '\0';
1607
+ }
1608
+ return count;
1609
+ }
1610
+
1611
+ static void
1612
+ check_x(mrb_state *mrb, mrb_int a, mrb_int count, char c)
1613
+ {
1614
+ if (a < count) {
1615
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "%c outside of string", c);
1616
+ }
1617
+ }
1618
+
1619
+ static void
1620
+ prepare_tmpl(mrb_state *mrb, struct tmpl *tmpl)
1621
+ {
1622
+ mrb_get_args(mrb, "S", &tmpl->str);
1623
+ tmpl->idx = 0;
1624
+ }
1625
+
1626
+ static int
1627
+ has_tmpl(const struct tmpl *tmpl)
1628
+ {
1629
+ return (tmpl->idx < RSTRING_LEN(tmpl->str));
1630
+ }
1631
+
1632
+ static enum pack_dir
1633
+ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_type *typep, mrb_int *sizep, mrb_int *countp, unsigned int *flagsp)
1634
+ {
1635
+ mrb_int t, tlen;
1636
+ int ch, size = 0;
1637
+ enum pack_dir dir;
1638
+ enum pack_type type;
1639
+ mrb_int count = 1;
1640
+ unsigned int flags = 0;
1641
+ const char *tptr;
1642
+
1643
+ tptr = RSTRING_PTR(tmpl->str);
1644
+ tlen = RSTRING_LEN(tmpl->str);
1645
+
1646
+ restart:
1647
+ if (tmpl->idx >= tlen) return PACK_DIR_NONE;
1648
+ t = tptr[tmpl->idx++];
1649
+ alias:
1650
+
1651
+ /* Handle whitespace - skip and restart */
1652
+ if (ISSPACE((char)t)) {
1653
+ goto restart;
1654
+ }
1655
+
1656
+ /* Special handling for runtime-dependent formats and special characters */
1657
+ switch (t) {
1658
+ case 'I':
1659
+ switch (sizeof(int)) {
1660
+ case 2: t = 'S'; goto alias;
1661
+ case 4: t = 'L'; goto alias;
1662
+ case 8: t = 'Q'; goto alias;
1663
+ default:
1664
+ mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %d", (int)sizeof(int));
1665
+ }
1666
+ break;
1667
+ case 'i':
1668
+ switch (sizeof(int)) {
1669
+ case 2: t = 's'; goto alias;
1670
+ case 4: t = 'l'; goto alias;
1671
+ case 8: t = 'q'; goto alias;
1672
+ default:
1673
+ mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %d", (int)sizeof(int));
1674
+ }
1675
+ break;
1676
+ case 'J':
1677
+ switch (sizeof(intptr_t)) {
1678
+ case 4: t = 'L'; goto alias;
1679
+ case 8: t = 'Q'; goto alias;
1680
+ default:
1681
+ mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(uintptr_t) == %d", (int)sizeof(uintptr_t));
1682
+ }
1683
+ break;
1684
+ case 'j':
1685
+ switch (sizeof(intptr_t)) {
1686
+ case 4: t = 'l'; goto alias;
1687
+ case 8: t = 'q'; goto alias;
1688
+ default:
1689
+ mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(intptr_t) == %d", (int)sizeof(intptr_t));
1690
+ }
1691
+ break;
1692
+ case '#':
1693
+ while (++tmpl->idx < tlen && tptr[tmpl->idx] != '\n')
1694
+ ;
1695
+ goto restart;
1696
+ case 'p': case 'P':
1697
+ case '%':
1698
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "%c is not supported", (char)t);
1699
+ break;
1700
+ default:
1701
+ /* Use O(1) lookup table for standard format characters */
1702
+ if (t >= 0 && t < 256) {
1703
+ format_info_t info_val = pack_format_info((unsigned char)t);
1704
+ const format_info_t *info = &info_val;
1705
+ if (info->dir != PACK_DIR_NONE) {
1706
+ /* Valid format character found in lookup table */
1707
+ dir = info->dir;
1708
+ type = info->type;
1709
+ size = info->size;
1710
+ flags = info->base_flags;
1711
+ break;
1712
+ }
1713
+ }
1714
+
1715
+ /* Handle invalid characters */
1716
+ char c = (char)t;
1717
+ mrb_value s = mrb_str_new(mrb, &c, 1);
1718
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown unpack directive %!v", s);
1719
+ }
1720
+
1721
+ /* read suffix [0-9*_!<>] */
1722
+ while (tmpl->idx < tlen) {
1723
+ ch = tptr[tmpl->idx];
1724
+ if (ISDIGIT(ch)) {
1725
+ char *e;
1726
+ mrb_int n;
1727
+ if (!mrb_read_int(tptr+tmpl->idx, tptr+tlen, &e, &n) || INT_MAX < n) {
1728
+ mrb_raise(mrb, E_RUNTIME_ERROR, "too big template length");
1729
+ }
1730
+ count = n;
1731
+ tmpl->idx = (int)(e - tptr);
1732
+ continue;
1733
+ }
1734
+ else if (ch == '*') {
1735
+ if (type == PACK_TYPE_NONE)
1736
+ count = 0;
1737
+ else
1738
+ count = -1;
1739
+ }
1740
+ else if (ch == '_' || ch == '!' || ch == '<' || ch == '>') {
1741
+ if (strchr("sSiIlLqQ", (int)t) == NULL) {
1742
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%c' allowed only after types sSiIlLqQ", ch);
1743
+ }
1744
+ if (ch == '_' || ch == '!') {
1745
+ flags |= PACK_FLAG_s;
1746
+ }
1747
+ else if (ch == '<') {
1748
+ flags |= PACK_FLAG_LT;
1749
+ }
1750
+ else if (ch == '>') {
1751
+ flags |= PACK_FLAG_GT;
1752
+ }
1753
+ }
1754
+ else {
1755
+ break;
1756
+ }
1757
+ tmpl->idx++;
1758
+ }
1759
+
1760
+ if ((flags & PACK_FLAG_LT) || (!(flags & PACK_FLAG_GT) && littleendian)) {
1761
+ flags |= PACK_FLAG_LITTLEENDIAN;
1762
+ }
1763
+
1764
+ *typep = type;
1765
+ *sizep = size;
1766
+ *countp = count;
1767
+ *flagsp = flags;
1768
+ return dir;
1769
+ }
1770
+
1771
+ /*
1772
+ * call-seq:
1773
+ * array.pack(template) -> string
1774
+ *
1775
+ * Packs the contents of array into a binary string according to the
1776
+ * directives in template. Directives are single characters from the
1777
+ * table below. Each directive may be followed by a number indicating
1778
+ * the number of times to repeat the directive.
1779
+ *
1780
+ * Template string directives:
1781
+ * C - 8-bit unsigned integer (unsigned char)
1782
+ * c - 8-bit signed integer (signed char)
1783
+ * S - 16-bit unsigned integer, native endian (uint16_t)
1784
+ * s - 16-bit signed integer, native endian (int16_t)
1785
+ * L - 32-bit unsigned integer, native endian (uint32_t)
1786
+ * l - 32-bit signed integer, native endian (int32_t)
1787
+ * Q - 64-bit unsigned integer, native endian (uint64_t)
1788
+ * q - 64-bit signed integer, native endian (int64_t)
1789
+ * n - 16-bit unsigned integer, network byte order
1790
+ * N - 32-bit unsigned integer, network byte order
1791
+ * v - 16-bit unsigned integer, little endian
1792
+ * V - 32-bit unsigned integer, little endian
1793
+ * f - single precision float, native format
1794
+ * d - double precision float, native format
1795
+ * A - ASCII string, space padded
1796
+ * a - ASCII string, null padded
1797
+ * Z - null-terminated string
1798
+ * H - hex string, high nibble first
1799
+ * h - hex string, low nibble first
1800
+ * x - null byte
1801
+ * X - back up one byte
1802
+ * @ - null fill to absolute position
1803
+ *
1804
+ * [1, 2, 3].pack("CCC") #=> "\x01\x02\x03"
1805
+ * [1, 2].pack("S*") #=> "\x01\x00\x02\x00" (little endian)
1806
+ * ["hello"].pack("A10") #=> "hello "
1807
+ */
1808
+ static mrb_value
1809
+ mrb_pack_pack(mrb_state *mrb, mrb_value ary)
1810
+ {
1811
+ mrb_value o;
1812
+ struct tmpl tmpl;
1813
+ enum pack_type type;
1814
+ mrb_int count;
1815
+ mrb_int size;
1816
+ unsigned int flags;
1817
+ enum pack_dir dir;
1818
+
1819
+ prepare_tmpl(mrb, &tmpl);
1820
+
1821
+ mrb_value result = mrb_str_new(mrb, NULL, 128); /* allocate initial buffer */
1822
+ mrb_int aidx = 0;
1823
+ mrb_int ridx = 0;
1824
+ while (has_tmpl(&tmpl)) {
1825
+ dir = read_tmpl(mrb, &tmpl, &type, &size, &count, &flags);
1826
+
1827
+ if (dir == PACK_DIR_NONE) break;
1828
+ if (dir == PACK_DIR_NUL) {
1829
+ grow:
1830
+ if (ridx > INT_MAX - count) goto overflow;
1831
+ ridx += pack_nul(mrb, result, ridx, (int)count);
1832
+ continue;
1833
+ }
1834
+ else if (dir == PACK_DIR_BACK) {
1835
+ check_x(mrb, ridx, count, 'X');
1836
+ ridx -= count;
1837
+ continue;
1838
+ }
1839
+ else if (dir == PACK_DIR_ABS) {
1840
+ count -= ridx;
1841
+ if (count > 0) goto grow;
1842
+ count = -count;
1843
+ check_x(mrb, ridx, count, '@');
1844
+ ridx -= count;
1845
+ continue;
1846
+ }
1847
+
1848
+ if ((flags & PACK_FLAG_WIDTH) && aidx >= RARRAY_LEN(ary)) {
1849
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments");
1850
+ }
1851
+ for (; aidx < RARRAY_LEN(ary); aidx++) {
1852
+ if (count == 0 && !(flags & PACK_FLAG_WIDTH))
1853
+ break;
1854
+
1855
+ o = RARRAY_PTR(ary)[aidx];
1856
+ if (type == PACK_TYPE_INTEGER) {
1857
+ o = mrb_ensure_int_type(mrb, o);
1858
+ }
1859
+ #ifndef MRB_NO_FLOAT
1860
+ else if (type == PACK_TYPE_FLOAT) {
1861
+ if (!mrb_float_p(o)) {
1862
+ o = mrb_ensure_float_type(mrb, o);
1863
+ }
1864
+ }
1865
+ #endif
1866
+ else if (type == PACK_TYPE_STRING) {
1867
+ if (!mrb_string_p(o)) {
1868
+ mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %T into String", o);
1869
+ }
1870
+ }
1871
+
1872
+ /* Optimized dispatch using grouped format handling for better branch prediction */
1873
+ switch (dir) {
1874
+ /* Integer formats - all use (mrb, o, result, ridx, flags) signature */
1875
+ case PACK_DIR_CHAR:
1876
+ ridx += pack_char(mrb, o, result, ridx, flags);
1877
+ break;
1878
+ case PACK_DIR_SHORT:
1879
+ ridx += pack_short(mrb, o, result, ridx, flags);
1880
+ break;
1881
+ case PACK_DIR_LONG:
1882
+ ridx += pack_long(mrb, o, result, ridx, flags);
1883
+ break;
1884
+ case PACK_DIR_QUAD:
1885
+ ridx += pack_quad(mrb, o, result, ridx, flags);
1886
+ break;
1887
+ case PACK_DIR_BER:
1888
+ ridx += pack_BER(mrb, o, result, ridx, flags);
1889
+ break;
1890
+
1891
+ #ifndef MRB_NO_FLOAT
1892
+ /* Float formats - all use (mrb, o, result, ridx, flags) signature */
1893
+ case PACK_DIR_DOUBLE:
1894
+ ridx += pack_double(mrb, o, result, ridx, flags);
1895
+ break;
1896
+ case PACK_DIR_FLOAT:
1897
+ ridx += pack_float(mrb, o, result, ridx, flags);
1898
+ break;
1899
+ #endif
1900
+
1901
+ /* String formats with count - use (mrb, o, result, ridx, count, flags) signature */
1902
+ case PACK_DIR_HEX:
1903
+ ridx += pack_hex(mrb, o, result, ridx, (int)count, flags);
1904
+ break;
1905
+ case PACK_DIR_BSTR:
1906
+ ridx += pack_bstr(mrb, o, result, ridx, (int)count, flags);
1907
+ break;
1908
+ case PACK_DIR_STR:
1909
+ ridx += pack_str(mrb, o, result, ridx, (int)count, flags);
1910
+ break;
1911
+
1912
+ /* String formats with count only - use (mrb, o, result, ridx, count) signature */
1913
+ case PACK_DIR_BASE64:
1914
+ ridx += pack_base64(mrb, o, result, ridx, (int)count);
1915
+ break;
1916
+ case PACK_DIR_UU:
1917
+ ridx += pack_uu(mrb, o, result, ridx, (int)count);
1918
+ break;
1919
+ case PACK_DIR_QENC:
1920
+ ridx += pack_qenc(mrb, o, result, ridx, (int)count);
1921
+ break;
1922
+
1923
+ /* UTF8 format - special signature (mrb, o, result, ridx, count, flags) */
1924
+ case PACK_DIR_UTF8:
1925
+ ridx += pack_utf8(mrb, o, result, ridx, (int)count, flags);
1926
+ break;
1927
+
1928
+ default:
1929
+ break;
1930
+ }
1931
+ if (flags & PACK_FLAG_COUNT2) {
1932
+ /* always consumes 1 entry */
1933
+ aidx++;
1934
+ break;
1935
+ }
1936
+ if (count > 0) {
1937
+ count--;
1938
+ }
1939
+ }
1940
+ if (ridx < 0) {
1941
+ overflow:
1942
+ mrb_raise(mrb, E_RANGE_ERROR, "negative (or overflowed) template size");
1943
+ }
1944
+ }
1945
+
1946
+ mrb_str_resize(mrb, result, ridx);
1947
+ return result;
1948
+ }
1949
+
1950
+ static mrb_value
1951
+ pack_unpack(mrb_state *mrb, mrb_value str, mrb_bool single)
1952
+ {
1953
+ struct tmpl tmpl;
1954
+ mrb_int count;
1955
+ unsigned int flags;
1956
+ enum pack_type type;
1957
+ mrb_int size;
1958
+ const unsigned char *sptr;
1959
+
1960
+ prepare_tmpl(mrb, &tmpl);
1961
+
1962
+ mrb_int srcidx = 0;
1963
+ mrb_int srclen = RSTRING_LEN(str);
1964
+
1965
+ mrb_value result = mrb_ary_new(mrb);
1966
+ while (has_tmpl(&tmpl)) {
1967
+ enum pack_dir dir = read_tmpl(mrb, &tmpl, &type, &size, &count, &flags);
1968
+
1969
+ if (dir == PACK_DIR_NONE) break;
1970
+ if (dir == PACK_DIR_NUL) {
1971
+ check_x(mrb, srclen-srcidx, count, 'x');
1972
+ srcidx += count;
1973
+ continue;
1974
+ }
1975
+ else if (dir == PACK_DIR_BACK) {
1976
+ check_x(mrb, srcidx, count, 'X');
1977
+ srcidx -= count;
1978
+ continue;
1979
+ }
1980
+ else if (dir == PACK_DIR_ABS) {
1981
+ check_x(mrb, srclen, count, '@');
1982
+ srcidx = count;
1983
+ continue;
1984
+ }
1985
+
1986
+ /* Optimized dispatch for PACK_FLAG_COUNT2 formats - grouped by signature */
1987
+ sptr = (const unsigned char*)RSTRING_PTR(str) + srcidx;
1988
+ switch (dir) {
1989
+ /* String formats with count and flags - (mrb, sptr, len, result, count, flags) */
1990
+ case PACK_DIR_HEX:
1991
+ srcidx += unpack_hex(mrb, sptr, srclen - srcidx, result, (int)count, flags);
1992
+ if (single) goto single_return;
1993
+ continue;
1994
+ case PACK_DIR_BSTR:
1995
+ srcidx += unpack_bstr(mrb, sptr, srclen - srcidx, result, (int)count, flags);
1996
+ if (single) goto single_return;
1997
+ continue;
1998
+ case PACK_DIR_STR:
1999
+ srcidx += unpack_str(mrb, sptr, srclen - srcidx, result, (int)count, flags);
2000
+ if (single) goto single_return;
2001
+ continue;
2002
+
2003
+ /* String formats without flags - (mrb, sptr, len, result) */
2004
+ case PACK_DIR_BASE64:
2005
+ srcidx += unpack_base64(mrb, sptr, srclen - srcidx, result);
2006
+ if (single) goto single_return;
2007
+ continue;
2008
+ case PACK_DIR_UU:
2009
+ srcidx += unpack_uu(mrb, sptr, srclen - srcidx, result);
2010
+ if (single) goto single_return;
2011
+ continue;
2012
+ case PACK_DIR_QENC:
2013
+ srcidx += unpack_qenc(mrb, sptr, srclen - srcidx, result);
2014
+ if (single) goto single_return;
2015
+ continue;
2016
+
2017
+ default:
2018
+ break;
2019
+ }
2020
+
2021
+ while (count != 0 && srcidx < srclen) {
2022
+ if (srclen - srcidx < size) {
2023
+ while (count-- > 0) {
2024
+ mrb_ary_push(mrb, result, mrb_nil_value());
2025
+ }
2026
+ break;
2027
+ }
2028
+
2029
+ sptr = (const unsigned char*)RSTRING_PTR(str) + srcidx;
2030
+ /* Optimized dispatch for element-by-element formats - grouped by signature */
2031
+ switch (dir) {
2032
+ /* Integer formats - all use (mrb, sptr, len, result, flags) signature */
2033
+ case PACK_DIR_CHAR:
2034
+ srcidx += unpack_char(mrb, sptr, srclen - srcidx, result, flags);
2035
+ break;
2036
+ case PACK_DIR_SHORT:
2037
+ srcidx += unpack_short(mrb, sptr, srclen - srcidx, result, flags);
2038
+ break;
2039
+ case PACK_DIR_LONG:
2040
+ srcidx += unpack_long(mrb, sptr, srclen - srcidx, result, flags);
2041
+ break;
2042
+ case PACK_DIR_QUAD:
2043
+ srcidx += unpack_quad(mrb, sptr, srclen - srcidx, result, flags);
2044
+ break;
2045
+ case PACK_DIR_BER:
2046
+ srcidx += unpack_BER(mrb, sptr, srclen - srcidx, result, flags);
2047
+ break;
2048
+
2049
+ #ifndef MRB_NO_FLOAT
2050
+ /* Float formats - all use (mrb, sptr, len, result, flags) signature */
2051
+ case PACK_DIR_FLOAT:
2052
+ srcidx += unpack_float(mrb, sptr, srclen - srcidx, result, flags);
2053
+ break;
2054
+ case PACK_DIR_DOUBLE:
2055
+ srcidx += unpack_double(mrb, sptr, srclen - srcidx, result, flags);
2056
+ break;
2057
+ #endif
2058
+
2059
+ /* UTF8 format - uses (mrb, sptr, len, result, flags) signature */
2060
+ case PACK_DIR_UTF8:
2061
+ srcidx += unpack_utf8(mrb, sptr, srclen - srcidx, result, flags);
2062
+ break;
2063
+
2064
+ default:
2065
+ mrb_raise(mrb, E_RUNTIME_ERROR, "mruby-pack's bug");
2066
+ }
2067
+ if (count > 0) {
2068
+ count--;
2069
+ }
2070
+ }
2071
+ }
2072
+ if (single) {
2073
+ single_return:
2074
+ if (RARRAY_LEN(result) > 0) {
2075
+ return RARRAY_PTR(result)[0];
2076
+ }
2077
+ return mrb_nil_value();
2078
+ }
2079
+ return result;
2080
+ }
2081
+
2082
+ /*
2083
+ * call-seq:
2084
+ * string.unpack(template) -> array
2085
+ *
2086
+ * Unpacks the contents of string according to the template string,
2087
+ * returning an array of values. Template uses the same format as
2088
+ * Array#pack. See Array#pack for template string format.
2089
+ *
2090
+ * "\x01\x02\x03".unpack("CCC") #=> [1, 2, 3]
2091
+ * "\x01\x00\x02\x00".unpack("S*") #=> [1, 2] (little endian)
2092
+ * "hello ".unpack("A10") #=> ["hello"]
2093
+ */
2094
+ static mrb_value
2095
+ mrb_pack_unpack(mrb_state *mrb, mrb_value str)
2096
+ {
2097
+ return pack_unpack(mrb, str, FALSE);
2098
+ }
2099
+
2100
+ /*
2101
+ * call-seq:
2102
+ * string.unpack1(template) -> object
2103
+ *
2104
+ * Unpacks the first value from string according to the template string.
2105
+ * This is equivalent to string.unpack(template)[0] but more efficient
2106
+ * when only the first value is needed.
2107
+ *
2108
+ * "\x01\x02\x03".unpack1("C") #=> 1
2109
+ * "\x01\x00\x02\x00".unpack1("S") #=> 1 (little endian)
2110
+ * "hello ".unpack1("A10") #=> "hello"
2111
+ */
2112
+ static mrb_value
2113
+ mrb_pack_unpack1(mrb_state *mrb, mrb_value str)
2114
+ {
2115
+ return pack_unpack(mrb, str, TRUE);
2116
+ }
2117
+
2118
+ void
2119
+ mrb_mruby_pack_gem_init(mrb_state *mrb)
2120
+ {
2121
+ mrb_define_method_id(mrb, mrb->array_class, MRB_SYM(pack), mrb_pack_pack, MRB_ARGS_REQ(1));
2122
+ mrb_define_method_id(mrb, mrb->string_class, MRB_SYM(unpack), mrb_pack_unpack, MRB_ARGS_REQ(1));
2123
+ mrb_define_method_id(mrb, mrb->string_class, MRB_SYM(unpack1), mrb_pack_unpack1, MRB_ARGS_REQ(1));
2124
+ }
2125
+
2126
+ void
2127
+ mrb_mruby_pack_gem_final(mrb_state *mrb)
2128
+ {
2129
+ }