react-native-nitro-xlsx 0.1.4 → 0.2.6

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 (428) hide show
  1. package/NitroXlsx.podspec +27 -27
  2. package/Package.swift +35 -10
  3. package/README.md +220 -58
  4. package/android/CMakeLists.txt +24 -27
  5. package/android/cpp-adapter.cpp +12 -0
  6. package/android/src/main/java/com/margelo/nitro/xlsx/NitroXlsxPackage.kt +9 -0
  7. package/cpp/HybridNitroXlsx.cpp +25 -179
  8. package/cpp/HybridNitroXlsx.hpp +2 -2
  9. package/cpp/HybridXlsxConditionalFormat.cpp +252 -0
  10. package/cpp/HybridXlsxConditionalFormat.hpp +62 -0
  11. package/cpp/HybridXlsxConditionalFormats.cpp +46 -0
  12. package/cpp/HybridXlsxConditionalFormats.hpp +28 -0
  13. package/cpp/HybridXlsxWorkbook.cpp +159 -196
  14. package/cpp/HybridXlsxWorkbook.hpp +7 -2
  15. package/cpp/HybridXlsxWorksheet.cpp +433 -62
  16. package/cpp/HybridXlsxWorksheet.hpp +73 -26
  17. package/cpp/XlsxCacheDir.cpp +76 -0
  18. package/cpp/XlsxCacheDir.hpp +27 -0
  19. package/cpp/XlsxError.hpp +68 -0
  20. package/cpp/XlsxJson.cpp +185 -0
  21. package/cpp/XlsxJson.hpp +36 -0
  22. package/ios/XlsxCacheDir.mm +60 -0
  23. package/nitrogen/generated/android/NitroXlsx+autolinking.cmake +2 -0
  24. package/nitrogen/generated/shared/c++/HybridNitroXlsxSpec.hpp +5 -3
  25. package/nitrogen/generated/shared/c++/HybridXlsxConditionalFormatSpec.cpp +54 -0
  26. package/nitrogen/generated/shared/c++/HybridXlsxConditionalFormatSpec.hpp +95 -0
  27. package/nitrogen/generated/shared/c++/HybridXlsxConditionalFormatsSpec.cpp +24 -0
  28. package/nitrogen/generated/shared/c++/HybridXlsxConditionalFormatsSpec.hpp +68 -0
  29. package/nitrogen/generated/shared/c++/HybridXlsxWorkbookSpec.cpp +3 -0
  30. package/nitrogen/generated/shared/c++/HybridXlsxWorkbookSpec.hpp +6 -1
  31. package/nitrogen/generated/shared/c++/HybridXlsxWorksheetSpec.cpp +47 -19
  32. package/nitrogen/generated/shared/c++/HybridXlsxWorksheetSpec.hpp +52 -20
  33. package/package.json +3 -3
  34. package/scripts/run-cpp-tests.sh +14 -0
  35. package/src/__mocks__/react-native-nitro-modules.ts +1 -0
  36. package/src/__tests__/index.test.ts +76 -7
  37. package/src/index.ts +107 -18
  38. package/src/specs/NitroXlsx.nitro.ts +141 -44
  39. package/thirdparty/OpenXLSX/.clang-format +118 -0
  40. package/thirdparty/OpenXLSX/.clang-tidy +28 -0
  41. package/thirdparty/OpenXLSX/.gitignore +130 -0
  42. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_before_XMLNode_wrappers +46 -0
  43. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_and_stripping +49 -0
  44. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_char_support +49 -0
  45. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_support +49 -0
  46. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespaced_name_disabled +49 -0
  47. package/thirdparty/OpenXLSX/Benchmarks/2024-08-11-benchmarks_post-XLCellIterator-Rework +46 -0
  48. package/thirdparty/OpenXLSX/Benchmarks/2024-08-14-benchmarks_post-default-row-column-style-support +46 -0
  49. package/thirdparty/OpenXLSX/Benchmarks/2024-09-02-benchmarks +46 -0
  50. package/thirdparty/OpenXLSX/Benchmarks/2024-12-19-benchmarks +46 -0
  51. package/thirdparty/OpenXLSX/Benchmarks/2024-12-30-benchmarks-post-XLSharedStrings-by-ref +46 -0
  52. package/thirdparty/OpenXLSX/Benchmarks/2025-01-09-benchmarks-post-conditionalFormatsAndSheetProtection +46 -0
  53. package/thirdparty/OpenXLSX/Benchmarks/2025-01-10-benchmarks-post-XLCellValue-bugfix +46 -0
  54. package/thirdparty/OpenXLSX/Benchmarks/2025-01-31-benchmarks-post-XLComments-implementation +46 -0
  55. package/thirdparty/OpenXLSX/Benchmarks/2025-02-02-benchmarks-post-XLRowIterator-Rework +46 -0
  56. package/thirdparty/OpenXLSX/Benchmarks/2025-07-20-benchmarks-after-hiding-pugixml-internals +46 -0
  57. package/thirdparty/OpenXLSX/Benchmarks/2025-08-29-benchmarks-after-code-review-with-libzip +46 -0
  58. package/thirdparty/OpenXLSX/Benchmarks/Benchmark.cpp +249 -0
  59. package/thirdparty/OpenXLSX/Benchmarks/CMakeLists.txt +19 -0
  60. package/thirdparty/OpenXLSX/CMakeLists.txt +466 -0
  61. package/thirdparty/OpenXLSX/Documentation/CMakeLists.txt +31 -0
  62. package/thirdparty/OpenXLSX/Documentation/Doxyfile.in +2471 -0
  63. package/thirdparty/OpenXLSX/Documentation/DoxygenLayout.xml +194 -0
  64. package/thirdparty/OpenXLSX/Documentation/customdoxygen.css +1355 -0
  65. package/thirdparty/OpenXLSX/Examples/CMakeLists.txt +103 -0
  66. package/thirdparty/OpenXLSX/Examples/Demo1.cpp +279 -0
  67. package/thirdparty/OpenXLSX/Examples/Demo10.cpp +545 -0
  68. package/thirdparty/OpenXLSX/Examples/Demo1A.cpp +137 -0
  69. package/thirdparty/OpenXLSX/Examples/Demo2.cpp +65 -0
  70. package/thirdparty/OpenXLSX/Examples/Demo3.cpp +89 -0
  71. package/thirdparty/OpenXLSX/Examples/Demo4.cpp +86 -0
  72. package/thirdparty/OpenXLSX/Examples/Demo5.cpp +77 -0
  73. package/thirdparty/OpenXLSX/Examples/Demo6.cpp +103 -0
  74. package/thirdparty/OpenXLSX/Examples/Demo7.cpp +79 -0
  75. package/thirdparty/OpenXLSX/Examples/Demo8.cpp +117 -0
  76. package/thirdparty/OpenXLSX/Examples/Demo9.cpp +363 -0
  77. package/thirdparty/OpenXLSX/Examples/cmake/FindLIBZIP.cmake +61 -0
  78. package/thirdparty/OpenXLSX/Examples/external/CustomZip/CustomZip.hpp +256 -0
  79. package/thirdparty/OpenXLSX/LICENSE.md +29 -0
  80. package/thirdparty/OpenXLSX/Makefile.GNU +530 -0
  81. package/thirdparty/OpenXLSX/Notes/TBDs.txt +16 -0
  82. package/thirdparty/OpenXLSX/Notes/confirmed-TBCs.txt +8 -0
  83. package/thirdparty/OpenXLSX/Notes/styles-missing-support.xml +12 -0
  84. package/thirdparty/OpenXLSX/Notes/todo-list.txt +108 -0
  85. package/thirdparty/OpenXLSX/OpenXLSX/CMakeLists.txt +631 -0
  86. package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSX.hpp +63 -0
  87. package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSXConfig.cmake +11 -0
  88. package/thirdparty/OpenXLSX/OpenXLSX/cmake/bundle_static_library.cmake +198 -0
  89. package/thirdparty/OpenXLSX/OpenXLSX/cmake/patch_pkg_config.cmake +69 -0
  90. package/thirdparty/OpenXLSX/OpenXLSX/headers/IZipArchive.hpp +361 -0
  91. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX-Exports.hpp +12 -0
  92. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCell.hpp +367 -0
  93. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellIterator.hpp +252 -0
  94. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellRange.hpp +223 -0
  95. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellReference.hpp +317 -0
  96. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellValue.hpp +793 -0
  97. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColor.hpp +232 -0
  98. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColumn.hpp +159 -0
  99. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCommandQuery.hpp +228 -0
  100. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLComments.hpp +270 -0
  101. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLConstants.hpp +18 -0
  102. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLContentTypes.hpp +264 -0
  103. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDateTime.hpp +175 -0
  104. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDocument.hpp +505 -0
  105. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDrawing.hpp +452 -0
  106. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLException.hpp +161 -0
  107. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLFormula.hpp +375 -0
  108. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLIterator.hpp +40 -0
  109. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLMergeCells.hpp +216 -0
  110. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLProperties.hpp +348 -0
  111. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRelationships.hpp +348 -0
  112. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRow.hpp +721 -0
  113. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRowData.hpp +488 -0
  114. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSharedStrings.hpp +204 -0
  115. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSheet.hpp +1640 -0
  116. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLStyles.hpp +2390 -0
  117. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLTables.hpp +132 -0
  118. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLWorkbook.hpp +404 -0
  119. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlData.hpp +283 -0
  120. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlFile.hpp +194 -0
  121. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParser.hpp +282 -0
  122. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParserForwardDeclarations.hpp +85 -0
  123. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLZipArchive.hpp +232 -0
  124. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/LibZip.hpp +447 -0
  125. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/OpenXLSXFileSystemTools.hpp +207 -0
  126. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/Zippy.hpp +1375 -0
  127. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCell.cpp +340 -0
  128. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellIterator.cpp +427 -0
  129. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellRange.cpp +221 -0
  130. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellReference.cpp +408 -0
  131. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellValue.cpp +519 -0
  132. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColor.cpp +202 -0
  133. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColumn.cpp +141 -0
  134. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLComments.cpp +637 -0
  135. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLContentTypes.cpp +329 -0
  136. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDateTime.cpp +269 -0
  137. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDocument.cpp +1678 -0
  138. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDrawing.cpp +784 -0
  139. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLFormula.cpp +201 -0
  140. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLMergeCells.cpp +357 -0
  141. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLProperties.cpp +810 -0
  142. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRelationships.cpp +529 -0
  143. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRow.cpp +918 -0
  144. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRowData.cpp +508 -0
  145. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSharedStrings.cpp +220 -0
  146. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSheet.cpp +1970 -0
  147. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLStyles.cpp +3014 -0
  148. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLTables.cpp +125 -0
  149. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLWorkbook.cpp +784 -0
  150. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlData.cpp +247 -0
  151. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlFile.cpp +160 -0
  152. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlParser.cpp +261 -0
  153. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLZipArchive.cpp +266 -0
  154. package/thirdparty/OpenXLSX/OpenXLSX/sources/utilities/XLUtilities.hpp +478 -0
  155. package/thirdparty/OpenXLSX/README.md +1279 -0
  156. package/thirdparty/OpenXLSX/Scripts/cmake-cleanup.sh +102 -0
  157. package/thirdparty/OpenXLSX/Scripts/compile.sh +23 -0
  158. package/thirdparty/OpenXLSX/Scripts/demos-cleanup.sh +25 -0
  159. package/thirdparty/OpenXLSX/Scripts/demos-run-all.sh +60 -0
  160. package/thirdparty/OpenXLSX/Scripts/guarded-xml-format.sh +47 -0
  161. package/thirdparty/OpenXLSX/Scripts/make-gnu.sh +11 -0
  162. package/thirdparty/OpenXLSX/Scripts/uninstall-manifest.sh +48 -0
  163. package/thirdparty/OpenXLSX/Scripts/xml-format-all.sh +19 -0
  164. package/thirdparty/OpenXLSX/Scripts/xml-format.sh +38 -0
  165. package/thirdparty/OpenXLSX/Tests/CMakeLists.txt +37 -0
  166. package/thirdparty/OpenXLSX/Tests/catch/catch.hpp +17799 -0
  167. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_automake.hpp +68 -0
  168. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_sonarqube.hpp +182 -0
  169. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_tap.hpp +278 -0
  170. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_teamcity.hpp +212 -0
  171. package/thirdparty/OpenXLSX/Tests/main.cpp +55 -0
  172. package/thirdparty/OpenXLSX/Tests/testXLCell.cpp +176 -0
  173. package/thirdparty/OpenXLSX/Tests/testXLCellRange.cpp +180 -0
  174. package/thirdparty/OpenXLSX/Tests/testXLCellReference.cpp +160 -0
  175. package/thirdparty/OpenXLSX/Tests/testXLCellValue.cpp +366 -0
  176. package/thirdparty/OpenXLSX/Tests/testXLCellValueProxy.cpp +255 -0
  177. package/thirdparty/OpenXLSX/Tests/testXLColor.cpp +75 -0
  178. package/thirdparty/OpenXLSX/Tests/testXLDateTime.cpp +229 -0
  179. package/thirdparty/OpenXLSX/Tests/testXLDocument.cpp +197 -0
  180. package/thirdparty/OpenXLSX/Tests/testXLFormula.cpp +131 -0
  181. package/thirdparty/OpenXLSX/Tests/testXLRow.cpp +597 -0
  182. package/thirdparty/OpenXLSX/Tests/testXLSheet.cpp +77 -0
  183. package/thirdparty/OpenXLSX/Tests/ziptest-with-libs.cpp +88 -0
  184. package/thirdparty/OpenXLSX/Tests/ziptest.cpp +735 -0
  185. package/thirdparty/OpenXLSX/cmake/get-git-HEAD-ID.cmake +45 -0
  186. package/thirdparty/OpenXLSX/cmake/libopenxlsxCPackOptions.cmake.in +20 -0
  187. package/thirdparty/OpenXLSX/cmake/manage_dependency.cmake +813 -0
  188. package/thirdparty/OpenXLSX/cmake/recursive_library_type_test.cmake +52 -0
  189. package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-shared.hpp +42 -0
  190. package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-static.hpp +42 -0
  191. package/thirdparty/OpenXLSX/vcpkg.json +24 -0
  192. package/thirdparty/README.md +42 -0
  193. package/thirdparty/miniz/.clang-format +47 -0
  194. package/thirdparty/miniz/.travis.yml +2 -0
  195. package/thirdparty/miniz/CMakeLists.txt +333 -0
  196. package/thirdparty/miniz/CMakePresets.json +31 -0
  197. package/thirdparty/miniz/ChangeLog.md +272 -0
  198. package/thirdparty/miniz/Config.cmake.in +1 -0
  199. package/thirdparty/miniz/LICENSE +22 -0
  200. package/thirdparty/miniz/amalgamate.sh +57 -0
  201. package/thirdparty/miniz/examples/example1.c +105 -0
  202. package/thirdparty/miniz/examples/example2.c +164 -0
  203. package/thirdparty/miniz/examples/example3.c +269 -0
  204. package/thirdparty/miniz/examples/example4.c +102 -0
  205. package/thirdparty/miniz/examples/example5.c +327 -0
  206. package/thirdparty/miniz/examples/example6.c +189 -0
  207. package/thirdparty/miniz/meson.build +21 -0
  208. package/thirdparty/miniz/miniz.c +646 -0
  209. package/thirdparty/miniz/miniz.h +615 -0
  210. package/thirdparty/miniz/miniz.pc.in +13 -0
  211. package/thirdparty/miniz/miniz_common.h +89 -0
  212. package/thirdparty/miniz/miniz_export.h +20 -0
  213. package/thirdparty/miniz/miniz_tdef.c +1602 -0
  214. package/thirdparty/miniz/miniz_tdef.h +199 -0
  215. package/thirdparty/miniz/miniz_tinfl.c +778 -0
  216. package/thirdparty/miniz/miniz_tinfl.h +150 -0
  217. package/thirdparty/miniz/miniz_zip.c +4895 -0
  218. package/thirdparty/miniz/miniz_zip.h +454 -0
  219. package/thirdparty/miniz/readme.md +46 -0
  220. package/thirdparty/miniz/test.sh +36 -0
  221. package/thirdparty/miniz/tests/add_in_place_fuzzer.c +87 -0
  222. package/thirdparty/miniz/tests/catch_amalgamated.cpp +10795 -0
  223. package/thirdparty/miniz/tests/catch_amalgamated.hpp +13143 -0
  224. package/thirdparty/miniz/tests/checksum_fuzzer.c +26 -0
  225. package/thirdparty/miniz/tests/compress_fuzzer.c +91 -0
  226. package/thirdparty/miniz/tests/flush_fuzzer.c +88 -0
  227. package/thirdparty/miniz/tests/fuzz_main.c +55 -0
  228. package/thirdparty/miniz/tests/large_fuzzer.c +133 -0
  229. package/thirdparty/miniz/tests/main.cpp +185 -0
  230. package/thirdparty/miniz/tests/miniz_tdefl_fuzzer.cc +115 -0
  231. package/thirdparty/miniz/tests/miniz_tester.cpp +1881 -0
  232. package/thirdparty/miniz/tests/miniz_zip_validate_fuzzer.cc +71 -0
  233. package/thirdparty/miniz/tests/miniz_zip_writer_fuzzer.cc +96 -0
  234. package/thirdparty/miniz/tests/ossfuzz.sh +48 -0
  235. package/thirdparty/miniz/tests/small_fuzzer.c +126 -0
  236. package/thirdparty/miniz/tests/timer.cpp +152 -0
  237. package/thirdparty/miniz/tests/timer.h +40 -0
  238. package/thirdparty/miniz/tests/uncompress2_fuzzer.c +21 -0
  239. package/thirdparty/miniz/tests/uncompress_fuzzer.c +30 -0
  240. package/thirdparty/miniz/tests/zip.dict +9 -0
  241. package/thirdparty/miniz/tests/zip_fuzzer.c +63 -0
  242. package/thirdparty/pugixml/.codecov.yml +7 -0
  243. package/thirdparty/pugixml/.gitattributes +1 -0
  244. package/thirdparty/pugixml/CMakeLists.txt +330 -0
  245. package/thirdparty/pugixml/LICENSE.md +24 -0
  246. package/thirdparty/pugixml/Makefile +98 -0
  247. package/thirdparty/pugixml/README.md +81 -0
  248. package/thirdparty/pugixml/SECURITY.md +9 -0
  249. package/thirdparty/pugixml/appveyor.yml +50 -0
  250. package/thirdparty/pugixml/docs/config.adoc +7 -0
  251. package/thirdparty/pugixml/docs/images/dom_tree.png +0 -0
  252. package/thirdparty/pugixml/docs/images/vs2005_link1.png +0 -0
  253. package/thirdparty/pugixml/docs/images/vs2005_link2.png +0 -0
  254. package/thirdparty/pugixml/docs/images/vs2005_pch1.png +0 -0
  255. package/thirdparty/pugixml/docs/images/vs2005_pch2.png +0 -0
  256. package/thirdparty/pugixml/docs/images/vs2005_pch3.png +0 -0
  257. package/thirdparty/pugixml/docs/images/vs2005_pch4.png +0 -0
  258. package/thirdparty/pugixml/docs/images/vs2010_link1.png +0 -0
  259. package/thirdparty/pugixml/docs/images/vs2010_link2.png +0 -0
  260. package/thirdparty/pugixml/docs/manual.adoc +3326 -0
  261. package/thirdparty/pugixml/docs/manual.html +6395 -0
  262. package/thirdparty/pugixml/docs/quickstart.adoc +287 -0
  263. package/thirdparty/pugixml/docs/quickstart.html +1107 -0
  264. package/thirdparty/pugixml/docs/samples/character.xml +8 -0
  265. package/thirdparty/pugixml/docs/samples/custom_memory_management.cpp +27 -0
  266. package/thirdparty/pugixml/docs/samples/include.cpp +64 -0
  267. package/thirdparty/pugixml/docs/samples/load_error_handling.cpp +33 -0
  268. package/thirdparty/pugixml/docs/samples/load_file.cpp +16 -0
  269. package/thirdparty/pugixml/docs/samples/load_memory.cpp +66 -0
  270. package/thirdparty/pugixml/docs/samples/load_options.cpp +30 -0
  271. package/thirdparty/pugixml/docs/samples/load_stream.cpp +97 -0
  272. package/thirdparty/pugixml/docs/samples/modify_add.cpp +29 -0
  273. package/thirdparty/pugixml/docs/samples/modify_base.cpp +43 -0
  274. package/thirdparty/pugixml/docs/samples/modify_remove.cpp +27 -0
  275. package/thirdparty/pugixml/docs/samples/save_custom_writer.cpp +116 -0
  276. package/thirdparty/pugixml/docs/samples/save_declaration.cpp +27 -0
  277. package/thirdparty/pugixml/docs/samples/save_file.cpp +17 -0
  278. package/thirdparty/pugixml/docs/samples/save_options.cpp +48 -0
  279. package/thirdparty/pugixml/docs/samples/save_stream.cpp +18 -0
  280. package/thirdparty/pugixml/docs/samples/save_subtree.cpp +26 -0
  281. package/thirdparty/pugixml/docs/samples/text.cpp +35 -0
  282. package/thirdparty/pugixml/docs/samples/transitions.xml +7 -0
  283. package/thirdparty/pugixml/docs/samples/traverse_base.cpp +51 -0
  284. package/thirdparty/pugixml/docs/samples/traverse_iter.cpp +27 -0
  285. package/thirdparty/pugixml/docs/samples/traverse_predicate.cpp +48 -0
  286. package/thirdparty/pugixml/docs/samples/traverse_rangefor.cpp +32 -0
  287. package/thirdparty/pugixml/docs/samples/traverse_walker.cpp +35 -0
  288. package/thirdparty/pugixml/docs/samples/tree.xml +12 -0
  289. package/thirdparty/pugixml/docs/samples/weekly-shift_jis.xml +78 -0
  290. package/thirdparty/pugixml/docs/samples/weekly-utf-16.xml +0 -0
  291. package/thirdparty/pugixml/docs/samples/weekly-utf-8.xml +78 -0
  292. package/thirdparty/pugixml/docs/samples/xgconsole.xml +12 -0
  293. package/thirdparty/pugixml/docs/samples/xpath_error.cpp +43 -0
  294. package/thirdparty/pugixml/docs/samples/xpath_query.cpp +36 -0
  295. package/thirdparty/pugixml/docs/samples/xpath_select.cpp +28 -0
  296. package/thirdparty/pugixml/docs/samples/xpath_variables.cpp +38 -0
  297. package/thirdparty/pugixml/readme.txt +50 -0
  298. package/thirdparty/pugixml/scripts/archive.py +54 -0
  299. package/thirdparty/pugixml/scripts/cocoapods_push.sh +4 -0
  300. package/thirdparty/pugixml/scripts/natvis/pugixml.natvis +77 -0
  301. package/thirdparty/pugixml/scripts/natvis/pugixml_compact.natvis +506 -0
  302. package/thirdparty/pugixml/scripts/nuget/build/native/pugixml-propertiesui.xml +17 -0
  303. package/thirdparty/pugixml/scripts/nuget/build/native/pugixml.targets +28 -0
  304. package/thirdparty/pugixml/scripts/nuget/pugixml.nuspec +20 -0
  305. package/thirdparty/pugixml/scripts/nuget_build.ps1 +60 -0
  306. package/thirdparty/pugixml/scripts/premake4.lua +92 -0
  307. package/thirdparty/pugixml/scripts/pugixml-config.cmake.in +12 -0
  308. package/thirdparty/pugixml/scripts/pugixml.pc.in +11 -0
  309. package/thirdparty/pugixml/scripts/pugixml.podspec +14 -0
  310. package/thirdparty/pugixml/scripts/pugixml.xcodeproj/project.pbxproj +212 -0
  311. package/thirdparty/pugixml/scripts/pugixml_airplay.mkf +13 -0
  312. package/thirdparty/pugixml/scripts/pugixml_codeblocks.cbp +44 -0
  313. package/thirdparty/pugixml/scripts/pugixml_codelite.project +56 -0
  314. package/thirdparty/pugixml/scripts/pugixml_dll.rc +45 -0
  315. package/thirdparty/pugixml/scripts/pugixml_vs2005.vcproj +343 -0
  316. package/thirdparty/pugixml/scripts/pugixml_vs2005_static.vcproj +343 -0
  317. package/thirdparty/pugixml/scripts/pugixml_vs2008.vcproj +339 -0
  318. package/thirdparty/pugixml/scripts/pugixml_vs2008_static.vcproj +339 -0
  319. package/thirdparty/pugixml/scripts/pugixml_vs2010.vcxproj +191 -0
  320. package/thirdparty/pugixml/scripts/pugixml_vs2010_static.vcxproj +191 -0
  321. package/thirdparty/pugixml/scripts/pugixml_vs2013.vcxproj +199 -0
  322. package/thirdparty/pugixml/scripts/pugixml_vs2013_static.vcxproj +199 -0
  323. package/thirdparty/pugixml/scripts/pugixml_vs2015.vcxproj +172 -0
  324. package/thirdparty/pugixml/scripts/pugixml_vs2015_static.vcxproj +176 -0
  325. package/thirdparty/pugixml/scripts/pugixml_vs2017.vcxproj +172 -0
  326. package/thirdparty/pugixml/scripts/pugixml_vs2017_static.vcxproj +176 -0
  327. package/thirdparty/pugixml/scripts/pugixml_vs2019.vcxproj +176 -0
  328. package/thirdparty/pugixml/scripts/pugixml_vs2019_static.vcxproj +180 -0
  329. package/thirdparty/pugixml/scripts/pugixml_vs2022.vcxproj +176 -0
  330. package/thirdparty/pugixml/scripts/pugixml_vs2022_static.vcxproj +180 -0
  331. package/thirdparty/pugixml/scripts/pugixml_vs2026.vcxproj +176 -0
  332. package/thirdparty/pugixml/scripts/pugixml_vs2026_static.vcxproj +180 -0
  333. package/thirdparty/pugixml/scripts/sbom.cdx.json +47 -0
  334. package/thirdparty/pugixml/src/pugiconfig.hpp +81 -0
  335. package/thirdparty/pugixml/src/pugixml.cpp +13776 -0
  336. package/thirdparty/pugixml/src/pugixml.hpp +1604 -0
  337. package/thirdparty/pugixml/tests/allocator.cpp +175 -0
  338. package/thirdparty/pugixml/tests/allocator.hpp +10 -0
  339. package/thirdparty/pugixml/tests/autotest-appveyor.ps1 +93 -0
  340. package/thirdparty/pugixml/tests/cmake-appveyor.ps1 +57 -0
  341. package/thirdparty/pugixml/tests/data/empty.xml +0 -0
  342. package/thirdparty/pugixml/tests/data/large.xml +1 -0
  343. package/thirdparty/pugixml/tests/data/latintest_latin1.xml +1 -0
  344. package/thirdparty/pugixml/tests/data/latintest_utf8.xml +1 -0
  345. package/thirdparty/pugixml/tests/data/multiline.xml +3 -0
  346. package/thirdparty/pugixml/tests/data/small.xml +1 -0
  347. package/thirdparty/pugixml/tests/data/truncation.xml +19 -0
  348. package/thirdparty/pugixml/tests/data/utftest_utf16_be.xml +0 -0
  349. package/thirdparty/pugixml/tests/data/utftest_utf16_be_bom.xml +0 -0
  350. package/thirdparty/pugixml/tests/data/utftest_utf16_be_clean.xml +0 -0
  351. package/thirdparty/pugixml/tests/data/utftest_utf16_be_nodecl.xml +0 -0
  352. package/thirdparty/pugixml/tests/data/utftest_utf16_le.xml +0 -0
  353. package/thirdparty/pugixml/tests/data/utftest_utf16_le_bom.xml +0 -0
  354. package/thirdparty/pugixml/tests/data/utftest_utf16_le_clean.xml +0 -0
  355. package/thirdparty/pugixml/tests/data/utftest_utf16_le_nodecl.xml +0 -0
  356. package/thirdparty/pugixml/tests/data/utftest_utf32_be.xml +0 -0
  357. package/thirdparty/pugixml/tests/data/utftest_utf32_be_bom.xml +0 -0
  358. package/thirdparty/pugixml/tests/data/utftest_utf32_be_clean.xml +0 -0
  359. package/thirdparty/pugixml/tests/data/utftest_utf32_be_nodecl.xml +0 -0
  360. package/thirdparty/pugixml/tests/data/utftest_utf32_le.xml +0 -0
  361. package/thirdparty/pugixml/tests/data/utftest_utf32_le_bom.xml +0 -0
  362. package/thirdparty/pugixml/tests/data/utftest_utf32_le_clean.xml +0 -0
  363. package/thirdparty/pugixml/tests/data/utftest_utf32_le_nodecl.xml +0 -0
  364. package/thirdparty/pugixml/tests/data/utftest_utf8.xml +87 -0
  365. package/thirdparty/pugixml/tests/data/utftest_utf8_bom.xml +87 -0
  366. package/thirdparty/pugixml/tests/data/utftest_utf8_clean.xml +84 -0
  367. package/thirdparty/pugixml/tests/data/utftest_utf8_nodecl.xml +86 -0
  368. package/thirdparty/pugixml/tests/data//321/202/320/265/321/201/321/202.xml +1 -0
  369. package/thirdparty/pugixml/tests/data_fuzz_parse/basic.xml +1 -0
  370. package/thirdparty/pugixml/tests/data_fuzz_parse/doctype.xml +1 -0
  371. package/thirdparty/pugixml/tests/data_fuzz_parse/refs.xml +1 -0
  372. package/thirdparty/pugixml/tests/data_fuzz_parse/types.xml +1 -0
  373. package/thirdparty/pugixml/tests/data_fuzz_parse/utf16.xml +0 -0
  374. package/thirdparty/pugixml/tests/data_fuzz_parse/utf32.xml +0 -0
  375. package/thirdparty/pugixml/tests/data_fuzz_xpath/basic.xpath +1 -0
  376. package/thirdparty/pugixml/tests/data_fuzz_xpath/functions.xpath +1 -0
  377. package/thirdparty/pugixml/tests/data_fuzz_xpath/math.xpath +1 -0
  378. package/thirdparty/pugixml/tests/data_fuzz_xpath/path.xpath +1 -0
  379. package/thirdparty/pugixml/tests/data_fuzz_xpath/predicate.xpath +1 -0
  380. package/thirdparty/pugixml/tests/fuzz_parse.cpp +14 -0
  381. package/thirdparty/pugixml/tests/fuzz_parse.dict +72 -0
  382. package/thirdparty/pugixml/tests/fuzz_setup.sh +11 -0
  383. package/thirdparty/pugixml/tests/fuzz_xpath.cpp +46 -0
  384. package/thirdparty/pugixml/tests/fuzz_xpath.dict +72 -0
  385. package/thirdparty/pugixml/tests/helpers.hpp +114 -0
  386. package/thirdparty/pugixml/tests/main.cpp +218 -0
  387. package/thirdparty/pugixml/tests/test.cpp +220 -0
  388. package/thirdparty/pugixml/tests/test.hpp +175 -0
  389. package/thirdparty/pugixml/tests/test_compact.cpp +150 -0
  390. package/thirdparty/pugixml/tests/test_deprecated.cpp +25 -0
  391. package/thirdparty/pugixml/tests/test_document.cpp +1910 -0
  392. package/thirdparty/pugixml/tests/test_dom_modify.cpp +2122 -0
  393. package/thirdparty/pugixml/tests/test_dom_text.cpp +601 -0
  394. package/thirdparty/pugixml/tests/test_dom_traverse.cpp +1481 -0
  395. package/thirdparty/pugixml/tests/test_header_guard.cpp +3 -0
  396. package/thirdparty/pugixml/tests/test_header_iosfwd_1.cpp +3 -0
  397. package/thirdparty/pugixml/tests/test_header_iosfwd_2.cpp +3 -0
  398. package/thirdparty/pugixml/tests/test_header_iostream_1.cpp +3 -0
  399. package/thirdparty/pugixml/tests/test_header_iostream_2.cpp +3 -0
  400. package/thirdparty/pugixml/tests/test_header_only_1.cpp +21 -0
  401. package/thirdparty/pugixml/tests/test_header_only_2.cpp +21 -0
  402. package/thirdparty/pugixml/tests/test_header_string_1.cpp +3 -0
  403. package/thirdparty/pugixml/tests/test_header_string_2.cpp +3 -0
  404. package/thirdparty/pugixml/tests/test_header_string_iostream.cpp +5 -0
  405. package/thirdparty/pugixml/tests/test_memory.cpp +303 -0
  406. package/thirdparty/pugixml/tests/test_parse.cpp +1463 -0
  407. package/thirdparty/pugixml/tests/test_parse_doctype.cpp +366 -0
  408. package/thirdparty/pugixml/tests/test_unicode.cpp +152 -0
  409. package/thirdparty/pugixml/tests/test_version.cpp +5 -0
  410. package/thirdparty/pugixml/tests/test_write.cpp +757 -0
  411. package/thirdparty/pugixml/tests/test_xpath.cpp +833 -0
  412. package/thirdparty/pugixml/tests/test_xpath_api.cpp +646 -0
  413. package/thirdparty/pugixml/tests/test_xpath_functions.cpp +844 -0
  414. package/thirdparty/pugixml/tests/test_xpath_operators.cpp +566 -0
  415. package/thirdparty/pugixml/tests/test_xpath_parse.cpp +428 -0
  416. package/thirdparty/pugixml/tests/test_xpath_paths.cpp +787 -0
  417. package/thirdparty/pugixml/tests/test_xpath_paths_abbrev_w3c.cpp +219 -0
  418. package/thirdparty/pugixml/tests/test_xpath_paths_w3c.cpp +312 -0
  419. package/thirdparty/pugixml/tests/test_xpath_variables.cpp +683 -0
  420. package/thirdparty/pugixml/tests/test_xpath_xalan_1.cpp +411 -0
  421. package/thirdparty/pugixml/tests/test_xpath_xalan_2.cpp +417 -0
  422. package/thirdparty/pugixml/tests/test_xpath_xalan_3.cpp +321 -0
  423. package/thirdparty/pugixml/tests/test_xpath_xalan_4.cpp +300 -0
  424. package/thirdparty/pugixml/tests/test_xpath_xalan_5.cpp +295 -0
  425. package/thirdparty/pugixml/tests/writer_string.cpp +79 -0
  426. package/thirdparty/pugixml/tests/writer_string.hpp +27 -0
  427. package/ios/dummy.swift +0 -2
  428. package/scripts/prepare-openxlsx.js +0 -109
