inkcpp_rb 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 (273) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -0
  3. data/CHANGELOG.md +1 -0
  4. data/Gemfile +10 -0
  5. data/Gemfile.lock +84 -0
  6. data/LICENSE +7 -0
  7. data/README.md +3 -0
  8. data/Rakefile +16 -0
  9. data/bin/console +15 -0
  10. data/bin/setup +10 -0
  11. data/bin/tapioca +29 -0
  12. data/ext/inkcpp_rb/extconf.rb +19 -0
  13. data/ext/inkcpp_rb/inkcpp/.clang-format +99 -0
  14. data/ext/inkcpp_rb/inkcpp/.github/FUNDING.yml +1 -0
  15. data/ext/inkcpp_rb/inkcpp/.github/workflows/build.yml +344 -0
  16. data/ext/inkcpp_rb/inkcpp/.github/workflows/release.yml +49 -0
  17. data/ext/inkcpp_rb/inkcpp/.gitignore +25 -0
  18. data/ext/inkcpp_rb/inkcpp/.gitmodules +9 -0
  19. data/ext/inkcpp_rb/inkcpp/CMakeLists.txt +170 -0
  20. data/ext/inkcpp_rb/inkcpp/CODE_OF_CONDUCT.md +76 -0
  21. data/ext/inkcpp_rb/inkcpp/CONTRIBUTING.md +55 -0
  22. data/ext/inkcpp_rb/inkcpp/Config.cmake.in +2 -0
  23. data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/CMakeLists.txt +13 -0
  24. data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/main.c +38 -0
  25. data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/main.cpp +40 -0
  26. data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/test.ink +8 -0
  27. data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/test.ink.json +1 -0
  28. data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example.zip +0 -0
  29. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/InkCPP_DEMO.zip +0 -0
  30. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/CreateThread.png +0 -0
  31. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/HandleChoice.png +0 -0
  32. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/ListElementOf.png +0 -0
  33. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/MinimalRuntime.png +0 -0
  34. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/MinimalThread.png +0 -0
  35. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/ObseverChange.png +0 -0
  36. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/TagListGetValue.png +0 -0
  37. data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/YieldResume.png +0 -0
  38. data/ext/inkcpp_rb/inkcpp/Doxyfile +2825 -0
  39. data/ext/inkcpp_rb/inkcpp/LICENSE.txt +22 -0
  40. data/ext/inkcpp_rb/inkcpp/Minimal.runsettings +8 -0
  41. data/ext/inkcpp_rb/inkcpp/README.md +192 -0
  42. data/ext/inkcpp_rb/inkcpp/inkcpp/CMakeLists.txt +67 -0
  43. data/ext/inkcpp_rb/inkcpp/inkcpp/array.h +481 -0
  44. data/ext/inkcpp_rb/inkcpp/inkcpp/avl_array.h +833 -0
  45. data/ext/inkcpp_rb/inkcpp/inkcpp/casting.h +93 -0
  46. data/ext/inkcpp_rb/inkcpp/inkcpp/choice.cpp +54 -0
  47. data/ext/inkcpp_rb/inkcpp/inkcpp/collections/restorable.cpp +124 -0
  48. data/ext/inkcpp_rb/inkcpp/inkcpp/collections/restorable.h +406 -0
  49. data/ext/inkcpp_rb/inkcpp/inkcpp/container_operations.cpp +52 -0
  50. data/ext/inkcpp_rb/inkcpp/inkcpp/container_operations.h +34 -0
  51. data/ext/inkcpp_rb/inkcpp/inkcpp/executioner.h +179 -0
  52. data/ext/inkcpp_rb/inkcpp/inkcpp/functional.cpp +86 -0
  53. data/ext/inkcpp_rb/inkcpp/inkcpp/functions.cpp +54 -0
  54. data/ext/inkcpp_rb/inkcpp/inkcpp/functions.h +40 -0
  55. data/ext/inkcpp_rb/inkcpp/inkcpp/globals_impl.cpp +289 -0
  56. data/ext/inkcpp_rb/inkcpp/inkcpp/globals_impl.h +149 -0
  57. data/ext/inkcpp_rb/inkcpp/inkcpp/header.cpp +44 -0
  58. data/ext/inkcpp_rb/inkcpp/inkcpp/include/choice.h +106 -0
  59. data/ext/inkcpp_rb/inkcpp/inkcpp/include/functional.h +327 -0
  60. data/ext/inkcpp_rb/inkcpp/inkcpp/include/globals.h +196 -0
  61. data/ext/inkcpp_rb/inkcpp/inkcpp/include/list.h +187 -0
  62. data/ext/inkcpp_rb/inkcpp/inkcpp/include/runner.h +291 -0
  63. data/ext/inkcpp_rb/inkcpp/inkcpp/include/snapshot.h +61 -0
  64. data/ext/inkcpp_rb/inkcpp/inkcpp/include/story.h +219 -0
  65. data/ext/inkcpp_rb/inkcpp/inkcpp/include/story_ptr.h +233 -0
  66. data/ext/inkcpp_rb/inkcpp/inkcpp/include/traits.h +270 -0
  67. data/ext/inkcpp_rb/inkcpp/inkcpp/include/types.h +169 -0
  68. data/ext/inkcpp_rb/inkcpp/inkcpp/list_impl.cpp +79 -0
  69. data/ext/inkcpp_rb/inkcpp/inkcpp/list_impl.h +39 -0
  70. data/ext/inkcpp_rb/inkcpp/inkcpp/list_operations.cpp +276 -0
  71. data/ext/inkcpp_rb/inkcpp/inkcpp/list_operations.h +356 -0
  72. data/ext/inkcpp_rb/inkcpp/inkcpp/list_table.cpp +841 -0
  73. data/ext/inkcpp_rb/inkcpp/inkcpp/list_table.h +450 -0
  74. data/ext/inkcpp_rb/inkcpp/inkcpp/numeric_operations.cpp +40 -0
  75. data/ext/inkcpp_rb/inkcpp/inkcpp/numeric_operations.h +529 -0
  76. data/ext/inkcpp_rb/inkcpp/inkcpp/operation_bases.h +164 -0
  77. data/ext/inkcpp_rb/inkcpp/inkcpp/operations.h +100 -0
  78. data/ext/inkcpp_rb/inkcpp/inkcpp/output.cpp +528 -0
  79. data/ext/inkcpp_rb/inkcpp/inkcpp/output.h +153 -0
  80. data/ext/inkcpp_rb/inkcpp/inkcpp/platform.h +22 -0
  81. data/ext/inkcpp_rb/inkcpp/inkcpp/random.h +38 -0
  82. data/ext/inkcpp_rb/inkcpp/inkcpp/runner_impl.cpp +1396 -0
  83. data/ext/inkcpp_rb/inkcpp/inkcpp/runner_impl.h +336 -0
  84. data/ext/inkcpp_rb/inkcpp/inkcpp/simple_restorable_stack.h +335 -0
  85. data/ext/inkcpp_rb/inkcpp/inkcpp/snapshot_impl.cpp +182 -0
  86. data/ext/inkcpp_rb/inkcpp/inkcpp/snapshot_impl.h +91 -0
  87. data/ext/inkcpp_rb/inkcpp/inkcpp/snapshot_interface.h +57 -0
  88. data/ext/inkcpp_rb/inkcpp/inkcpp/stack.cpp +618 -0
  89. data/ext/inkcpp_rb/inkcpp/inkcpp/stack.h +243 -0
  90. data/ext/inkcpp_rb/inkcpp/inkcpp/story_impl.cpp +361 -0
  91. data/ext/inkcpp_rb/inkcpp/inkcpp/story_impl.h +92 -0
  92. data/ext/inkcpp_rb/inkcpp/inkcpp/story_ptr.cpp +75 -0
  93. data/ext/inkcpp_rb/inkcpp/inkcpp/string_operations.cpp +125 -0
  94. data/ext/inkcpp_rb/inkcpp/inkcpp/string_operations.h +67 -0
  95. data/ext/inkcpp_rb/inkcpp/inkcpp/string_table.cpp +149 -0
  96. data/ext/inkcpp_rb/inkcpp/inkcpp/string_table.h +47 -0
  97. data/ext/inkcpp_rb/inkcpp/inkcpp/string_utils.h +207 -0
  98. data/ext/inkcpp_rb/inkcpp/inkcpp/system.cpp +39 -0
  99. data/ext/inkcpp_rb/inkcpp/inkcpp/tuple.hpp +151 -0
  100. data/ext/inkcpp_rb/inkcpp/inkcpp/value.cpp +279 -0
  101. data/ext/inkcpp_rb/inkcpp/inkcpp/value.h +666 -0
  102. data/ext/inkcpp_rb/inkcpp/inkcpp_c/CMakeLists.txt +62 -0
  103. data/ext/inkcpp_rb/inkcpp/inkcpp_c/include/inkcpp.h +393 -0
  104. data/ext/inkcpp_rb/inkcpp/inkcpp_c/inkcpp.cpp +344 -0
  105. data/ext/inkcpp_rb/inkcpp/inkcpp_c/inkcpp_c.pc.in +10 -0
  106. data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/ExternalFunction.c +56 -0
  107. data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Globals.c +98 -0
  108. data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Lists.c +73 -0
  109. data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Observer.c +36 -0
  110. data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Snapshot.c +65 -0
  111. data/ext/inkcpp_rb/inkcpp/inkcpp_cl/CMakeLists.txt +49 -0
  112. data/ext/inkcpp_rb/inkcpp/inkcpp_cl/inkcpp_cl.cpp +215 -0
  113. data/ext/inkcpp_rb/inkcpp/inkcpp_cl/test.cpp +209 -0
  114. data/ext/inkcpp_rb/inkcpp/inkcpp_cl/test.h +8 -0
  115. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/CMakeLists.txt +37 -0
  116. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_emitter.cpp +446 -0
  117. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_emitter.h +70 -0
  118. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_stream.cpp +166 -0
  119. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_stream.h +79 -0
  120. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/command.cpp +107 -0
  121. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/compiler.cpp +96 -0
  122. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/emitter.cpp +62 -0
  123. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/emitter.h +104 -0
  124. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/include/compilation_results.h +22 -0
  125. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/include/compiler.h +44 -0
  126. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/json.hpp +24596 -0
  127. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/json_compiler.cpp +411 -0
  128. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/json_compiler.h +62 -0
  129. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/list_data.cpp +47 -0
  130. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/list_data.h +70 -0
  131. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/reporter.cpp +107 -0
  132. data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/reporter.h +55 -0
  133. data/ext/inkcpp_rb/inkcpp/inkcpp_py/CMakeLists.txt +19 -0
  134. data/ext/inkcpp_rb/inkcpp/inkcpp_py/example.py +78 -0
  135. data/ext/inkcpp_rb/inkcpp/inkcpp_py/src/module.cpp +317 -0
  136. data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/conftest.py +53 -0
  137. data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_ExternalFunctions.py +35 -0
  138. data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Globals.py +40 -0
  139. data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Lists.py +43 -0
  140. data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Observer.py +27 -0
  141. data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Snapshot.py +57 -0
  142. data/ext/inkcpp_rb/inkcpp/inkcpp_py/unreal_example.ink +71 -0
  143. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Array.cpp +115 -0
  144. data/ext/inkcpp_rb/inkcpp/inkcpp_test/CMakeLists.txt +117 -0
  145. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Callstack.cpp +392 -0
  146. data/ext/inkcpp_rb/inkcpp/inkcpp_test/EmptyStringForDivert.cpp +36 -0
  147. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ExternalFunctionsExecuteProperly.cpp +34 -0
  148. data/ext/inkcpp_rb/inkcpp/inkcpp_test/FallbackFunction.cpp +77 -0
  149. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Globals.cpp +73 -0
  150. data/ext/inkcpp_rb/inkcpp/inkcpp_test/InkyJson.cpp +34 -0
  151. data/ext/inkcpp_rb/inkcpp/inkcpp_test/LabelCondition.cpp +60 -0
  152. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Lists.cpp +144 -0
  153. data/ext/inkcpp_rb/inkcpp/inkcpp_test/LookaheadSafe.cpp +46 -0
  154. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Main.cpp +7 -0
  155. data/ext/inkcpp_rb/inkcpp/inkcpp_test/MoveTo.cpp +95 -0
  156. data/ext/inkcpp_rb/inkcpp/inkcpp_test/NewLines.cpp +76 -0
  157. data/ext/inkcpp_rb/inkcpp/inkcpp_test/NoEarlyTags.cpp +33 -0
  158. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Observer.cpp +245 -0
  159. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Pointer.cpp +191 -0
  160. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Restorable.cpp +294 -0
  161. data/ext/inkcpp_rb/inkcpp/inkcpp_test/SpaceAfterBracketChoice.cpp +45 -0
  162. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Stack.cpp +224 -0
  163. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Tags.cpp +131 -0
  164. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ThirdTierChoiceAfterBrackets.cpp +38 -0
  165. data/ext/inkcpp_rb/inkcpp/inkcpp_test/UTF8.cpp +56 -0
  166. data/ext/inkcpp_rb/inkcpp/inkcpp_test/Value.cpp +210 -0
  167. data/ext/inkcpp_rb/inkcpp/inkcpp_test/catch.hpp +17970 -0
  168. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/AHF.ink +7 -0
  169. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ChoiceBracketStory.ink +7 -0
  170. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/EmptyStringForDivert.ink +13 -0
  171. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ExternalFunctionsExecuteProperly.ink +11 -0
  172. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/FallBack.ink +15 -0
  173. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/GlobalStory.ink +9 -0
  174. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/LabelConditionStory.ink +5 -0
  175. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/LinesStory.ink +42 -0
  176. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ListLogicStory.ink +40 -0
  177. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ListStory.ink +8 -0
  178. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/LookaheadSafe.ink +14 -0
  179. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/MoveTo.ink +36 -0
  180. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/NoEarlyTags.ink +19 -0
  181. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ObserverStory.ink +8 -0
  182. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/SimpleStoryFlow.ink +65 -0
  183. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/TagsStory.ink +22 -0
  184. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/TheIntercept.ink +1686 -0
  185. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ThirdTierChoiceAfterBracketsStory.ink +13 -0
  186. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/UTF-8-demo.txt +212 -0
  187. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/UTF8Story.ink +218 -0
  188. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/simple-1.1.1-inklecate.json +154 -0
  189. data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/simple-1.1.1-inky.json +160 -0
  190. data/ext/inkcpp_rb/inkcpp/notes/ArchitectureNotes.md +54 -0
  191. data/ext/inkcpp_rb/inkcpp/notes/ListNotes.md +69 -0
  192. data/ext/inkcpp_rb/inkcpp/notes/OperationNotes.md +35 -0
  193. data/ext/inkcpp_rb/inkcpp/notes/TagsNotes.md +24 -0
  194. data/ext/inkcpp_rb/inkcpp/notes/WhitespaceNotes.md +28 -0
  195. data/ext/inkcpp_rb/inkcpp/proofing/README.md +3 -0
  196. data/ext/inkcpp_rb/inkcpp/proofing/inkcpp_runtime_driver +12 -0
  197. data/ext/inkcpp_rb/inkcpp/pyproject.toml +63 -0
  198. data/ext/inkcpp_rb/inkcpp/setup.py +166 -0
  199. data/ext/inkcpp_rb/inkcpp/shared/CMakeLists.txt +14 -0
  200. data/ext/inkcpp_rb/inkcpp/shared/private/command.h +172 -0
  201. data/ext/inkcpp_rb/inkcpp/shared/private/header.h +46 -0
  202. data/ext/inkcpp_rb/inkcpp/shared/public/config.h +53 -0
  203. data/ext/inkcpp_rb/inkcpp/shared/public/system.h +307 -0
  204. data/ext/inkcpp_rb/inkcpp/shared/public/version.h +14 -0
  205. data/ext/inkcpp_rb/inkcpp/tests/TestAllSequenceTypes.ink +59 -0
  206. data/ext/inkcpp_rb/inkcpp/tests/TestArithmetic.ink +17 -0
  207. data/ext/inkcpp_rb/inkcpp/tests/TestBasicStringLiterals.ink +8 -0
  208. data/ext/inkcpp_rb/inkcpp/tests/TestBasicTunnel.ink +10 -0
  209. data/ext/inkcpp_rb/inkcpp/tests/TestBlanksInInlineSequences.ink +51 -0
  210. data/ext/inkcpp_rb/inkcpp/tests/TestCallStackEvaluation.ink +15 -0
  211. data/ext/inkcpp_rb/inkcpp/tests/TestChoiceCount.ink +15 -0
  212. data/ext/inkcpp_rb/inkcpp/tests/TestChoiceDivertsToDone.ink +6 -0
  213. data/ext/inkcpp_rb/inkcpp/tests/TestChoiceWithBracketsOnly.ink +9 -0
  214. data/ext/inkcpp_rb/inkcpp/tests/TestCompareDivertTargets.ink +26 -0
  215. data/ext/inkcpp_rb/inkcpp/tests/TestComplexTunnels.ink +22 -0
  216. data/ext/inkcpp_rb/inkcpp/tests/TestConditionalChoiceInWeave.ink +19 -0
  217. data/ext/inkcpp_rb/inkcpp/tests/TestTunnelOnwardsAfterTunnel.ink +17 -0
  218. data/ext/inkcpp_rb/inkcpp/unreal/CMakeLists.txt +51 -0
  219. data/ext/inkcpp_rb/inkcpp/unreal/UE_example.ink +92 -0
  220. data/ext/inkcpp_rb/inkcpp/unreal/blueprint_filter.js +377 -0
  221. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Resources/Icon128.png +0 -0
  222. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkAsset.cpp +47 -0
  223. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkChoice.cpp +40 -0
  224. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkList.cpp +86 -0
  225. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkRuntime.cpp +265 -0
  226. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkThread.cpp +239 -0
  227. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkVar.cpp +143 -0
  228. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/TagList.cpp +95 -0
  229. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/inkcpp.cpp +13 -0
  230. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkAsset.h +50 -0
  231. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkChoice.h +58 -0
  232. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkDelegates.h +139 -0
  233. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkList.h +102 -0
  234. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkRuntime.h +177 -0
  235. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkSnapshot.h +30 -0
  236. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkThread.h +215 -0
  237. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkVar.h +245 -0
  238. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/TagList.h +77 -0
  239. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/inkcpp.h +217 -0
  240. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/inkcpp.Build.cs +62 -0
  241. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/InkAssetFactory.cpp +237 -0
  242. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/InkAssetFactory.h +43 -0
  243. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/inkcpp_editor.cpp +13 -0
  244. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/inklecate_cmd.cpp.in +24 -0
  245. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Public/inkcpp_editor.h +9 -0
  246. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/inkcpp_editor.Build.cs +61 -0
  247. data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/inkcpp.uplugin +44 -0
  248. data/ext/inkcpp_rb/inkcpp/unreal/render.css +1 -0
  249. data/ext/inkcpp_rb/inkcpp_rb.cpp +321 -0
  250. data/inkcpp_rb.gemspec +54 -0
  251. data/rbi/inkcpp_rb.rbi +211 -0
  252. data/sorbet/config +4 -0
  253. data/sorbet/rbi/annotations/.gitattributes +1 -0
  254. data/sorbet/rbi/annotations/minitest.rbi +119 -0
  255. data/sorbet/rbi/gems/.gitattributes +1 -0
  256. data/sorbet/rbi/gems/benchmark@0.4.0.rbi +618 -0
  257. data/sorbet/rbi/gems/erubi@1.13.1.rbi +155 -0
  258. data/sorbet/rbi/gems/minitest@5.25.4.rbi +1547 -0
  259. data/sorbet/rbi/gems/netrc@0.11.0.rbi +159 -0
  260. data/sorbet/rbi/gems/parallel@1.26.3.rbi +291 -0
  261. data/sorbet/rbi/gems/prism@1.3.0.rbi +40040 -0
  262. data/sorbet/rbi/gems/rake-compiler@1.2.8.rbi +9 -0
  263. data/sorbet/rbi/gems/rake@13.2.1.rbi +3033 -0
  264. data/sorbet/rbi/gems/rbi@0.2.2.rbi +4527 -0
  265. data/sorbet/rbi/gems/rice@4.3.3.rbi +44 -0
  266. data/sorbet/rbi/gems/spoom@1.5.0.rbi +4932 -0
  267. data/sorbet/rbi/gems/tapioca@0.16.7.rbi +3611 -0
  268. data/sorbet/rbi/gems/thor@1.3.2.rbi +4378 -0
  269. data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +435 -0
  270. data/sorbet/rbi/gems/yard@0.9.37.rbi +18379 -0
  271. data/sorbet/tapioca/config.yml +13 -0
  272. data/sorbet/tapioca/require.rb +4 -0
  273. metadata +400 -0