@@ -0,0 +1,735 @@
1
+ /*
2
+ * Program: ziptest
3
+ * Compile instructions: g++ ziptest.cpp -lzip -o ziptest
4
+ * Part of: OpenXLSX
5
+ *
6
+ * OpenXLSX Copyright (c) 2018, Kenneth Troldal Balslev
7
+ * ziptest Copyright 2025 Lars Uffmann <coding23@uffmann.name>
8
+ *
9
+ * --- NOTE: The below license is not applicable to namespace OpenXLSX! ---
10
+ *
11
+ * Licensed under the Apache License, Version 2.0 (the "License");
12
+ * you may not use this file except in compliance with the License.
13
+ * You may obtain a copy of the License at
14
+ *
15
+ * http://www.apache.org/licenses/LICENSE-2.0
16
+ *
17
+ * Unless required by applicable law or agreed to in writing, software
18
+ * distributed under the License is distributed on an "AS IS" BASIS,
19
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ * See the License for the specific language governing permissions and
21
+ * limitations under the License.
22
+ */
23
+ /*!
24
+ * @program ziptest
25
+ * @depends libzip
26
+ * @version 2025-04-27 16:45 CEST
27
+ * @brief provide a wrapper API for libzip to interface with OpenXLSX XLZipArchive
28
+ * @disclaimer This module is in a draft stage, to be reviewed / tested
29
+ */
30
+ #include <cstdio> // fprintf
31
+ #include <filesystem> // std::filesystem::remove, std::filesystem::rename
32
+ #include <iostream> // std::cout / std::cerr
33
+ #include <memory> // std::shared_ptr
34
+ #include <random> // std::random_device, std::mt19937, std::uniform_int_distribution
35
+ #include <string> // std::string
36
+ #include <string.h> // stderror
37
+ #include <sys/stat.h> // stat, struct stat
38
+
39
+ #define USE_LIBZIP // default will be to use zippy
40
+
41
+ #ifdef USE_LIBZIP
42
+ #include <zip.h> // libzip API
43
+ #define XLZipImplementation LibZip::ZipArchive
44
+ #else
45
+ #define XLZipImplementation Zippy::ZipArchive
46
+ #endif
47
+
48
+ #define OPENXLSX_EXPORT
49
+
50
+ namespace OpenXLSX {
51
+ /**
52
+ * @brief
53
+ */
54
+ class OPENXLSX_EXPORT XLException : public std::runtime_error
55
+ {
56
+ public:
57
+ explicit XLException(const std::string& err) : runtime_error(err) {};
58
+ };
59
+
60
+ /**
61
+ * @brief
62
+ */
63
+ class OPENXLSX_EXPORT XLInputError : public XLException
64
+ {
65
+ public:
66
+ explicit XLInputError(const std::string& err) : XLException(err) {};
67
+ };
68
+
69
+ /**
70
+ * @brief
71
+ */
72
+ class OPENXLSX_EXPORT XLInternalError : public XLException
73
+ {
74
+ public:
75
+ explicit XLInternalError(const std::string& err) : XLException(err) {};
76
+ };
77
+ } // namespace OpenXLSX
78
+
79
+
80
+ namespace LibZip {
81
+ using OpenXLSX::XLInputError, OpenXLSX::XLInternalError;
82
+
83
+ /**
84
+ * @brief Generates a random filename, which is used to generate a temporary archive when modifying and saving
85
+ * archive files.
86
+ * @param length The length of the filename to create.
87
+ * @return Returns the generated filenamen, appended with '.tmp'.
88
+ */
89
+ inline std::string GenerateRandomName(int length)
90
+ {
91
+ std::string letters = "abcdefghijklmnopqrstuvwxyz0123456789";
92
+
93
+ std::random_device rand_dev;
94
+ std::mt19937 generator(rand_dev());
95
+ std::uniform_int_distribution<int> distr(0, letters.size() - 1);
96
+
97
+ std::string result;
98
+ for (int i = 0; i < length; ++i) {
99
+ result += letters[distr(generator)];
100
+ }
101
+
102
+ return result + ".tmp";
103
+ }
104
+
105
+ class ZipArchive {
106
+ private:
107
+ void *m_zipData; // the raw data of the unmodified source archive, (re-)set on ZipArchive::Open
108
+ size_t m_zipSize; // the size in bytes of the unmodified source archive stored at m_zipData
109
+ zip_error_t m_zipError; // TBD how useful: save zip_error_t states across different methods
110
+ zip_source_t *m_zipSrc; // the zip source, as opposed to the archive - TBD what the logic of this is
111
+ zip_t *m_za; // the zip archive - changed must be commited before they can be read via GetEntryDataAsString
112
+ std::string m_name; // name of the archive file for which ZipArchive::Open was called
113
+
114
+ /**
115
+ * @brief close archive, commit changes and - if the underlying reference count reaches zero - free resources (m_zipData, m_zipSrc)
116
+ * @return N/A
117
+ * @throw XLInternalError
118
+ */
119
+ void closeZip() {
120
+ //
121
+ if (zip_close(m_za) < 0) {
122
+ using namespace std::literals::string_literals;
123
+ throw XLInternalError("ZipArchive::closeZip: can't close zip archive '"s + m_name + "': "s + zip_strerror(m_za));
124
+ }
125
+ m_za = nullptr;
126
+ }
127
+
128
+ /**
129
+ * @brief (re)open zip archive from source, allowing further read & write access
130
+ * @return N/A
131
+ * @throw XLInternalError
132
+ */
133
+ void reopenFromZipSource() {
134
+ if ((m_za = zip_open_from_source(m_zipSrc, 0, &m_zipError)) == nullptr) {
135
+ zip_source_free(m_zipSrc);
136
+ m_zipSrc = nullptr; // prevent double-free
137
+ zip_error_fini(&m_zipError);
138
+ using namespace std::literals::string_literals;
139
+ throw XLInternalError("ZipArchive::reopenFromZipSource: can't open zip from source: "s + zip_error_strerror(&m_zipError));
140
+ }
141
+ }
142
+
143
+ /**
144
+ * @brief load data from filename into this->m_zipData
145
+ * @param filename load a file from here
146
+ * @return 0 on success, -1 on failure
147
+ */
148
+ int loadArchiveData(std::string filename)
149
+ {
150
+ m_zipSize = 0; // init in case of failure
151
+
152
+ struct stat st;
153
+ if (stat(filename.c_str(), &st) < 0) {
154
+ if (errno != ENOENT) {
155
+ fprintf(stderr, "ZipArchive::loadArchiveData: can't obtain info about %s: %s\n", filename.c_str(), strerror(errno));
156
+ return -1;
157
+ }
158
+
159
+ m_zipData = nullptr;
160
+ return -1;
161
+ }
162
+
163
+ if ((m_zipData = malloc(static_cast<size_t>(st.st_size))) == nullptr) {
164
+ fprintf(stderr, "ZipArchive::loadArchiveData: can't allocate buffer\n");
165
+ return -1;
166
+ }
167
+
168
+ FILE *fp = fopen(filename.c_str(), "r");
169
+ if (fp == nullptr) {
170
+ free(m_zipData);
171
+ m_zipData = nullptr;
172
+ fprintf(stderr, "ZipArchive::loadArchiveData: can't open %s: %s\n", filename.c_str(), strerror(errno));
173
+ return -1;
174
+ }
175
+
176
+ if (fread(m_zipData, 1, static_cast<size_t>(st.st_size), fp) < static_cast<size_t>(st.st_size)) {
177
+ free(m_zipData);
178
+ m_zipData = nullptr;
179
+ fprintf(stderr, "ZipArchive::loadArchiveData: can't read %s: %s\n", filename.c_str(), strerror(errno));
180
+ fclose(fp);
181
+ return -1;
182
+ }
183
+
184
+ fclose(fp);
185
+
186
+ m_zipSize = static_cast<size_t>(st.st_size);
187
+ return 0;
188
+ }
189
+
190
+ /**
191
+ * @brief Save size bytes from data to a temporary file, then move that to filename
192
+ * @param data save data from here
193
+ * @param size amount of bytes to save
194
+ * @param filename (final) save destination
195
+ * @return 0 on success, -1 on failure
196
+ */
197
+ int saveArchiveFile(void *data, size_t size, std::string filename)
198
+ {
199
+ # ifdef _WIN32
200
+ std::replace( filename.begin(), filename.end(), '\\', '/' ); // pull request #210, alternate fix: fopen etc work fine with forward slashes
201
+ # endif
202
+
203
+ // ===== Determine path of the current file
204
+ size_t pathPos = filename.rfind('/');
205
+
206
+ // pull request #191, support AmigaOS style paths
207
+ # ifdef __amigaos__
208
+ constexpr const char * localFolder = ""; // local folder on AmigaOS can not be explicitly expressed in a path
209
+ if (pathPos == std::string::npos) pathPos = filename.rfind(':'); // if no '/' found, attempt to find amiga drive root path
210
+ # else
211
+ constexpr const char * localFolder = "./"; // local folder on _WIN32 && __linux__ is .
212
+ # endif
213
+ std::string tempPath{};
214
+ if (pathPos != std::string::npos) tempPath = filename.substr(0, pathPos + 1);
215
+ else tempPath = localFolder; // prepend explicit identification of local folder in case path did not contain a folder
216
+
217
+ // ===== Generate a random file name with the same path as the current file
218
+ tempPath = tempPath + GenerateRandomName(20);
219
+
220
+ FILE *fp = fopen(tempPath.c_str(), "wb");
221
+ if (fp == nullptr) {
222
+ fprintf(stderr, "ZipArchive::saveArchiveFile: can't open %s: %s\n", tempPath.c_str(), strerror(errno));
223
+ return -1;
224
+ }
225
+ if (fwrite(data, 1, size, fp) < size) {
226
+ fprintf(stderr, "ZipArchive::saveArchiveFile: can't write %s: %s\n", tempPath.c_str(), strerror(errno));
227
+ fclose(fp);
228
+ return -1;
229
+ }
230
+ if (fclose(fp) < 0) {
231
+ fprintf(stderr, "ZipArchive::saveArchiveFile: can't close %s: %s\n", tempPath.c_str(), strerror(errno));
232
+ return -1;
233
+ }
234
+ std::filesystem::remove(filename.c_str());
235
+ std::filesystem::rename(tempPath.c_str(), filename.c_str());
236
+
237
+ return 0;
238
+ }
239
+
240
+
241
+ public:
242
+ /**
243
+ * @brief construct an empty ZipArchive
244
+ */
245
+ ZipArchive()
246
+ : m_zipData(nullptr), m_zipSize(0), m_zipSrc(nullptr), m_za(nullptr), m_name("") {}
247
+
248
+ /**
249
+ * @brief destructor: close zip archive if open
250
+ * @note data will not be saved automatically on destruction - user must call ZipArchive::Save
251
+ */
252
+ ~ZipArchive() {
253
+ if (IsOpen()) Close();
254
+ }
255
+
256
+ /**
257
+ * @brief test whether zip archive is open / ready for reads & writes
258
+ * @return true if a zip file has been opened, false if archive is not open
259
+ */
260
+ bool IsOpen() const { return m_za != nullptr; }
261
+
262
+ /**
263
+ * @brief close an open archive and free resources
264
+ * @return N/A
265
+ * @throw XLInputError if archive is not open
266
+ */
267
+ void Close() {
268
+ if (!IsOpen())
269
+ throw XLInputError("ZipArchive::Close: archive is not open!");
270
+
271
+ // struct zip_file_attributes {
272
+ // zip_uint64_t valid; /* which fields have valid values */
273
+ // zip_uint8_t version; /* version of this struct, currently 1 */
274
+ // zip_uint8_t host_system; /* host system on which file was created */
275
+ // zip_uint8_t ascii; /* flag whether file is ASCII text */
276
+ // zip_uint8_t version_needed; /* minimum version needed to extract file */
277
+ // zip_uint32_t external_file_attributes; /* external file attributes (host-system specific) */
278
+ // zip_uint16_t general_purpose_bit_flags; /* general purpose big flags, only some bits are honored */
279
+ // zip_uint16_t general_purpose_bit_mask; /* which bits in general_purpose_bit_flags are valid */
280
+ // };
281
+ // zip_file_attributes_t zipAttrs;
282
+ // zipAttrs.general_purpose_bit_flags = 0;
283
+ // zip_source_get_file_attributes(m_zipSrc, &zipAttrs);
284
+ // printf( "zip_file_attributes::general_purpose_bit_flags is 0x%08x\n", static_cast< uint16_t >( zipAttrs.general_purpose_bit_flags ) );
285
+
286
+ closeZip(); // invalidates m_zipData and m_zipSrc because reference count for the underlying zip source should reach zero
287
+ m_zipData = nullptr;
288
+ m_zipSize = 0;
289
+ m_zipSrc = nullptr;
290
+ m_name = "";
291
+ }
292
+
293
+ /**
294
+ * @brief Open an existing archive file
295
+ * @param archiveName the file to load from
296
+ * @return N/A
297
+ * @throw XLInputError if archive is already open
298
+ * @throw XLInternalError if archiveName can't be opened / loaded
299
+ */
300
+ void Open(std::string archiveName) {
301
+ using namespace std::literals::string_literals;
302
+ if (IsOpen())
303
+ throw XLInputError("ZipArchive::Open: archive is already open for source file "s + m_name); // user must close the archive before re-opening
304
+
305
+ /* get buffer with zip archive inside */
306
+ if (loadArchiveData(archiveName) < 0)
307
+ throw XLInternalError("ZipArchive::Open: failed to load archive data from file "s + archiveName);
308
+
309
+ zip_error_init(&m_zipError);
310
+ /* create source from buffer */
311
+ if ((m_zipSrc = zip_source_buffer_create(m_zipData, m_zipSize, 1, &m_zipError)) == nullptr) {
312
+ free(m_zipData);
313
+ m_zipData = nullptr; // prevent double-free
314
+ zip_error_fini(&m_zipError);
315
+ // std::cerr << "can't create source: " << zip_error_strerror(&m_zipError) << std::endl;
316
+ throw XLInternalError("ZipArchive::Open: can't create source: "s + zip_error_strerror(&m_zipError));
317
+ }
318
+
319
+ reopenFromZipSource();
320
+
321
+ zip_error_fini(&m_zipError);
322
+ m_name = archiveName;
323
+ }
324
+
325
+ /**
326
+ * @brief make modified archive data available for reading via GetEntryDataAsString
327
+ * @return N/A
328
+ * @throw XLInternalError thrown from closeZip or reopenFromZipSource upon failure
329
+ */
330
+ void CommitChanges() { // make changes readable
331
+ zip_source_keep(m_zipSrc); // ensure that m_zipSrc survives zip_close
332
+ closeZip(); // close zip and thereby commit changes
333
+ reopenFromZipSource(); // ensure that archive is valid again for further reading & modifications
334
+ }
335
+
336
+ /**
337
+ * @brief Save the (modified) archive to savePath
338
+ * @param savePath save here, or save to original filename if empty string is provided
339
+ * @return N/A
340
+ * @throw XLInternalError upon any failure
341
+ */
342
+ void Save(std::string savePath)
343
+ {
344
+ if (savePath == "") // saving in original file location!
345
+ savePath = m_name;
346
+
347
+ zip_source_keep(m_zipSrc); // ensure that m_zipSrc survives zip_close
348
+ closeZip(); // close the zip archive to commit changes
349
+
350
+ if (zip_source_is_deleted(m_zipSrc)) {
351
+ /* new archive is empty, thus no data */
352
+ throw XLInternalError("ZipArchive::Save: zip_source_is_deleted returned true, this should not happen");
353
+ }
354
+ else {
355
+ using namespace std::literals::string_literals;
356
+
357
+ void *saveData = nullptr;
358
+ zip_stat_t zst;
359
+ if (zip_source_stat(m_zipSrc, &zst) < 0)
360
+ throw XLInternalError("ZipArchive::Save: can't stat source: "s + zip_error_strerror(zip_source_error(m_zipSrc)));
361
+
362
+ size_t saveSize = zst.size;
363
+ if (zip_source_open(m_zipSrc) < 0) // prepare m_zipSrc for reading archive data from it
364
+ throw XLInternalError("ZipArchive::Save: can't open source: "s + zip_error_strerror(zip_source_error(m_zipSrc)));
365
+
366
+ if ((saveData = malloc(saveSize)) == nullptr) { // allocate memory to store the modified archive for saving to a file
367
+ zip_source_close(m_zipSrc);
368
+ throw XLInternalError("ZipArchive::Save: malloc failed: "s + strerror(errno));
369
+ }
370
+ // ==== Read the archive raw data from m_zipSrc
371
+ if (static_cast<size_t>(zip_source_read(m_zipSrc, saveData, saveSize)) < saveSize) {
372
+ zip_source_close(m_zipSrc);
373
+ free(saveData);
374
+ throw XLInternalError("ZipArchive::Save: can't read saveData from source: "s + zip_error_strerror(zip_source_error(m_zipSrc)));
375
+ }
376
+ zip_source_close(m_zipSrc); // close the zip source
377
+ if (saveArchiveFile(saveData, saveSize, savePath.c_str()) < 0) // and save the archive
378
+ throw XLInternalError("ZipArchive::Save: failed to save archive data to "s + savePath);
379
+
380
+ free(saveData); // free temporary buffer used for saving the archive
381
+ }
382
+
383
+ reopenFromZipSource(); // ensure that archive is valid again for further modifications
384
+ }
385
+
386
+ /**
387
+ * @brief Add a file to the archive and write data to it - overwrite existing files
388
+ * @param entryName file path in the archive - if existing, destination will be replaced
389
+ * @param data contents for a text file to be placed in the archive for entryName
390
+ * @return N/A
391
+ * @throw XLInputError when called on a non-valid archive
392
+ * @throw XLInternalError upon any other failure
393
+ */
394
+ void AddEntry(const std::string& entryName, const std::string& data)
395
+ {
396
+ if (!IsOpen())
397
+ throw XLInputError("ZipArchive::AddEntry: archive is not open!");
398
+
399
+ void *buf = malloc(data.size()); // allocate memory for a persistent copy of data.data()
400
+ memcpy(buf, data.data(), data.size()); // copy data.data() to the allocated memory
401
+
402
+ // create the zip source for a single entry from data
403
+ struct zip_source *zipSrc = zip_source_buffer(m_za, buf, data.size(), 1); // create zip source from buffer, flagging that buf shall be freed by libzip
404
+
405
+ if (!zipSrc)
406
+ throw XLInternalError("ZipArchive::AddEntry: failed to create a zip source from entry data");
407
+
408
+ if (-1 == zip_file_add(m_za, entryName.c_str(), zipSrc, ZIP_FL_OVERWRITE | ZIP_FL_ENC_UTF_8)) {
409
+ using namespace std::literals::string_literals;
410
+ throw XLInternalError("ZipArchive::AddEntry: failed to add file to archive: "s + zip_error_strerror(zip_get_error(m_za)));
411
+ }
412
+ }
413
+
414
+ /**
415
+ * @brief Delete a file from the archive
416
+ * @param entryName archive file to delete
417
+ * @return N/A
418
+ * @throw XLInputError when called on a non-valid archive or if entryName does not exist in the archive
419
+ * @throw XLInternalError upon any other failure
420
+ */
421
+ void DeleteEntry(const std::string& entryName)
422
+ {
423
+ using namespace std::literals::string_literals;
424
+
425
+ if (!IsOpen())
426
+ throw XLInputError("ZipArchive::DeleteEntry: archive is not open!");
427
+
428
+ int index = zip_name_locate(m_za, entryName.c_str(), 0);
429
+ if (index == -1)
430
+ throw XLInputError("ZipArchive::DeleteEntry: archive does not contain file: "s + entryName);
431
+
432
+ if (0 != zip_delete(m_za, index))
433
+ throw XLInternalError("ZipArchive::DeleteEntry: failed to delete file "s + entryName + " from archive: "s + zip_error_strerror(zip_get_error(m_za)));
434
+ }
435
+
436
+ /**
437
+ * @brief Return the contents of an archive file as a string
438
+ * @note function is intended for text files only
439
+ * @param entryName archive file to fetch
440
+ * @return std::string with the contents of the archive file
441
+ * @throw XLInputError when called on a non-valid archive or if entryName does not exist in the archive
442
+ * @throw XLInternalError upon any other failure
443
+ */
444
+ std::string GetEntryDataAsString(const std::string& entryName) const
445
+ {
446
+ using namespace std::literals::string_literals;
447
+
448
+ if (!IsOpen())
449
+ throw XLInputError("ZipArchive::GetEntryDataAsString: archive is not open!");
450
+
451
+ int index = zip_name_locate(m_za, entryName.c_str(), 0); // ensure that entryName exists in the archive
452
+ if (index == -1)
453
+ throw XLInputError("ZipArchive::GetEntryDataAsString: archive does not contain file: "s + entryName);
454
+
455
+ // determine how many bytes entry data encompasses
456
+ struct zip_stat entryInfo;
457
+ if (0 != zip_stat_index(m_za, index, 0, &entryInfo))
458
+ throw XLInternalError("ZipArchive::GetEntryDataAsString: failed to obtain archive entry info for "s + entryName + ": "s + zip_error_strerror(zip_get_error(m_za)));
459
+
460
+ zip_file_t *fd = zip_fopen_index(m_za, index, 0); // get a file descriptor for desired entry
461
+ if (fd == nullptr)
462
+ throw XLInternalError("ZipArchive::GetEntryDataAsString: an error occurred trying to open archive file "s + entryName + ": "s + zip_error_strerror(zip_get_error(m_za)));
463
+
464
+ char *entryDataChr = reinterpret_cast<char *>(malloc(entryInfo.size + 1)); // temporary buffer to construct return string from
465
+ zip_fread(fd, entryDataChr, entryInfo.size); // read entry data into temporary buffer
466
+ entryDataChr[entryInfo.size] = 0; // ensure zero-termination of buffer data
467
+ std::string entryDataAsString(entryDataChr); // construct string return value from buffer data
468
+ free(entryDataChr); // free temporary buffer
469
+ zip_fclose(fd); // close file descriptor
470
+
471
+ return entryDataAsString;
472
+ }
473
+
474
+ /**
475
+ * @brief test whether a file exists in the archive
476
+ * @param entryName archive file to locate
477
+ * @return true if archive has file, false otherwise
478
+ */
479
+ bool HasEntry(const std::string& entryName) const
480
+ {
481
+ return (-1 != zip_name_locate(m_za, entryName.c_str(), 0)); // zip_name_locate also returns -1 if m_za is nullptr, thus no extra check for IsOpen()
482
+
483
+ }
484
+
485
+ /**
486
+ * @brief get valid entry index range [0;EntryCount()-1]
487
+ * @return amount of entries in the zip archive
488
+ * @return -1 on error (m_za is not open / nullptr)
489
+ */
490
+ ssize_t EntryCount() const { return zip_get_num_files(m_za); }
491
+
492
+ /**
493
+ * @brief get entry name by index
494
+ * @param index which entry name to get, must be within [0;EntryCount()-1]
495
+ * @return std::string with the name of the entry at index
496
+ * @return empty string if entry does not have a name / index is invalid
497
+ * @throw XLInputError if archive is closed (nullptr)
498
+ */
499
+ std::string EntryName( int index ) const // get name of the archive entry at index
500
+ {
501
+ if (!IsOpen())
502
+ throw XLInputError("ZipArchive::EntryName: archive is not open");
503
+ const char *name = zip_get_name(m_za, index, 0);
504
+ return std::string(name == nullptr ? "" : name);
505
+ }
506
+ };
507
+
508
+ } // namespace LibZip
509
+
510
+ namespace OpenXLSX
511
+ {
512
+ #define OPENXLSX_EXPORT
513
+ /**
514
+ * @brief
515
+ */
516
+ class OPENXLSX_EXPORT XLZipArchive
517
+ {
518
+ public:
519
+ /**
520
+ * @brief
521
+ */
522
+ XLZipArchive() : m_archive(nullptr) {}
523
+
524
+ /**
525
+ * @brief
526
+ * @param other
527
+ */
528
+ XLZipArchive(const XLZipArchive& other) = default;
529
+
530
+ /**
531
+ * @brief
532
+ * @param other
533
+ */
534
+ XLZipArchive(XLZipArchive&& other) = default;
535
+
536
+ /**
537
+ * @brief
538
+ */
539
+ ~XLZipArchive() = default;
540
+
541
+ /**
542
+ * @brief
543
+ * @param other
544
+ * @return
545
+ */
546
+ XLZipArchive& operator=(const XLZipArchive& other) = default;
547
+
548
+ /**
549
+ * @brief
550
+ * @param other
551
+ * @return
552
+ */
553
+ XLZipArchive& operator=(XLZipArchive&& other) = default;
554
+
555
+ /**
556
+ * @brief check if zippy is in use (or ziplib)
557
+ * @param
558
+ * @return true if zippy is used for the zip implementation, otherwise false
559
+ */
560
+ bool usesZippy() {
561
+ #ifdef USE_LIBZIP
562
+ return false;
563
+ #else
564
+ return true;
565
+ #endif
566
+ }
567
+
568
+ /**
569
+ * @brief
570
+ * @return
571
+ */
572
+ explicit operator bool() const {
573
+ return isValid();
574
+ }
575
+
576
+ bool isValid() const { return m_archive != nullptr; }
577
+
578
+ /**
579
+ * @brief
580
+ * @return
581
+ */
582
+ bool isOpen() const {
583
+ return m_archive && m_archive->IsOpen();
584
+ }
585
+
586
+ /**
587
+ * @brief
588
+ * @param fileName
589
+ */
590
+ void open(const std::string& fileName)
591
+ {
592
+ if (isOpen()) throw XLInputError("XLZipArchive::open: archive is already open"); // prevent double open
593
+ m_archive = std::make_shared<XLZipImplementation>();
594
+ try {
595
+ m_archive->Open(fileName);
596
+ }
597
+ catch( ... ) { // catch all exceptions
598
+ m_archive.reset(); // make m_archive invalid again
599
+ throw; // re-throw
600
+ }
601
+ }
602
+
603
+ /**
604
+ * @brief
605
+ */
606
+ void close()
607
+ {
608
+ if (!m_archive) throw XLInputError("XLZipArchive::close: archive is not open"); // prevent SEGFAULT
609
+ m_archive->Close();
610
+ m_archive.reset();
611
+ }
612
+
613
+ /**
614
+ * @brief make archive updates (from addEntry) available to calls via getEntry
615
+ */
616
+ void commitChanges()
617
+ {
618
+ if (!m_archive) throw 1; // prevent SEGFAULT
619
+ m_archive->CommitChanges();
620
+ }
621
+
622
+ /**
623
+ * @brief
624
+ * @param path
625
+ */
626
+ void save(const std::string& path = "")
627
+ {
628
+ if (!m_archive) throw 1; // prevent SEGFAULT
629
+ m_archive->Save(path);
630
+ }
631
+
632
+ /**
633
+ * @brief
634
+ * @param name
635
+ * @param data
636
+ */
637
+ void addEntry(const std::string& name, const std::string& data)
638
+ {
639
+ if (!m_archive) throw 1; // prevent SEGFAULT
640
+ m_archive->AddEntry(name, data);
641
+ }
642
+
643
+ /**
644
+ * @brief
645
+ * @param entryName
646
+ */
647
+ void deleteEntry(const std::string& entryName)
648
+ {
649
+ if (!m_archive) throw 1; // prevent SEGFAULT
650
+ m_archive->DeleteEntry(entryName);
651
+ }
652
+
653
+ /**
654
+ * @brief
655
+ * @param name
656
+ * @return
657
+ */
658
+ std::string getEntry(const std::string& name) const
659
+ {
660
+ if (!m_archive) throw 1; // prevent SEGFAULT
661
+ #ifdef USE_LIBZIP
662
+ return m_archive->GetEntryDataAsString(name);
663
+ #else
664
+ return m_archive->GetEntry(name).GetDataAsString();
665
+ #endif
666
+ }
667
+
668
+ /**
669
+ * @brief
670
+ * @param entryName
671
+ * @return
672
+ */
673
+ bool hasEntry(const std::string& entryName) const
674
+ {
675
+ if (!m_archive) throw 1; // prevent SEGFAULT
676
+ return m_archive->HasEntry(entryName);
677
+ }
678
+
679
+ ssize_t entryCount() const { return m_archive->EntryCount(); }
680
+ std::string entryName( int index ) const { return m_archive->EntryName(index); }
681
+
682
+ private:
683
+ std::shared_ptr<XLZipImplementation> m_archive; /**< */
684
+ };
685
+ } // namespace OpenXLSX
686
+
687
+
688
+ int main(int argc, char *argv[])
689
+ {
690
+ std::string archiveName = "Demo01";
691
+ std::string archiveExt = ".xlsx";
692
+
693
+ OpenXLSX::XLZipArchive myArc{};
694
+
695
+ std::cout << "myArc.usesZippy() is " << ( myArc.usesZippy() ? "true" : "false" ) << std::endl;
696
+ std::cout << "myArc.isOpen() is " << ( myArc.isOpen() ? "true" : "false" ) << std::endl;
697
+ myArc.open(archiveName + archiveExt);
698
+ std::cout << "myArc.isOpen() is " << ( myArc.isOpen() ? "true" : "false" ) << std::endl;
699
+ std::string entryName = "docProps/core.xml";
700
+ std::cout << "myArc.hasEntry(\"" << entryName << "\") is " << ( myArc.hasEntry(entryName) ? "true" : "false" ) << std::endl;
701
+
702
+ int i = 0;
703
+ ssize_t entryCount = myArc.entryCount();
704
+ std::cout << "myArc.entryCount() is " << entryCount << std::endl;
705
+ while (i < entryCount) {
706
+ std::cout << "myArc.entryName(" << i << ") is " << myArc.entryName(i) << std::endl;
707
+ ++i;
708
+ }
709
+
710
+ std::string testEntry = "xl/worksheets/sheet2.xml";
711
+ std::cout << "adding a file to myArc: " << testEntry << std::endl;
712
+ myArc.addEntry(testEntry, "Hello World!");
713
+
714
+ myArc.commitChanges();
715
+
716
+ // testEntry = "xl/worksheets/sheet1.xml";
717
+ std::string test = myArc.getEntry(testEntry);
718
+ std::cout << "contents of " << testEntry << ":" << std::endl;
719
+ std::cout << "------------------------------------------------" << std::endl;
720
+ std::cout << test << std::endl;
721
+ std::cout << "------------------------------------------------" << std::endl;
722
+
723
+ // TBD: for some reason, replacing any file except the ones that this program added itself, fixes the central general_purpose_bit_flags error that unzip reports
724
+ // entryName = "_rels/.rels";
725
+ // entryName = testEntry;
726
+ // std::string eData = myArc.getEntry(entryName);
727
+ // myArc.addEntry(entryName, eData); // replace archive contents
728
+ // myArc.commitChanges();
729
+
730
+ myArc.save(archiveName + "_1" + archiveExt); // saves and re-opens from source
731
+ myArc.close();
732
+ std::cout << "myArc.isOpen() is " << ( myArc.isOpen() ? "true" : "false" ) << std::endl;
733
+
734
+ return 0;
735
+ }