@@ -0,0 +1,446 @@
1
+ /* Copyright (c) 2024 Julian Benda
2
+ *
3
+ * This file is part of inkCPP which is released under MIT license.
4
+ * See file LICENSE.txt or go to
5
+ * https://github.com/JBenda/inkcpp for full license details.
6
+ */
7
+ #include "binary_emitter.h"
8
+
9
+ #include "header.h"
10
+ #include "version.h"
11
+ #include "list_data.h"
12
+
13
+ #include <vector>
14
+ #include <map>
15
+ #include <fstream>
16
+
17
+ #ifndef WIN32
18
+ # include <cstring>
19
+ #endif
20
+
21
+ namespace ink::compiler::internal
22
+ {
23
+ using std::vector;
24
+ using std::map;
25
+ using std::string;
26
+
27
+ char* strtok_s(char* s, const char* sep, char** context)
28
+ {
29
+ #if defined(_WIN32) || defined(_WIN64)
30
+ return ::strtok_s(s, sep, context);
31
+ #else
32
+ if (context == nullptr || sep == nullptr || (s == nullptr && *context == nullptr)) {
33
+ errno = EINVAL;
34
+ return nullptr;
35
+ }
36
+ return ::strtok_r(s, sep, context);
37
+ #endif
38
+ }
39
+
40
+ // holds information about a container
41
+ struct container_data {
42
+ // child containers
43
+ vector<container_data*> children;
44
+
45
+ // children names (not all containers have names)
46
+ map<string, container_data*> named_children;
47
+
48
+ // Indexes of child containers (index is child index of parent)
49
+ map<int, container_data*> indexed_children;
50
+
51
+ // Offsets of noop operations
52
+ map<int, uint32_t> noop_offsets;
53
+
54
+ // parent pointer
55
+ container_data* parent = nullptr;
56
+
57
+ // Offset in the binary stream
58
+ uint32_t offset = 0;
59
+ uint32_t end_offset = 0;
60
+
61
+ // Index used in CNT? operations
62
+ container_t counter_index = ~0;
63
+
64
+ ~container_data()
65
+ {
66
+ // Destroy children
67
+ for (auto child : children)
68
+ delete child;
69
+
70
+ // Clear lists
71
+ children.clear();
72
+ // named_children.clear();
73
+ // indexed_children.clear();
74
+ // noop_offsets.clear();
75
+ parent = nullptr;
76
+ }
77
+ };
78
+
79
+ binary_emitter::binary_emitter()
80
+ : _root(nullptr)
81
+ {
82
+ }
83
+
84
+ binary_emitter::~binary_emitter()
85
+ {
86
+ if (_root != nullptr)
87
+ delete _root;
88
+ _root = nullptr;
89
+ }
90
+
91
+ uint32_t binary_emitter::start_container(int index_in_parent, const std::string& name)
92
+ {
93
+ // Create new container metadata
94
+ auto container = new container_data();
95
+
96
+ // Store root
97
+ if (_root == nullptr)
98
+ _root = container;
99
+
100
+ // Parent it to the current container
101
+ container->parent = _current;
102
+
103
+ // Set offset to the current position
104
+ container->offset = _containers.pos();
105
+
106
+ // Add to parents lists
107
+ if (_current != nullptr) {
108
+ _current->children.push_back(container);
109
+ _current->indexed_children.insert({index_in_parent, container});
110
+
111
+ if (! name.empty()) {
112
+ _current->named_children.insert({name, container});
113
+ }
114
+ }
115
+
116
+ // Set this as the current pointer
117
+ _current = container;
118
+
119
+ // Return current position
120
+ return _containers.pos();
121
+ }
122
+
123
+ uint32_t binary_emitter::end_container()
124
+ {
125
+ // Move up the chain
126
+ _current->end_offset = _containers.pos();
127
+ _current = _current->parent;
128
+
129
+ // Return offset
130
+ return _containers.pos();
131
+ }
132
+
133
+ int binary_emitter::function_container_arguments(const std::string& name)
134
+ {
135
+ if (_root == nullptr) {
136
+ return -1;
137
+ }
138
+ auto fn = _root->named_children.find(name);
139
+ if (fn == _root->named_children.end()) {
140
+ return -1;
141
+ }
142
+
143
+ size_t offset = fn->second->offset;
144
+ byte_t cmd = _containers.get(offset);
145
+ int arity = 0;
146
+ while (static_cast<Command>(cmd) == Command::DEFINE_TEMP) {
147
+ offset += 6; // command(1) + flag(1) + variable_name_hash(4)
148
+ cmd = _containers.get(offset);
149
+ ++arity;
150
+ }
151
+ return arity;
152
+ }
153
+
154
+ void binary_emitter::write_raw(
155
+ Command command, CommandFlag flag, const char* payload, ink::size_t payload_size
156
+ )
157
+ {
158
+ _containers.write(command);
159
+ _containers.write(flag);
160
+ if (payload_size > 0)
161
+ _containers.write(( const byte_t* ) payload, payload_size);
162
+ }
163
+
164
+ void binary_emitter::write_path(
165
+ Command command, CommandFlag flag, const std::string& path, bool useCountIndex
166
+ )
167
+ {
168
+ // Write blank command with 0 payload
169
+ write(command, ( uint32_t ) 0, flag);
170
+
171
+ // Note the position of this later so we can resolve the paths at the end
172
+ size_t param_position = _containers.pos() - sizeof(uint32_t);
173
+ bool op = flag & CommandFlag::FALLBACK_FUNCTION;
174
+ _paths.push_back(std::make_tuple(param_position, path, op, _current, useCountIndex));
175
+ }
176
+
177
+ void binary_emitter::write_variable(Command command, CommandFlag flag, const std::string& name)
178
+ {
179
+ // Use hash as identifier
180
+ uint32_t hash = hash_string(name.c_str());
181
+
182
+ // Write it out
183
+ write(command, hash, flag);
184
+ }
185
+
186
+ void binary_emitter::write_string(Command command, CommandFlag flag, const std::string& string)
187
+ {
188
+ // Save current position in table
189
+ uint32_t pos = _strings.pos();
190
+
191
+ // Write string to table (omit ^ if it begins with one)
192
+ if (string.length() > 0 && string[0] == '^')
193
+ _strings.write(string.substr(1));
194
+ else
195
+ _strings.write(string);
196
+
197
+ // Written position is what we write out in our command
198
+ write(command, pos, flag);
199
+ }
200
+
201
+ void binary_emitter::write_list(
202
+ Command command, CommandFlag flag, const std::vector<list_flag>& entries
203
+ )
204
+ {
205
+ uint32_t id = _list_count++;
206
+ for (const list_flag& entry : entries) {
207
+ _lists.write(entry);
208
+ }
209
+ _lists.write(null_flag);
210
+ write(command, id, flag);
211
+ }
212
+
213
+ void binary_emitter::handle_nop(int index_in_parent)
214
+ {
215
+ _current->noop_offsets.insert({index_in_parent, _containers.pos()});
216
+ }
217
+
218
+ void binary_emitter::output(std::ostream& out)
219
+ {
220
+ // Write the ink version
221
+ // TODO: define this order in header?
222
+ using header = ink::internal::header;
223
+ header::endian_types same = header::endian_types::same;
224
+ out.write(( const char* ) &same, sizeof(decltype(same)));
225
+ out.write(( const char* ) &_ink_version, sizeof(decltype(_ink_version)));
226
+ out.write(( const char* ) &ink::InkBinVersion, sizeof(decltype(ink::InkBinVersion)));
227
+
228
+ // Write the string table
229
+ _strings.write_to(out);
230
+
231
+ // Write a separator
232
+ out << ( char ) 0;
233
+
234
+ // Write lists meta data and defined lists
235
+ _lists.write_to(out);
236
+ // Write a seperator
237
+ out.write(reinterpret_cast<const char*>(&null_flag), sizeof(null_flag));
238
+
239
+ // Write out container map
240
+ write_container_map(out, _container_map, _max_container_index);
241
+
242
+ // Write a separator
243
+ uint32_t END_MARKER = ~0;
244
+ out.write(( const char* ) &END_MARKER, sizeof(uint32_t));
245
+
246
+ // Write container hash list
247
+ write_container_hash_map(out);
248
+ out.write(( const char* ) &END_MARKER, sizeof(uint32_t));
249
+
250
+ // Write the container data
251
+ _containers.write_to(out);
252
+
253
+ // Flush the file
254
+ out.flush();
255
+ }
256
+
257
+ void binary_emitter::initialize()
258
+ {
259
+ // Reset binary data stores
260
+ _strings.reset();
261
+ _list_count = 0;
262
+ _lists.reset();
263
+ _containers.reset();
264
+
265
+ // clear other data
266
+ _paths.clear();
267
+
268
+ if (_root != nullptr)
269
+ delete _root;
270
+
271
+ _current = nullptr;
272
+ _root = nullptr;
273
+ }
274
+
275
+ void binary_emitter::finalize()
276
+ {
277
+ // post process path commands
278
+ process_paths();
279
+ }
280
+
281
+ void binary_emitter::setContainerIndex(container_t index) { _current->counter_index = index; }
282
+
283
+ uint32_t binary_emitter::fallthrough_divert()
284
+ {
285
+ // write a fallthrough divert ???
286
+ write<uint32_t>(Command::DIVERT, ( uint32_t ) 0, CommandFlag::DIVERT_IS_FALLTHROUGH);
287
+
288
+ // Return the location of the divert offset
289
+ return _containers.pos() - sizeof(uint32_t);
290
+ }
291
+
292
+ void binary_emitter::patch_fallthroughs(uint32_t position)
293
+ {
294
+ // Patch
295
+ _containers.set(position, _containers.pos());
296
+ }
297
+
298
+ void binary_emitter::process_paths()
299
+ {
300
+ for (auto pair : _paths) {
301
+ // We need to replace the uint32_t at this location with the byte position of the requested
302
+ // container
303
+ using std::get;
304
+ size_t position = get<0>(pair);
305
+ const std::string& path = get<1>(pair);
306
+ bool optional = get<2>(pair);
307
+ container_data* context = get<3>(pair);
308
+ bool useCountIndex = get<4>(pair);
309
+
310
+ // Start at the root
311
+ container_data* container = _root;
312
+
313
+ // Unless it's a relative path
314
+ const char* path_cstr = path.c_str();
315
+ if (path_cstr[0] == '.') {
316
+ container = context;
317
+ path_cstr += 1;
318
+ }
319
+
320
+ bool firstParent = true;
321
+
322
+ // We need to parse the path
323
+ offset_t noop_offset = ~0;
324
+ char* _context = nullptr;
325
+ const char* token
326
+ = ink::compiler::internal::strtok_s(const_cast<char*>(path_cstr), ".", &_context);
327
+ while (token != nullptr) {
328
+ // Number
329
+ // variable names can start with a number
330
+ bool isNumber = true;
331
+ for (const char* i = token; *i; ++i) {
332
+ if (! isdigit(*i)) {
333
+ isNumber = false;
334
+ break;
335
+ }
336
+ }
337
+ if (isNumber) {
338
+ // Check if we have a nop registered at that index
339
+ int index = atoi(token);
340
+ auto nop_iter = container->noop_offsets.find(index);
341
+ if (nop_iter != container->noop_offsets.end()) {
342
+ noop_offset = nop_iter->second;
343
+ break;
344
+ } else
345
+ container = container->indexed_children[index];
346
+ }
347
+ // Parent
348
+ else if (token[0] == '^') {
349
+ if (! firstParent)
350
+ container = container->parent;
351
+ }
352
+ // Named child
353
+ else {
354
+ auto itr = container->named_children.find(token);
355
+ container = itr == container->named_children.end() ? nullptr : itr->second;
356
+ }
357
+
358
+ firstParent = false;
359
+
360
+ // Get the next token
361
+ token = ink::compiler::internal::strtok_s(nullptr, ".", &_context);
362
+ }
363
+
364
+ if (noop_offset != ~0) {
365
+ inkAssert(! useCountIndex, "Can't count visits to a noop!");
366
+ _containers.set(position, noop_offset);
367
+ } else {
368
+ // If we want the count index, write that out
369
+ if (useCountIndex) {
370
+ inkAssert(container->counter_index != ~0, "No count index available for this container!");
371
+ _containers.set(position, container->counter_index);
372
+ } else {
373
+ // Otherwise, write container address
374
+ if (container == nullptr) {
375
+ _containers.set(position, 0);
376
+ inkAssert(optional, "Was not able to resolve a not optional path! '%hs'", path.c_str());
377
+ } else {
378
+ _containers.set(position, container->offset);
379
+ }
380
+ }
381
+ }
382
+ }
383
+ }
384
+
385
+ void binary_emitter::write_container_map(
386
+ std::ostream& out, const container_map& map, container_t num
387
+ )
388
+ {
389
+ // Write out container count
390
+ out.write(reinterpret_cast<const char*>(&num), sizeof(container_t));
391
+
392
+ // Write out entries
393
+ for (const auto& pair : map) {
394
+ out.write(( const char* ) &pair.first, sizeof(uint32_t));
395
+ out.write(( const char* ) &pair.second, sizeof(uint32_t));
396
+ }
397
+ }
398
+
399
+ void binary_emitter::write_container_hash_map(std::ostream& out)
400
+ {
401
+ write_container_hash_map(out, "", _root);
402
+ }
403
+
404
+ void binary_emitter::write_container_hash_map(
405
+ std::ostream& out, const std::string& name, const container_data* context
406
+ )
407
+ {
408
+ for (auto child : context->named_children) {
409
+ // Get the child's name in the hierarchy
410
+ std::string child_name = name.empty() ? child.first : (name + "." + child.first);
411
+ hash_t name_hash = hash_string(child_name.c_str());
412
+ // Write out name hash and offset
413
+ out.write(( const char* ) &name_hash, sizeof(hash_t));
414
+ out.write(( const char* ) &child.second->offset, sizeof(uint32_t));
415
+
416
+ // Recurse
417
+ write_container_hash_map(out, child_name, child.second);
418
+ }
419
+
420
+ for (auto child : context->indexed_children) {
421
+ write_container_hash_map(out, name, child.second);
422
+ }
423
+ }
424
+
425
+ void binary_emitter::set_list_meta(const list_data& list_defs)
426
+ {
427
+ if (list_defs.empty()) {
428
+ return;
429
+ }
430
+
431
+ auto flags = list_defs.get_flags();
432
+ auto list_names = list_defs.get_list_names().begin();
433
+ int list_id = -1;
434
+ for (const auto& flag : flags) {
435
+ _lists.write(flag.flag);
436
+ if (flag.flag.list_id != list_id) {
437
+ list_id = flag.flag.list_id;
438
+ _lists.write(reinterpret_cast<const byte_t*>(list_names->data()), list_names->size());
439
+ ++list_names;
440
+ _lists.write('\0');
441
+ }
442
+ _lists.write(reinterpret_cast<const byte_t*>(flag.name->c_str()), flag.name->size() + 1);
443
+ }
444
+ _lists.write(null_flag);
445
+ }
446
+ } // namespace ink::compiler::internal
@@ -0,0 +1,70 @@
1
+ /* Copyright (c) 2024 Julian Benda
2
+ *
3
+ * This file is part of inkCPP which is released under MIT license.
4
+ * See file LICENSE.txt or go to
5
+ * https://github.com/JBenda/inkcpp for full license details.
6
+ */
7
+ #pragma once
8
+
9
+ #include "emitter.h"
10
+ #include "binary_stream.h"
11
+
12
+ namespace ink::compiler::internal
13
+ {
14
+ struct container_data;
15
+ class list_data;
16
+
17
+ // binary emitter
18
+ class binary_emitter : public emitter
19
+ {
20
+ public:
21
+ binary_emitter();
22
+ virtual ~binary_emitter();
23
+
24
+ // Begin emitter
25
+ virtual uint32_t start_container(int index_in_parent, const std::string& name) override;
26
+ virtual uint32_t end_container() override;
27
+ virtual int function_container_arguments(const std::string& name) override;
28
+ virtual void write_raw(Command command, CommandFlag flag = CommandFlag::NO_FLAGS, const char* payload = nullptr, ink::size_t payload_size = 0) override;
29
+ virtual void write_path(Command command, CommandFlag flag, const std::string& path, bool useCountIndex = false) override;
30
+ virtual void write_variable(Command command, CommandFlag flag, const std::string& name) override;
31
+ virtual void write_string(Command command, CommandFlag flag, const std::string& string) override;
32
+ virtual void handle_nop(int index_in_parent) override;
33
+ virtual uint32_t fallthrough_divert() override;
34
+ virtual void patch_fallthroughs(uint32_t position) override;
35
+ virtual void set_list_meta(const list_data& list_defs) override;
36
+ virtual void write_list(Command command, CommandFlag flag, const std::vector<list_flag>& entries) override;
37
+ // End emitter
38
+
39
+ // write out the emitters data
40
+ virtual void output(std::ostream&);
41
+
42
+ protected:
43
+ virtual void initialize() override;
44
+ virtual void finalize() override;
45
+ virtual void setContainerIndex(container_t index) override;
46
+
47
+ private:
48
+ void process_paths();
49
+ void write_container_map(std::ostream&, const container_map&, container_t);
50
+ void write_container_hash_map(std::ostream&);
51
+ void write_container_hash_map(std::ostream&, const std::string&, const container_data*);
52
+
53
+ private:
54
+ container_data* _root;
55
+ container_data* _current;
56
+ compilation_results* _results;
57
+
58
+ binary_stream _strings;
59
+ uint32_t _list_count = 0;
60
+ binary_stream _lists;
61
+ binary_stream _containers;
62
+
63
+ // positon to write address
64
+ // path as string
65
+ // if path may not exists (used for function fallbackes)
66
+ // container data
67
+ // use count index?
68
+ std::vector<std::tuple<size_t, std::string, bool, container_data*, bool>> _paths;
69
+ };
70
+ }
@@ -0,0 +1,166 @@
1
+ /* Copyright (c) 2024 Julian Benda
2
+ *
3
+ * This file is part of inkCPP which is released under MIT license.
4
+ * See file LICENSE.txt or go to
5
+ * https://github.com/JBenda/inkcpp for full license details.
6
+ */
7
+ #include "binary_stream.h"
8
+
9
+ #include <cstring>
10
+
11
+ namespace ink
12
+ {
13
+ namespace compiler
14
+ {
15
+ namespace internal
16
+ {
17
+ template<>
18
+ size_t binary_stream::write(const std::string& value)
19
+ {
20
+ constexpr byte_t ZERO = 0;
21
+ size_t len;
22
+ if(value.length()) {
23
+ len = write((const byte_t*)value.c_str(), value.length());
24
+ } else {
25
+ len = write(' ');
26
+ }
27
+ len += write(ZERO);
28
+ return len;
29
+ }
30
+
31
+ binary_stream::binary_stream()
32
+ : _currentSlab(nullptr)
33
+ , _ptr(nullptr)
34
+ { }
35
+
36
+ binary_stream::~binary_stream()
37
+ {
38
+ reset();
39
+ }
40
+
41
+ size_t binary_stream::write(const byte_t* data, size_t len)
42
+ {
43
+ // Create first slab if none exist
44
+ if (_currentSlab == nullptr)
45
+ {
46
+ _currentSlab = new byte_t[DATA_SIZE];
47
+ _ptr = _currentSlab;
48
+ }
49
+
50
+ // Check how much space we have left
51
+ size_t slab_remaining = _currentSlab + DATA_SIZE - _ptr;
52
+
53
+ // If we're out of space...
54
+ if (slab_remaining < len)
55
+ {
56
+ // Write what we can into the slab
57
+ memcpy(_ptr, data, slab_remaining);
58
+
59
+ // Create a new slab
60
+ _slabs.push_back(_currentSlab);
61
+ _currentSlab = new byte_t[DATA_SIZE];
62
+ _ptr = _currentSlab;
63
+
64
+ // Recurse
65
+ return slab_remaining + write(data + slab_remaining, len - slab_remaining);
66
+ }
67
+
68
+ // We have the space
69
+ memcpy(_ptr, data, len);
70
+ _ptr += len;
71
+ return len;
72
+ }
73
+
74
+ void binary_stream::write_to(std::ostream& out) const
75
+ {
76
+ // Write previous slabs
77
+ for (byte_t* slab : _slabs)
78
+ {
79
+ out.write(reinterpret_cast<const char*>(slab), DATA_SIZE);
80
+ }
81
+
82
+ // Write current slab (if it exists)
83
+ if (_currentSlab != nullptr && _ptr != _currentSlab)
84
+ {
85
+ out.write(reinterpret_cast<const char*>(_currentSlab), _ptr - _currentSlab);
86
+ }
87
+ }
88
+
89
+ size_t binary_stream::pos() const
90
+ {
91
+ // If we have no data, we're at position 0
92
+ if (_currentSlab == nullptr)
93
+ return 0;
94
+
95
+ // Each slabs is size DATA_SIZE then add the position in the current slab
96
+ return _slabs.size() * DATA_SIZE + (_ptr - _currentSlab);
97
+ }
98
+
99
+ void binary_stream::set(size_t offset, const byte_t* data, size_t len)
100
+ {
101
+ // Find slab for offset
102
+ unsigned int slab_index = offset / DATA_SIZE;
103
+ size_t pos = offset % DATA_SIZE;
104
+
105
+ // Get slab and ptr
106
+ byte_t* slab = nullptr;
107
+ if (slab_index < _slabs.size())
108
+ slab = _slabs[slab_index];
109
+ else if (slab_index == _slabs.size())
110
+ slab = _currentSlab;
111
+
112
+ if (slab == nullptr)
113
+ return; // TODO: Error?
114
+
115
+ byte_t* ptr = slab + pos;
116
+
117
+ // Check if data will fit into slab
118
+ if (pos + len > DATA_SIZE)
119
+ {
120
+ // Write only what we can fit
121
+ size_t new_length = DATA_SIZE - pos;
122
+ memcpy(ptr, data, new_length);
123
+
124
+ // Recurse
125
+ set(offset + new_length, data + new_length, len - new_length);
126
+ return;
127
+ }
128
+
129
+ // Otherwise write the whole data
130
+ memcpy(ptr, data, len);
131
+ }
132
+
133
+ byte_t binary_stream::get(size_t offset) const
134
+ {
135
+ // Find slab for offset
136
+ unsigned int slab_index = offset / DATA_SIZE;
137
+ size_t pos = offset % DATA_SIZE;
138
+
139
+ // Get slab and ptr
140
+ byte_t* slab = nullptr;
141
+ if (slab_index < _slabs.size())
142
+ slab = _slabs[slab_index];
143
+ else if (slab_index == _slabs.size())
144
+ slab = _currentSlab;
145
+
146
+ inkAssert(slab != nullptr, "try to access invalid slab in binary stream");
147
+ return slab[pos];
148
+ }
149
+
150
+ void binary_stream::reset()
151
+ {
152
+ // Delete all slabs
153
+ for (byte_t* slab : _slabs)
154
+ {
155
+ delete[] slab;
156
+ }
157
+ _slabs.clear();
158
+
159
+ // Delete active slab (if it exists)
160
+ if (_currentSlab != nullptr)
161
+ delete[] _currentSlab;
162
+ _currentSlab = _ptr = nullptr;
163
+ }
164
+ }
165
+ }
166
+ }