react-native-nitro-xlsx 0.2.5 → 0.2.7

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 (449) hide show
  1. package/NitroXlsx.podspec +26 -27
  2. package/Package.swift +31 -10
  3. package/README.md +21 -9
  4. package/android/CMakeLists.txt +20 -27
  5. package/cpp/HybridNitroXlsx.cpp +25 -1
  6. package/cpp/HybridXlsxCellFormat.cpp +46 -146
  7. package/cpp/HybridXlsxCellFormat.hpp +9 -41
  8. package/cpp/HybridXlsxConditionalFormat.cpp +4 -1
  9. package/cpp/HybridXlsxConditionalFormats.cpp +5 -1
  10. package/cpp/HybridXlsxWorkbook.cpp +38 -8
  11. package/cpp/HybridXlsxWorkbook.hpp +10 -1
  12. package/cpp/HybridXlsxWorksheet.cpp +422 -141
  13. package/cpp/HybridXlsxWorksheet.hpp +4 -1
  14. package/cpp/XlsxCacheDir.cpp +25 -2
  15. package/cpp/XlsxCacheDir.hpp +3 -1
  16. package/cpp/XlsxCellStyle.hpp +360 -0
  17. package/cpp/XlsxJson.cpp +29 -8
  18. package/package.json +2 -2
  19. package/scripts/run-cpp-tests.sh +1 -1
  20. package/scripts/sync-openxlsx-headers.sh +34 -0
  21. package/src/__mocks__/react-native-nitro-modules.ts +523 -20
  22. package/src/__tests__/index.test.ts +124 -16
  23. package/src/index.ts +13 -13
  24. package/thirdparty/OpenXLSX/.clang-format +118 -0
  25. package/thirdparty/OpenXLSX/.clang-tidy +28 -0
  26. package/thirdparty/OpenXLSX/.gitignore +130 -0
  27. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_before_XMLNode_wrappers +46 -0
  28. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_and_stripping +49 -0
  29. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_char_support +49 -0
  30. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_support +49 -0
  31. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespaced_name_disabled +49 -0
  32. package/thirdparty/OpenXLSX/Benchmarks/2024-08-11-benchmarks_post-XLCellIterator-Rework +46 -0
  33. package/thirdparty/OpenXLSX/Benchmarks/2024-08-14-benchmarks_post-default-row-column-style-support +46 -0
  34. package/thirdparty/OpenXLSX/Benchmarks/2024-09-02-benchmarks +46 -0
  35. package/thirdparty/OpenXLSX/Benchmarks/2024-12-19-benchmarks +46 -0
  36. package/thirdparty/OpenXLSX/Benchmarks/2024-12-30-benchmarks-post-XLSharedStrings-by-ref +46 -0
  37. package/thirdparty/OpenXLSX/Benchmarks/2025-01-09-benchmarks-post-conditionalFormatsAndSheetProtection +46 -0
  38. package/thirdparty/OpenXLSX/Benchmarks/2025-01-10-benchmarks-post-XLCellValue-bugfix +46 -0
  39. package/thirdparty/OpenXLSX/Benchmarks/2025-01-31-benchmarks-post-XLComments-implementation +46 -0
  40. package/thirdparty/OpenXLSX/Benchmarks/2025-02-02-benchmarks-post-XLRowIterator-Rework +46 -0
  41. package/thirdparty/OpenXLSX/Benchmarks/2025-07-20-benchmarks-after-hiding-pugixml-internals +46 -0
  42. package/thirdparty/OpenXLSX/Benchmarks/2025-08-29-benchmarks-after-code-review-with-libzip +46 -0
  43. package/thirdparty/OpenXLSX/Benchmarks/Benchmark.cpp +249 -0
  44. package/thirdparty/OpenXLSX/Benchmarks/CMakeLists.txt +19 -0
  45. package/thirdparty/OpenXLSX/CMakeLists.txt +466 -0
  46. package/thirdparty/OpenXLSX/Documentation/CMakeLists.txt +31 -0
  47. package/thirdparty/OpenXLSX/Documentation/Doxyfile.in +2471 -0
  48. package/thirdparty/OpenXLSX/Documentation/DoxygenLayout.xml +194 -0
  49. package/thirdparty/OpenXLSX/Documentation/customdoxygen.css +1355 -0
  50. package/thirdparty/OpenXLSX/Examples/CMakeLists.txt +103 -0
  51. package/thirdparty/OpenXLSX/Examples/Demo1.cpp +279 -0
  52. package/thirdparty/OpenXLSX/Examples/Demo10.cpp +545 -0
  53. package/thirdparty/OpenXLSX/Examples/Demo1A.cpp +137 -0
  54. package/thirdparty/OpenXLSX/Examples/Demo2.cpp +65 -0
  55. package/thirdparty/OpenXLSX/Examples/Demo3.cpp +89 -0
  56. package/thirdparty/OpenXLSX/Examples/Demo4.cpp +86 -0
  57. package/thirdparty/OpenXLSX/Examples/Demo5.cpp +77 -0
  58. package/thirdparty/OpenXLSX/Examples/Demo6.cpp +103 -0
  59. package/thirdparty/OpenXLSX/Examples/Demo7.cpp +79 -0
  60. package/thirdparty/OpenXLSX/Examples/Demo8.cpp +117 -0
  61. package/thirdparty/OpenXLSX/Examples/Demo9.cpp +363 -0
  62. package/thirdparty/OpenXLSX/Examples/cmake/FindLIBZIP.cmake +61 -0
  63. package/thirdparty/OpenXLSX/Examples/external/CustomZip/CustomZip.hpp +256 -0
  64. package/thirdparty/OpenXLSX/LICENSE.md +29 -0
  65. package/thirdparty/OpenXLSX/Makefile.GNU +530 -0
  66. package/thirdparty/OpenXLSX/Notes/TBDs.txt +16 -0
  67. package/thirdparty/OpenXLSX/Notes/confirmed-TBCs.txt +8 -0
  68. package/thirdparty/OpenXLSX/Notes/styles-missing-support.xml +12 -0
  69. package/thirdparty/OpenXLSX/Notes/todo-list.txt +108 -0
  70. package/thirdparty/OpenXLSX/OpenXLSX/CMakeLists.txt +631 -0
  71. package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSX.hpp +63 -0
  72. package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSXConfig.cmake +11 -0
  73. package/thirdparty/OpenXLSX/OpenXLSX/cmake/bundle_static_library.cmake +198 -0
  74. package/thirdparty/OpenXLSX/OpenXLSX/cmake/patch_pkg_config.cmake +69 -0
  75. package/thirdparty/OpenXLSX/OpenXLSX/headers/IZipArchive.hpp +361 -0
  76. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/IZipArchive.hpp +361 -0
  77. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/OpenXLSX-Exports.hpp +12 -0
  78. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCell.hpp +367 -0
  79. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCellIterator.hpp +252 -0
  80. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCellRange.hpp +223 -0
  81. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCellReference.hpp +317 -0
  82. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCellValue.hpp +793 -0
  83. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLColor.hpp +232 -0
  84. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLColumn.hpp +159 -0
  85. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCommandQuery.hpp +228 -0
  86. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLComments.hpp +270 -0
  87. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLConstants.hpp +18 -0
  88. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLContentTypes.hpp +264 -0
  89. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLDateTime.hpp +175 -0
  90. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLDocument.hpp +505 -0
  91. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLDrawing.hpp +452 -0
  92. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLException.hpp +161 -0
  93. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLFormula.hpp +375 -0
  94. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLIterator.hpp +40 -0
  95. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLMergeCells.hpp +216 -0
  96. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLProperties.hpp +348 -0
  97. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLRelationships.hpp +348 -0
  98. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLRow.hpp +721 -0
  99. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLRowData.hpp +488 -0
  100. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLSharedStrings.hpp +204 -0
  101. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLSheet.hpp +1640 -0
  102. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLStyles.hpp +2390 -0
  103. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLTables.hpp +132 -0
  104. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLWorkbook.hpp +404 -0
  105. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLXmlData.hpp +283 -0
  106. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLXmlFile.hpp +194 -0
  107. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLXmlParser.hpp +282 -0
  108. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLXmlParserForwardDeclarations.hpp +85 -0
  109. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLZipArchive.hpp +232 -0
  110. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/detail/LibZip.hpp +447 -0
  111. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/detail/OpenXLSXFileSystemTools.hpp +207 -0
  112. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/detail/Zippy.hpp +1375 -0
  113. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX-Exports.hpp +12 -0
  114. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCell.hpp +367 -0
  115. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellIterator.hpp +252 -0
  116. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellRange.hpp +223 -0
  117. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellReference.hpp +317 -0
  118. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellValue.hpp +793 -0
  119. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColor.hpp +232 -0
  120. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColumn.hpp +159 -0
  121. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCommandQuery.hpp +228 -0
  122. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLComments.hpp +270 -0
  123. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLConstants.hpp +18 -0
  124. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLContentTypes.hpp +264 -0
  125. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDateTime.hpp +175 -0
  126. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDocument.hpp +505 -0
  127. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDrawing.hpp +452 -0
  128. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLException.hpp +161 -0
  129. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLFormula.hpp +375 -0
  130. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLIterator.hpp +40 -0
  131. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLMergeCells.hpp +216 -0
  132. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLProperties.hpp +348 -0
  133. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRelationships.hpp +348 -0
  134. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRow.hpp +721 -0
  135. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRowData.hpp +488 -0
  136. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSharedStrings.hpp +204 -0
  137. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSheet.hpp +1640 -0
  138. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLStyles.hpp +2390 -0
  139. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLTables.hpp +132 -0
  140. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLWorkbook.hpp +404 -0
  141. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlData.hpp +283 -0
  142. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlFile.hpp +194 -0
  143. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParser.hpp +282 -0
  144. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParserForwardDeclarations.hpp +85 -0
  145. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLZipArchive.hpp +232 -0
  146. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/LibZip.hpp +447 -0
  147. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/OpenXLSXFileSystemTools.hpp +207 -0
  148. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/Zippy.hpp +1375 -0
  149. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCell.cpp +340 -0
  150. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellIterator.cpp +427 -0
  151. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellRange.cpp +221 -0
  152. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellReference.cpp +408 -0
  153. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellValue.cpp +519 -0
  154. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColor.cpp +202 -0
  155. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColumn.cpp +141 -0
  156. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLComments.cpp +637 -0
  157. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLContentTypes.cpp +329 -0
  158. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDateTime.cpp +269 -0
  159. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDocument.cpp +1678 -0
  160. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDrawing.cpp +784 -0
  161. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLFormula.cpp +201 -0
  162. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLMergeCells.cpp +357 -0
  163. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLProperties.cpp +810 -0
  164. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRelationships.cpp +529 -0
  165. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRow.cpp +918 -0
  166. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRowData.cpp +508 -0
  167. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSharedStrings.cpp +220 -0
  168. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSheet.cpp +1970 -0
  169. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLStyles.cpp +3014 -0
  170. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLTables.cpp +125 -0
  171. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLWorkbook.cpp +784 -0
  172. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlData.cpp +247 -0
  173. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlFile.cpp +160 -0
  174. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlParser.cpp +261 -0
  175. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLZipArchive.cpp +266 -0
  176. package/thirdparty/OpenXLSX/OpenXLSX/sources/utilities/XLUtilities.hpp +478 -0
  177. package/thirdparty/OpenXLSX/README.md +1279 -0
  178. package/thirdparty/OpenXLSX/Scripts/cmake-cleanup.sh +102 -0
  179. package/thirdparty/OpenXLSX/Scripts/compile.sh +23 -0
  180. package/thirdparty/OpenXLSX/Scripts/demos-cleanup.sh +25 -0
  181. package/thirdparty/OpenXLSX/Scripts/demos-run-all.sh +60 -0
  182. package/thirdparty/OpenXLSX/Scripts/guarded-xml-format.sh +47 -0
  183. package/thirdparty/OpenXLSX/Scripts/make-gnu.sh +11 -0
  184. package/thirdparty/OpenXLSX/Scripts/uninstall-manifest.sh +48 -0
  185. package/thirdparty/OpenXLSX/Scripts/xml-format-all.sh +19 -0
  186. package/thirdparty/OpenXLSX/Scripts/xml-format.sh +38 -0
  187. package/thirdparty/OpenXLSX/Tests/CMakeLists.txt +37 -0
  188. package/thirdparty/OpenXLSX/Tests/catch/catch.hpp +17799 -0
  189. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_automake.hpp +68 -0
  190. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_sonarqube.hpp +182 -0
  191. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_tap.hpp +278 -0
  192. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_teamcity.hpp +212 -0
  193. package/thirdparty/OpenXLSX/Tests/main.cpp +55 -0
  194. package/thirdparty/OpenXLSX/Tests/testXLCell.cpp +176 -0
  195. package/thirdparty/OpenXLSX/Tests/testXLCellRange.cpp +180 -0
  196. package/thirdparty/OpenXLSX/Tests/testXLCellReference.cpp +160 -0
  197. package/thirdparty/OpenXLSX/Tests/testXLCellValue.cpp +366 -0
  198. package/thirdparty/OpenXLSX/Tests/testXLCellValueProxy.cpp +255 -0
  199. package/thirdparty/OpenXLSX/Tests/testXLColor.cpp +75 -0
  200. package/thirdparty/OpenXLSX/Tests/testXLDateTime.cpp +229 -0
  201. package/thirdparty/OpenXLSX/Tests/testXLDocument.cpp +197 -0
  202. package/thirdparty/OpenXLSX/Tests/testXLFormula.cpp +131 -0
  203. package/thirdparty/OpenXLSX/Tests/testXLRow.cpp +597 -0
  204. package/thirdparty/OpenXLSX/Tests/testXLSheet.cpp +77 -0
  205. package/thirdparty/OpenXLSX/Tests/ziptest-with-libs.cpp +88 -0
  206. package/thirdparty/OpenXLSX/Tests/ziptest.cpp +735 -0
  207. package/thirdparty/OpenXLSX/cmake/get-git-HEAD-ID.cmake +45 -0
  208. package/thirdparty/OpenXLSX/cmake/libopenxlsxCPackOptions.cmake.in +20 -0
  209. package/thirdparty/OpenXLSX/cmake/manage_dependency.cmake +813 -0
  210. package/thirdparty/OpenXLSX/cmake/recursive_library_type_test.cmake +52 -0
  211. package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-shared.hpp +42 -0
  212. package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-static.hpp +42 -0
  213. package/thirdparty/OpenXLSX/vcpkg.json +24 -0
  214. package/thirdparty/README.md +46 -0
  215. package/thirdparty/miniz/.clang-format +47 -0
  216. package/thirdparty/miniz/.travis.yml +2 -0
  217. package/thirdparty/miniz/CMakeLists.txt +333 -0
  218. package/thirdparty/miniz/CMakePresets.json +31 -0
  219. package/thirdparty/miniz/ChangeLog.md +272 -0
  220. package/thirdparty/miniz/Config.cmake.in +1 -0
  221. package/thirdparty/miniz/LICENSE +22 -0
  222. package/thirdparty/miniz/amalgamate.sh +57 -0
  223. package/thirdparty/miniz/examples/example1.c +105 -0
  224. package/thirdparty/miniz/examples/example2.c +164 -0
  225. package/thirdparty/miniz/examples/example3.c +269 -0
  226. package/thirdparty/miniz/examples/example4.c +102 -0
  227. package/thirdparty/miniz/examples/example5.c +327 -0
  228. package/thirdparty/miniz/examples/example6.c +189 -0
  229. package/thirdparty/miniz/meson.build +21 -0
  230. package/thirdparty/miniz/miniz.c +646 -0
  231. package/thirdparty/miniz/miniz.h +615 -0
  232. package/thirdparty/miniz/miniz.pc.in +13 -0
  233. package/thirdparty/miniz/miniz_common.h +89 -0
  234. package/thirdparty/miniz/miniz_export.h +20 -0
  235. package/thirdparty/miniz/miniz_tdef.c +1602 -0
  236. package/thirdparty/miniz/miniz_tdef.h +199 -0
  237. package/thirdparty/miniz/miniz_tinfl.c +778 -0
  238. package/thirdparty/miniz/miniz_tinfl.h +150 -0
  239. package/thirdparty/miniz/miniz_zip.c +4895 -0
  240. package/thirdparty/miniz/miniz_zip.h +454 -0
  241. package/thirdparty/miniz/readme.md +46 -0
  242. package/thirdparty/miniz/test.sh +36 -0
  243. package/thirdparty/miniz/tests/add_in_place_fuzzer.c +87 -0
  244. package/thirdparty/miniz/tests/catch_amalgamated.cpp +10795 -0
  245. package/thirdparty/miniz/tests/catch_amalgamated.hpp +13143 -0
  246. package/thirdparty/miniz/tests/checksum_fuzzer.c +26 -0
  247. package/thirdparty/miniz/tests/compress_fuzzer.c +91 -0
  248. package/thirdparty/miniz/tests/flush_fuzzer.c +88 -0
  249. package/thirdparty/miniz/tests/fuzz_main.c +55 -0
  250. package/thirdparty/miniz/tests/large_fuzzer.c +133 -0
  251. package/thirdparty/miniz/tests/main.cpp +185 -0
  252. package/thirdparty/miniz/tests/miniz_tdefl_fuzzer.cc +115 -0
  253. package/thirdparty/miniz/tests/miniz_tester.cpp +1881 -0
  254. package/thirdparty/miniz/tests/miniz_zip_validate_fuzzer.cc +71 -0
  255. package/thirdparty/miniz/tests/miniz_zip_writer_fuzzer.cc +96 -0
  256. package/thirdparty/miniz/tests/ossfuzz.sh +48 -0
  257. package/thirdparty/miniz/tests/small_fuzzer.c +126 -0
  258. package/thirdparty/miniz/tests/timer.cpp +152 -0
  259. package/thirdparty/miniz/tests/timer.h +40 -0
  260. package/thirdparty/miniz/tests/uncompress2_fuzzer.c +21 -0
  261. package/thirdparty/miniz/tests/uncompress_fuzzer.c +30 -0
  262. package/thirdparty/miniz/tests/zip.dict +9 -0
  263. package/thirdparty/miniz/tests/zip_fuzzer.c +63 -0
  264. package/thirdparty/pugixml/.codecov.yml +7 -0
  265. package/thirdparty/pugixml/.gitattributes +1 -0
  266. package/thirdparty/pugixml/CMakeLists.txt +330 -0
  267. package/thirdparty/pugixml/LICENSE.md +24 -0
  268. package/thirdparty/pugixml/Makefile +98 -0
  269. package/thirdparty/pugixml/README.md +81 -0
  270. package/thirdparty/pugixml/SECURITY.md +9 -0
  271. package/thirdparty/pugixml/appveyor.yml +50 -0
  272. package/thirdparty/pugixml/docs/config.adoc +7 -0
  273. package/thirdparty/pugixml/docs/images/dom_tree.png +0 -0
  274. package/thirdparty/pugixml/docs/images/vs2005_link1.png +0 -0
  275. package/thirdparty/pugixml/docs/images/vs2005_link2.png +0 -0
  276. package/thirdparty/pugixml/docs/images/vs2005_pch1.png +0 -0
  277. package/thirdparty/pugixml/docs/images/vs2005_pch2.png +0 -0
  278. package/thirdparty/pugixml/docs/images/vs2005_pch3.png +0 -0
  279. package/thirdparty/pugixml/docs/images/vs2005_pch4.png +0 -0
  280. package/thirdparty/pugixml/docs/images/vs2010_link1.png +0 -0
  281. package/thirdparty/pugixml/docs/images/vs2010_link2.png +0 -0
  282. package/thirdparty/pugixml/docs/manual.adoc +3326 -0
  283. package/thirdparty/pugixml/docs/manual.html +6395 -0
  284. package/thirdparty/pugixml/docs/quickstart.adoc +287 -0
  285. package/thirdparty/pugixml/docs/quickstart.html +1107 -0
  286. package/thirdparty/pugixml/docs/samples/character.xml +8 -0
  287. package/thirdparty/pugixml/docs/samples/custom_memory_management.cpp +27 -0
  288. package/thirdparty/pugixml/docs/samples/include.cpp +64 -0
  289. package/thirdparty/pugixml/docs/samples/load_error_handling.cpp +33 -0
  290. package/thirdparty/pugixml/docs/samples/load_file.cpp +16 -0
  291. package/thirdparty/pugixml/docs/samples/load_memory.cpp +66 -0
  292. package/thirdparty/pugixml/docs/samples/load_options.cpp +30 -0
  293. package/thirdparty/pugixml/docs/samples/load_stream.cpp +97 -0
  294. package/thirdparty/pugixml/docs/samples/modify_add.cpp +29 -0
  295. package/thirdparty/pugixml/docs/samples/modify_base.cpp +43 -0
  296. package/thirdparty/pugixml/docs/samples/modify_remove.cpp +27 -0
  297. package/thirdparty/pugixml/docs/samples/save_custom_writer.cpp +116 -0
  298. package/thirdparty/pugixml/docs/samples/save_declaration.cpp +27 -0
  299. package/thirdparty/pugixml/docs/samples/save_file.cpp +17 -0
  300. package/thirdparty/pugixml/docs/samples/save_options.cpp +48 -0
  301. package/thirdparty/pugixml/docs/samples/save_stream.cpp +18 -0
  302. package/thirdparty/pugixml/docs/samples/save_subtree.cpp +26 -0
  303. package/thirdparty/pugixml/docs/samples/text.cpp +35 -0
  304. package/thirdparty/pugixml/docs/samples/transitions.xml +7 -0
  305. package/thirdparty/pugixml/docs/samples/traverse_base.cpp +51 -0
  306. package/thirdparty/pugixml/docs/samples/traverse_iter.cpp +27 -0
  307. package/thirdparty/pugixml/docs/samples/traverse_predicate.cpp +48 -0
  308. package/thirdparty/pugixml/docs/samples/traverse_rangefor.cpp +32 -0
  309. package/thirdparty/pugixml/docs/samples/traverse_walker.cpp +35 -0
  310. package/thirdparty/pugixml/docs/samples/tree.xml +12 -0
  311. package/thirdparty/pugixml/docs/samples/weekly-shift_jis.xml +78 -0
  312. package/thirdparty/pugixml/docs/samples/weekly-utf-16.xml +0 -0
  313. package/thirdparty/pugixml/docs/samples/weekly-utf-8.xml +78 -0
  314. package/thirdparty/pugixml/docs/samples/xgconsole.xml +12 -0
  315. package/thirdparty/pugixml/docs/samples/xpath_error.cpp +43 -0
  316. package/thirdparty/pugixml/docs/samples/xpath_query.cpp +36 -0
  317. package/thirdparty/pugixml/docs/samples/xpath_select.cpp +28 -0
  318. package/thirdparty/pugixml/docs/samples/xpath_variables.cpp +38 -0
  319. package/thirdparty/pugixml/readme.txt +50 -0
  320. package/thirdparty/pugixml/scripts/archive.py +54 -0
  321. package/thirdparty/pugixml/scripts/cocoapods_push.sh +4 -0
  322. package/thirdparty/pugixml/scripts/natvis/pugixml.natvis +77 -0
  323. package/thirdparty/pugixml/scripts/natvis/pugixml_compact.natvis +506 -0
  324. package/thirdparty/pugixml/scripts/nuget/build/native/pugixml-propertiesui.xml +17 -0
  325. package/thirdparty/pugixml/scripts/nuget/build/native/pugixml.targets +28 -0
  326. package/thirdparty/pugixml/scripts/nuget/pugixml.nuspec +20 -0
  327. package/thirdparty/pugixml/scripts/nuget_build.ps1 +60 -0
  328. package/thirdparty/pugixml/scripts/premake4.lua +92 -0
  329. package/thirdparty/pugixml/scripts/pugixml-config.cmake.in +12 -0
  330. package/thirdparty/pugixml/scripts/pugixml.pc.in +11 -0
  331. package/thirdparty/pugixml/scripts/pugixml.podspec +14 -0
  332. package/thirdparty/pugixml/scripts/pugixml.xcodeproj/project.pbxproj +212 -0
  333. package/thirdparty/pugixml/scripts/pugixml_airplay.mkf +13 -0
  334. package/thirdparty/pugixml/scripts/pugixml_codeblocks.cbp +44 -0
  335. package/thirdparty/pugixml/scripts/pugixml_codelite.project +56 -0
  336. package/thirdparty/pugixml/scripts/pugixml_dll.rc +45 -0
  337. package/thirdparty/pugixml/scripts/pugixml_vs2005.vcproj +343 -0
  338. package/thirdparty/pugixml/scripts/pugixml_vs2005_static.vcproj +343 -0
  339. package/thirdparty/pugixml/scripts/pugixml_vs2008.vcproj +339 -0
  340. package/thirdparty/pugixml/scripts/pugixml_vs2008_static.vcproj +339 -0
  341. package/thirdparty/pugixml/scripts/pugixml_vs2010.vcxproj +191 -0
  342. package/thirdparty/pugixml/scripts/pugixml_vs2010_static.vcxproj +191 -0
  343. package/thirdparty/pugixml/scripts/pugixml_vs2013.vcxproj +199 -0
  344. package/thirdparty/pugixml/scripts/pugixml_vs2013_static.vcxproj +199 -0
  345. package/thirdparty/pugixml/scripts/pugixml_vs2015.vcxproj +172 -0
  346. package/thirdparty/pugixml/scripts/pugixml_vs2015_static.vcxproj +176 -0
  347. package/thirdparty/pugixml/scripts/pugixml_vs2017.vcxproj +172 -0
  348. package/thirdparty/pugixml/scripts/pugixml_vs2017_static.vcxproj +176 -0
  349. package/thirdparty/pugixml/scripts/pugixml_vs2019.vcxproj +176 -0
  350. package/thirdparty/pugixml/scripts/pugixml_vs2019_static.vcxproj +180 -0
  351. package/thirdparty/pugixml/scripts/pugixml_vs2022.vcxproj +176 -0
  352. package/thirdparty/pugixml/scripts/pugixml_vs2022_static.vcxproj +180 -0
  353. package/thirdparty/pugixml/scripts/pugixml_vs2026.vcxproj +176 -0
  354. package/thirdparty/pugixml/scripts/pugixml_vs2026_static.vcxproj +180 -0
  355. package/thirdparty/pugixml/scripts/sbom.cdx.json +47 -0
  356. package/thirdparty/pugixml/src/pugiconfig.hpp +81 -0
  357. package/thirdparty/pugixml/src/pugixml.cpp +13776 -0
  358. package/thirdparty/pugixml/src/pugixml.hpp +1604 -0
  359. package/thirdparty/pugixml/tests/allocator.cpp +175 -0
  360. package/thirdparty/pugixml/tests/allocator.hpp +10 -0
  361. package/thirdparty/pugixml/tests/autotest-appveyor.ps1 +93 -0
  362. package/thirdparty/pugixml/tests/cmake-appveyor.ps1 +57 -0
  363. package/thirdparty/pugixml/tests/data/empty.xml +0 -0
  364. package/thirdparty/pugixml/tests/data/large.xml +1 -0
  365. package/thirdparty/pugixml/tests/data/latintest_latin1.xml +1 -0
  366. package/thirdparty/pugixml/tests/data/latintest_utf8.xml +1 -0
  367. package/thirdparty/pugixml/tests/data/multiline.xml +3 -0
  368. package/thirdparty/pugixml/tests/data/small.xml +1 -0
  369. package/thirdparty/pugixml/tests/data/truncation.xml +19 -0
  370. package/thirdparty/pugixml/tests/data/utftest_utf16_be.xml +0 -0
  371. package/thirdparty/pugixml/tests/data/utftest_utf16_be_bom.xml +0 -0
  372. package/thirdparty/pugixml/tests/data/utftest_utf16_be_clean.xml +0 -0
  373. package/thirdparty/pugixml/tests/data/utftest_utf16_be_nodecl.xml +0 -0
  374. package/thirdparty/pugixml/tests/data/utftest_utf16_le.xml +0 -0
  375. package/thirdparty/pugixml/tests/data/utftest_utf16_le_bom.xml +0 -0
  376. package/thirdparty/pugixml/tests/data/utftest_utf16_le_clean.xml +0 -0
  377. package/thirdparty/pugixml/tests/data/utftest_utf16_le_nodecl.xml +0 -0
  378. package/thirdparty/pugixml/tests/data/utftest_utf32_be.xml +0 -0
  379. package/thirdparty/pugixml/tests/data/utftest_utf32_be_bom.xml +0 -0
  380. package/thirdparty/pugixml/tests/data/utftest_utf32_be_clean.xml +0 -0
  381. package/thirdparty/pugixml/tests/data/utftest_utf32_be_nodecl.xml +0 -0
  382. package/thirdparty/pugixml/tests/data/utftest_utf32_le.xml +0 -0
  383. package/thirdparty/pugixml/tests/data/utftest_utf32_le_bom.xml +0 -0
  384. package/thirdparty/pugixml/tests/data/utftest_utf32_le_clean.xml +0 -0
  385. package/thirdparty/pugixml/tests/data/utftest_utf32_le_nodecl.xml +0 -0
  386. package/thirdparty/pugixml/tests/data/utftest_utf8.xml +87 -0
  387. package/thirdparty/pugixml/tests/data/utftest_utf8_bom.xml +87 -0
  388. package/thirdparty/pugixml/tests/data/utftest_utf8_clean.xml +84 -0
  389. package/thirdparty/pugixml/tests/data/utftest_utf8_nodecl.xml +86 -0
  390. package/thirdparty/pugixml/tests/data//321/202/320/265/321/201/321/202.xml +1 -0
  391. package/thirdparty/pugixml/tests/data_fuzz_parse/basic.xml +1 -0
  392. package/thirdparty/pugixml/tests/data_fuzz_parse/doctype.xml +1 -0
  393. package/thirdparty/pugixml/tests/data_fuzz_parse/refs.xml +1 -0
  394. package/thirdparty/pugixml/tests/data_fuzz_parse/types.xml +1 -0
  395. package/thirdparty/pugixml/tests/data_fuzz_parse/utf16.xml +0 -0
  396. package/thirdparty/pugixml/tests/data_fuzz_parse/utf32.xml +0 -0
  397. package/thirdparty/pugixml/tests/data_fuzz_xpath/basic.xpath +1 -0
  398. package/thirdparty/pugixml/tests/data_fuzz_xpath/functions.xpath +1 -0
  399. package/thirdparty/pugixml/tests/data_fuzz_xpath/math.xpath +1 -0
  400. package/thirdparty/pugixml/tests/data_fuzz_xpath/path.xpath +1 -0
  401. package/thirdparty/pugixml/tests/data_fuzz_xpath/predicate.xpath +1 -0
  402. package/thirdparty/pugixml/tests/fuzz_parse.cpp +14 -0
  403. package/thirdparty/pugixml/tests/fuzz_parse.dict +72 -0
  404. package/thirdparty/pugixml/tests/fuzz_setup.sh +11 -0
  405. package/thirdparty/pugixml/tests/fuzz_xpath.cpp +46 -0
  406. package/thirdparty/pugixml/tests/fuzz_xpath.dict +72 -0
  407. package/thirdparty/pugixml/tests/helpers.hpp +114 -0
  408. package/thirdparty/pugixml/tests/main.cpp +218 -0
  409. package/thirdparty/pugixml/tests/test.cpp +220 -0
  410. package/thirdparty/pugixml/tests/test.hpp +175 -0
  411. package/thirdparty/pugixml/tests/test_compact.cpp +150 -0
  412. package/thirdparty/pugixml/tests/test_deprecated.cpp +25 -0
  413. package/thirdparty/pugixml/tests/test_document.cpp +1910 -0
  414. package/thirdparty/pugixml/tests/test_dom_modify.cpp +2122 -0
  415. package/thirdparty/pugixml/tests/test_dom_text.cpp +601 -0
  416. package/thirdparty/pugixml/tests/test_dom_traverse.cpp +1481 -0
  417. package/thirdparty/pugixml/tests/test_header_guard.cpp +3 -0
  418. package/thirdparty/pugixml/tests/test_header_iosfwd_1.cpp +3 -0
  419. package/thirdparty/pugixml/tests/test_header_iosfwd_2.cpp +3 -0
  420. package/thirdparty/pugixml/tests/test_header_iostream_1.cpp +3 -0
  421. package/thirdparty/pugixml/tests/test_header_iostream_2.cpp +3 -0
  422. package/thirdparty/pugixml/tests/test_header_only_1.cpp +21 -0
  423. package/thirdparty/pugixml/tests/test_header_only_2.cpp +21 -0
  424. package/thirdparty/pugixml/tests/test_header_string_1.cpp +3 -0
  425. package/thirdparty/pugixml/tests/test_header_string_2.cpp +3 -0
  426. package/thirdparty/pugixml/tests/test_header_string_iostream.cpp +5 -0
  427. package/thirdparty/pugixml/tests/test_memory.cpp +303 -0
  428. package/thirdparty/pugixml/tests/test_parse.cpp +1463 -0
  429. package/thirdparty/pugixml/tests/test_parse_doctype.cpp +366 -0
  430. package/thirdparty/pugixml/tests/test_unicode.cpp +152 -0
  431. package/thirdparty/pugixml/tests/test_version.cpp +5 -0
  432. package/thirdparty/pugixml/tests/test_write.cpp +757 -0
  433. package/thirdparty/pugixml/tests/test_xpath.cpp +833 -0
  434. package/thirdparty/pugixml/tests/test_xpath_api.cpp +646 -0
  435. package/thirdparty/pugixml/tests/test_xpath_functions.cpp +844 -0
  436. package/thirdparty/pugixml/tests/test_xpath_operators.cpp +566 -0
  437. package/thirdparty/pugixml/tests/test_xpath_parse.cpp +428 -0
  438. package/thirdparty/pugixml/tests/test_xpath_paths.cpp +787 -0
  439. package/thirdparty/pugixml/tests/test_xpath_paths_abbrev_w3c.cpp +219 -0
  440. package/thirdparty/pugixml/tests/test_xpath_paths_w3c.cpp +312 -0
  441. package/thirdparty/pugixml/tests/test_xpath_variables.cpp +683 -0
  442. package/thirdparty/pugixml/tests/test_xpath_xalan_1.cpp +411 -0
  443. package/thirdparty/pugixml/tests/test_xpath_xalan_2.cpp +417 -0
  444. package/thirdparty/pugixml/tests/test_xpath_xalan_3.cpp +321 -0
  445. package/thirdparty/pugixml/tests/test_xpath_xalan_4.cpp +300 -0
  446. package/thirdparty/pugixml/tests/test_xpath_xalan_5.cpp +295 -0
  447. package/thirdparty/pugixml/tests/writer_string.cpp +79 -0
  448. package/thirdparty/pugixml/tests/writer_string.hpp +27 -0
  449. package/scripts/prepare-openxlsx.js +0 -126
@@ -0,0 +1,918 @@
1
+ /*
2
+
3
+ ____ ____ ___ ____ ____ ____ ___
4
+ 6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
5
+ 8P Y8 `MM. d' MM 6M' ` `MM. d'
6
+ 6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
7
+ MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
8
+ MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
9
+ MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
10
+ MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
11
+ YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
12
+ 8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
13
+ YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
14
+ MM
15
+ MM
16
+ _MM_
17
+
18
+ Copyright (c) 2018, Kenneth Troldal Balslev
19
+
20
+ All rights reserved.
21
+
22
+ Redistribution and use in source and binary forms, with or without
23
+ modification, are permitted provided that the following conditions are met:
24
+ - Redistributions of source code must retain the above copyright
25
+ notice, this list of conditions and the following disclaimer.
26
+ - Redistributions in binary form must reproduce the above copyright
27
+ notice, this list of conditions and the following disclaimer in the
28
+ documentation and/or other materials provided with the distribution.
29
+ - Neither the name of the author nor the
30
+ names of any contributors may be used to endorse or promote products
31
+ derived from this software without specific prior written permission.
32
+
33
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
34
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36
+ DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
40
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43
+
44
+ */
45
+
46
+ // ===== External Includes ===== //
47
+
48
+ // ===== OpenXLSX Includes ===== //
49
+ #include "XLCell.hpp"
50
+ #include "XLCellIterator.hpp"
51
+ #include "XLCellReference.hpp"
52
+ #include "XLRow.hpp"
53
+ #include "XLStyles.hpp" // XLDefaultCellFormat
54
+ #include "XLXmlParser.hpp" // pugixml wrapper
55
+ #include "utilities/XLUtilities.hpp"
56
+
57
+ // ========== XLRow ======================================================== //
58
+ namespace OpenXLSX
59
+ {
60
+ /**
61
+ * @details
62
+ * @pre
63
+ * @post
64
+ */
65
+ XLRow::XLRow()
66
+ : m_rowNode(nullptr),
67
+ m_sharedStrings(XLSharedStringsDefaulted),
68
+ m_rowDataProxy(this, m_rowNode.get())
69
+ {}
70
+
71
+ /**
72
+ * @details Constructs a new XLRow object from information in the underlying XML file. A pointer to the corresponding
73
+ * node in the underlying XML file must be provided.
74
+ * @pre
75
+ * @post
76
+ */
77
+ XLRow::XLRow(const XMLNode& rowNode, const XLSharedStrings& sharedStrings)
78
+ : m_rowNode(std::make_unique<XMLNode>(rowNode)),
79
+ m_sharedStrings(sharedStrings),
80
+ m_rowDataProxy(this, m_rowNode.get())
81
+ {}
82
+
83
+ /**
84
+ * @details
85
+ * @pre
86
+ * @post
87
+ */
88
+ XLRow::XLRow(const XLRow& other)
89
+ : m_rowNode(other.m_rowNode ? std::make_unique<XMLNode>(*other.m_rowNode) : nullptr),
90
+ m_sharedStrings(other.m_sharedStrings),
91
+ m_rowDataProxy(this, m_rowNode.get())
92
+ {}
93
+
94
+ /**
95
+ * @details Because the m_rowDataProxy variable is tied to an exact XLRow object, the move operation is
96
+ * not a 'pure' move, as a new XLRowDataProxy has to be constructed.
97
+ * @pre
98
+ * @post
99
+ */
100
+ XLRow::XLRow(XLRow&& other) noexcept
101
+ : m_rowNode(std::move(other.m_rowNode)),
102
+ m_sharedStrings(std::move(other.m_sharedStrings)),
103
+ m_rowDataProxy(this, m_rowNode.get())
104
+ {}
105
+
106
+ /**
107
+ * @details
108
+ * @pre
109
+ * @post
110
+ */
111
+ XLRow::~XLRow() = default;
112
+
113
+ /**
114
+ * @details
115
+ * @pre
116
+ * @post
117
+ */
118
+ XLRow& XLRow::operator=(const XLRow& other)
119
+ {
120
+ if (&other != this) {
121
+ XLRow temp = XLRow(other);
122
+ std::swap(*this, temp);
123
+ }
124
+ return *this;
125
+ }
126
+
127
+ /**
128
+ * @details Because the m_rowDataProxy variable is tied to an exact XLRow object, the move operation is
129
+ * not a 'pure' move, as a new XLRowDataProxy has to be constructed.
130
+ * @pre
131
+ * @post
132
+ */
133
+ XLRow& XLRow::operator=(XLRow&& other) noexcept
134
+ {
135
+ if (&other != this) {
136
+ m_rowNode = std::move(other.m_rowNode);
137
+ m_sharedStrings = std::move(other.m_sharedStrings);
138
+ m_rowDataProxy = XLRowDataProxy(this, m_rowNode.get());
139
+ }
140
+ return *this;
141
+ }
142
+
143
+ /**
144
+ * @details
145
+ */
146
+ bool XLRow::empty() const { return (!m_rowNode) || m_rowNode->empty(); }
147
+
148
+ /**
149
+ * @details
150
+ */
151
+ XLRow::operator bool() const { return m_rowNode && (not m_rowNode->empty() ); }
152
+
153
+ /**
154
+ * @details Returns the m_height member by getValue.
155
+ * @pre
156
+ * @post
157
+ */
158
+ double XLRow::height() const
159
+ {
160
+ return m_rowNode->attribute("ht").as_double(15.0); // NOLINT
161
+ }
162
+
163
+ /**
164
+ * @details Set the height of the row. This is done by setting the getValue of the 'ht' attribute and setting the
165
+ * 'customHeight' attribute to true.
166
+ * @pre
167
+ * @post
168
+ */
169
+ void XLRow::setHeight(float height) // NOLINT
170
+ {
171
+ // Set the 'ht' attribute for the Cell. If it does not exist, create it.
172
+ if (m_rowNode->attribute("ht").empty())
173
+ m_rowNode->append_attribute("ht") = height;
174
+ else
175
+ m_rowNode->attribute("ht").set_value(height);
176
+
177
+ // Set the 'customHeight' attribute. If it does not exist, create it.
178
+ if (m_rowNode->attribute("customHeight").empty())
179
+ m_rowNode->append_attribute("customHeight") = 1;
180
+ else
181
+ m_rowNode->attribute("customHeight").set_value(1);
182
+ }
183
+
184
+ /**
185
+ * @details Return the m_descent member by getValue.
186
+ * @pre
187
+ * @post
188
+ */
189
+ float XLRow::descent() const
190
+ {
191
+ return m_rowNode->attribute("x14ac:dyDescent").as_float(0.25); // NOLINT
192
+ }
193
+
194
+ /**
195
+ * @details Set the descent by setting the 'x14ac:dyDescent' attribute in the XML file
196
+ * @pre
197
+ * @post
198
+ */
199
+ void XLRow::setDescent(float descent)
200
+ {
201
+ // Set the 'x14ac:dyDescent' attribute. If it does not exist, create it.
202
+ if (m_rowNode->attribute("x14ac:dyDescent").empty())
203
+ m_rowNode->append_attribute("x14ac:dyDescent") = descent;
204
+ else
205
+ m_rowNode->attribute("x14ac:dyDescent") = descent;
206
+ }
207
+
208
+ /**
209
+ * @details Determine if the row is hidden or not.
210
+ * @pre
211
+ * @post
212
+ */
213
+ bool XLRow::isHidden() const { return m_rowNode->attribute("hidden").as_bool(false); }
214
+
215
+ /**
216
+ * @details Set the hidden state by setting the 'hidden' attribute to true or false.
217
+ * @pre
218
+ * @post
219
+ */
220
+ void XLRow::setHidden(bool state) // NOLINT
221
+ {
222
+ // Set the 'hidden' attribute. If it does not exist, create it.
223
+ if (m_rowNode->attribute("hidden").empty())
224
+ m_rowNode->append_attribute("hidden") = static_cast<int>(state);
225
+ else
226
+ m_rowNode->attribute("hidden").set_value(static_cast<int>(state));
227
+ }
228
+
229
+ /**
230
+ * @details
231
+ * @pre
232
+ * @post
233
+ * @note 2024-08-18: changed return type of rowNumber to uint32_t
234
+ * CAUTION: there is no validity check on the underlying XML (nor was there ever one in case a value was inconsistent with OpenXLSX::MAX_ROWS)
235
+ */
236
+ uint32_t XLRow::rowNumber() const { return static_cast<uint32_t>(m_rowNode->attribute("r").as_ullong()); }
237
+
238
+ /**
239
+ * @details Get the number of cells in the row, by returning the size of the m_cells vector.
240
+ * @pre
241
+ * @post
242
+ */
243
+ uint16_t XLRow::cellCount() const
244
+ {
245
+ const auto node = m_rowNode->last_child_of_type(pugi::node_element);
246
+ if (node.empty()) return 0;
247
+ return XLCellReference(node.attribute("r").value()).column();
248
+ }
249
+
250
+ /**
251
+ * @details
252
+ * @pre
253
+ * @post
254
+ */
255
+ XLRowDataProxy& XLRow::values() { return m_rowDataProxy; }
256
+
257
+ /**
258
+ * @details
259
+ * @pre
260
+ * @post
261
+ */
262
+ const XLRowDataProxy& XLRow::values() const { return m_rowDataProxy; }
263
+
264
+ /**
265
+ * @details
266
+ * @pre
267
+ * @post
268
+ */
269
+ XLRowDataRange XLRow::cells() const
270
+ {
271
+ const XMLNode node = m_rowNode->last_child_of_type(pugi::node_element);
272
+ if (node.empty()) return XLRowDataRange(); // empty range
273
+ return XLRowDataRange(*m_rowNode, 1, XLCellReference(node.attribute("r").value()).column(), m_sharedStrings.get());
274
+ }
275
+
276
+ /**
277
+ * @details
278
+ * @pre
279
+ * @post
280
+ */
281
+ XLRowDataRange XLRow::cells(uint16_t cellCount) const { return XLRowDataRange(*m_rowNode, 1, cellCount, m_sharedStrings.get()); }
282
+
283
+ /**
284
+ * @details
285
+ * @pre
286
+ * @post
287
+ */
288
+ XLRowDataRange XLRow::cells(uint16_t firstCell, uint16_t lastCell) const
289
+ {
290
+ return XLRowDataRange(*m_rowNode, firstCell, lastCell, m_sharedStrings.get());
291
+ }
292
+
293
+ /**
294
+ * @details Find & return a cell in indicated column
295
+ */
296
+ XLCell XLRow::findCell(uint16_t columnNumber)
297
+ {
298
+ if (m_rowNode->empty()) return XLCell{};
299
+
300
+ XMLNode cellNode = m_rowNode->last_child_of_type(pugi::node_element);
301
+
302
+ // ===== If there are no cells in the current row, or the requested cell is beyond the last cell in the row...
303
+ if (cellNode.empty() || (XLCellReference(cellNode.attribute("r").value()).column() < columnNumber))
304
+ return XLCell{}; // fail
305
+
306
+ // ===== If the requested node is closest to the end, start from the end and search backwards...
307
+ if (XLCellReference(cellNode.attribute("r").value()).column() - columnNumber < columnNumber) {
308
+ while (not cellNode.empty() && (XLCellReference(cellNode.attribute("r").value()).column() > columnNumber))
309
+ cellNode = cellNode.previous_sibling_of_type(pugi::node_element);
310
+ // ===== If the backwards search failed to locate the requested cell
311
+ if (cellNode.empty() || (XLCellReference(cellNode.attribute("r").value()).column() < columnNumber))
312
+ return XLCell{}; // fail
313
+ }
314
+ // ===== Otherwise, start from the beginning
315
+ else {
316
+ // ===== At this point, it is guaranteed that there is at least one node_element in the row that is not empty.
317
+ cellNode = m_rowNode->first_child_of_type(pugi::node_element);
318
+
319
+ // ===== It has been verified above that the requested columnNumber is <= the column number of the last node_element, therefore this loop will halt:
320
+ while (XLCellReference(cellNode.attribute("r").value()).column() < columnNumber)
321
+ cellNode = cellNode.next_sibling_of_type(pugi::node_element);
322
+ // ===== If the forwards search failed to locate the requested cell
323
+ if (XLCellReference(cellNode.attribute("r").value()).column() > columnNumber)
324
+ return XLCell{}; // fail
325
+ }
326
+ return XLCell(cellNode, m_sharedStrings.get());
327
+ }
328
+
329
+ /**
330
+ * @details Determine the value of the style attribute "s" - if attribute does not exist, return default value
331
+ */
332
+ XLStyleIndex XLRow::format() const { return m_rowNode->attribute("s").as_uint(XLDefaultCellFormat); }
333
+
334
+ /**
335
+ * @brief Set the row style as a reference to the array index of xl/styles.xml:<styleSheet>:<cellXfs>
336
+ * If the style attribute "s" does not exist, create it
337
+ */
338
+ bool XLRow::setFormat(XLStyleIndex cellFormatIndex)
339
+ {
340
+ XMLAttribute customFormatAtt = m_rowNode->attribute("customFormat");
341
+ if (cellFormatIndex != XLDefaultCellFormat) {
342
+ if (customFormatAtt.empty()) {
343
+ customFormatAtt = m_rowNode->append_attribute("customFormat");
344
+ if (customFormatAtt.empty()) return false; // fail if missing customFormat attribute could not be created
345
+ }
346
+ customFormatAtt.set_value("true");
347
+ }
348
+ else { // cellFormatIndex is XLDefaultCellFormat
349
+ if (not customFormatAtt.empty()) m_rowNode->remove_attribute(customFormatAtt); // an existing customFormat attribute should be deleted
350
+ }
351
+
352
+ XMLAttribute styleAtt = m_rowNode->attribute("s");
353
+ if (styleAtt.empty()) {
354
+ styleAtt = m_rowNode->append_attribute("s");
355
+ if (styleAtt.empty()) return false;
356
+ }
357
+ styleAtt.set_value(cellFormatIndex);
358
+
359
+ return true;
360
+ }
361
+
362
+
363
+ // ---------- Private Member Functions ---------- //
364
+
365
+ bool XLRow::isEqual(const XLRow& lhs, const XLRow& rhs)
366
+ {
367
+ // 2024-05-28 BUGFIX: (!lhs.m_rowNode && rhs.m_rowNode) was not evaluated, triggering a segmentation fault on dereferencing
368
+ if (static_cast<bool>(lhs.m_rowNode) != static_cast<bool>(rhs.m_rowNode)) return false;
369
+ // ===== If execution gets here, row nodes are BOTH valid or BOTH invalid / empty
370
+ if (not lhs.m_rowNode) return true; // checking one for being empty is enough to know both are empty
371
+ return *lhs.m_rowNode == *rhs.m_rowNode;
372
+ }
373
+
374
+ bool XLRow::isLessThan(const XLRow& lhs, const XLRow& rhs) { return *lhs.m_rowNode < *rhs.m_rowNode; }
375
+
376
+ } // namespace OpenXLSX
377
+
378
+ // ========== XLRowIterator and XLRowReverseIterator ======================== //
379
+ namespace OpenXLSX
380
+ {
381
+ // ===== XLRowIterator
382
+ /**
383
+ * @details
384
+ * @pre
385
+ * @post
386
+ */
387
+ XLRowIterator::XLRowIterator(const XLRowRange& rowRange, XLIteratorLocation loc)
388
+ : m_dataNode(std::make_unique<XMLNode>(*rowRange.m_dataNode)),
389
+ m_firstRow(rowRange.m_firstRow),
390
+ m_lastRow(rowRange.m_lastRow),
391
+ m_currentRow(),
392
+ m_sharedStrings(rowRange.m_sharedStrings),
393
+ m_endReached(false),
394
+ m_hintRow(std::make_unique<XMLNode>()),
395
+ m_hintRowNumber(0),
396
+ m_currentRowStatus(XLNotLoaded),
397
+ m_currentRowNumber(0)
398
+ {
399
+ if (loc == XLIteratorLocation::End)
400
+ m_endReached = true;
401
+ else {
402
+ m_currentRowNumber = m_firstRow;
403
+ }
404
+ }
405
+
406
+ /**
407
+ * @details explicit default destructor
408
+ */
409
+ XLRowIterator::~XLRowIterator() = default;
410
+
411
+ /**
412
+ * @details copy constructor
413
+ */
414
+ XLRowIterator::XLRowIterator(const XLRowIterator& other)
415
+ : m_dataNode(std::make_unique<XMLNode>(*other.m_dataNode)),
416
+ m_firstRow(other.m_firstRow),
417
+ m_lastRow(other.m_lastRow),
418
+ m_currentRow(other.m_currentRow),
419
+ m_sharedStrings(other.m_sharedStrings),
420
+ m_endReached(other.m_endReached),
421
+ m_hintRow(std::make_unique<XMLNode>(*other.m_hintRow)),
422
+ m_hintRowNumber(other.m_hintRowNumber),
423
+ m_currentRowStatus(other.m_currentRowStatus),
424
+ m_currentRowNumber(other.m_currentRowNumber)
425
+ {}
426
+
427
+ /**
428
+ * @details explicit default move constructor
429
+ */
430
+ XLRowIterator::XLRowIterator(XLRowIterator&& other) noexcept = default;
431
+
432
+ /**
433
+ * @details copy assignment operator
434
+ */
435
+ XLRowIterator& XLRowIterator::operator=(const XLRowIterator& other)
436
+ {
437
+ if (&other != this) {
438
+ XLRowIterator temp = XLRowIterator(other);
439
+ std::swap(*this, temp);
440
+ }
441
+ return *this;
442
+ }
443
+
444
+ /**
445
+ * @details explicit default move assignment operator
446
+ */
447
+ XLRowIterator& XLRowIterator::operator=(XLRowIterator&& other) noexcept = default;
448
+
449
+ /**
450
+ * @brief update m_currentRow by fetching (or inserting) a row at m_currentRowNumber
451
+ */
452
+ void XLRowIterator::updateCurrentRow(bool createIfMissing)
453
+ {
454
+ // ===== Quick exit checks - can't be true when m_endReached
455
+ if (m_currentRowStatus == XLLoaded) return; // nothing to do, row is already loaded
456
+ if (!createIfMissing && m_currentRowStatus == XLNoSuchRow) return; // nothing to do, row has already been determined as missing
457
+
458
+ // ===== At this stage, m_currentRowStatus is XLUnloaded or XLNoSuchRow and createIfMissing == true
459
+
460
+ if (m_endReached)
461
+ throw XLInputError("XLRowIterator updateCurrentRow: iterator should not be dereferenced when endReached() == true");
462
+
463
+ // ===== Row needs to be updated
464
+
465
+ if (m_hintRow->empty()) { // no hint has been established: fetch first row node the "tedious" way
466
+ if (createIfMissing) // getRowNode creates missing rows
467
+ m_currentRow = XLRow(getRowNode(*m_dataNode, m_currentRowNumber), m_sharedStrings.get());
468
+ else // findRowNode returns an empty row for missing rows
469
+ m_currentRow = XLRow(findRowNode(*m_dataNode, m_currentRowNumber), m_sharedStrings.get());
470
+ }
471
+ else {
472
+ // ===== Find or create, and fetch an XLRow at m_currentRowNumber
473
+ if (m_currentRowNumber > m_hintRowNumber) {
474
+ // ===== Start from m_hintRow and search forwards...
475
+ XMLNode rowNode = m_hintRow->next_sibling_of_type(pugi::node_element);
476
+ uint32_t rowNo = 0;
477
+ while (not rowNode.empty()) {
478
+ rowNo = rowNode.attribute("r").as_ullong();
479
+ if (rowNo >= m_currentRowNumber) break; // if desired row was reached / passed, break before incrementing rowNode
480
+ rowNode = rowNode.next_sibling_of_type(pugi::node_element);
481
+ }
482
+ if (rowNo != m_currentRowNumber) rowNode = XMLNode{}; // if a higher row number was found, set empty node (means: "missing")
483
+
484
+ // ===== Create missing row node if createIfMissing == true
485
+ if (createIfMissing && rowNode.empty()) {
486
+ rowNode = m_dataNode->insert_child_after("row", *m_hintRow);
487
+ rowNode.append_attribute("r").set_value(m_currentRowNumber);
488
+ }
489
+ if (rowNode.empty()) // if row could not be found / created
490
+ m_currentRow = XLRow{}; // make sure m_currentRow is set to an empty cell
491
+ else
492
+ m_currentRow = XLRow(rowNode, m_sharedStrings.get());
493
+ }
494
+ else
495
+ throw XLInternalError("XLRowIterator::updateCurrentRow: an internal error occured (m_currentRowNumber <= m_hintRowNumber)");
496
+ }
497
+
498
+ if (m_currentRow.empty()) // if row is confirmed missing
499
+ m_currentRowStatus = XLNoSuchRow; // mark this status for further calls to updateCurrentRow()
500
+ else {
501
+ // ===== If the current row exists, update the hints
502
+ m_hintRow = std::make_unique<XMLNode>(*m_currentRow.m_rowNode); // don't store a full XLRow, just the XMLNode, for better performance
503
+ m_hintRowNumber = m_currentRowNumber;
504
+ m_currentRowStatus = XLLoaded; // mark row status for further calls to updateCurrentRow()
505
+ }
506
+ }
507
+
508
+ /**
509
+ * @details
510
+ * @pre
511
+ * @post
512
+ */
513
+ XLRowIterator& XLRowIterator::operator++() // 2024-04-29: patched for whitespace
514
+ {
515
+ if (m_endReached)
516
+ throw XLInputError("XLRowIterator: tried to increment beyond end operator");
517
+
518
+ if(m_currentRowNumber < m_lastRow)
519
+ ++m_currentRowNumber;
520
+ else
521
+ m_endReached = true;
522
+
523
+ m_currentRowStatus = XLNotLoaded; // trigger a new attempt to locate / create the row via updateRowCell
524
+
525
+ return *this;
526
+ }
527
+
528
+ /**
529
+ * @details
530
+ * @pre
531
+ * @post
532
+ */
533
+ XLRowIterator XLRowIterator::operator++(int) // NOLINT
534
+ {
535
+ auto oldIter(*this);
536
+ ++(*this);
537
+ return oldIter;
538
+ }
539
+
540
+ /**
541
+ * @details
542
+ * @pre
543
+ * @post
544
+ */
545
+ XLRow& XLRowIterator::operator*()
546
+ {
547
+ updateCurrentRow(XLCreateIfMissing);
548
+ return m_currentRow;
549
+ }
550
+
551
+ /**
552
+ * @details
553
+ * @pre
554
+ * @post
555
+ */
556
+ XLRowIterator::pointer XLRowIterator::operator->()
557
+ {
558
+ updateCurrentRow(XLCreateIfMissing);
559
+ return &m_currentRow;
560
+ }
561
+
562
+ /**
563
+ * @details
564
+ * @pre
565
+ * @post
566
+ */
567
+ bool XLRowIterator::operator==(const XLRowIterator& rhs) const
568
+ {
569
+ if (m_endReached && rhs.m_endReached) return true; // If both iterators are end iterators
570
+
571
+ if (m_currentRowNumber != rhs.m_currentRowNumber) // If iterators point to a different row
572
+ return false; // that means no match
573
+
574
+ // CAUTION: for performance reasons, disabled all checks whether this and rhs are iterators on the same worksheet & row range
575
+ return true;
576
+
577
+ // if (*m_dataNode != *rhs.m_dataNode) return false; // TBD: iterators over different worksheets may never match
578
+ // TBD if iterators shall be considered not equal if they were created on different XLRowRanges
579
+ // this would require checking the m_firstRow and m_lastRow, potentially costing CPU time
580
+
581
+ // return m_currentRow == rhs.m_currentRow; // match only if row nodes are equal
582
+ // CAUTION: in the current code, that means iterators that point to the same row in different worksheets,
583
+ // and rows that do not exist in both sheets, will be considered equal
584
+ }
585
+
586
+ /**
587
+ * @details
588
+ * @pre
589
+ * @post
590
+ */
591
+ bool XLRowIterator::operator!=(const XLRowIterator& rhs) const { return !(*this == rhs); }
592
+
593
+ /**
594
+ * @details
595
+ * @pre
596
+ * @post
597
+ */
598
+ XLRowIterator::operator bool() const { return false; }
599
+
600
+ /**
601
+ * @details
602
+ */
603
+ bool XLRowIterator::rowExists()
604
+ {
605
+ // ===== Update m_currentRow once so that rowExists will always test the correct cell (an empty row if current row doesn't exist)
606
+ updateCurrentRow(XLDoNotCreateIfMissing);
607
+ return not m_currentRow.empty();
608
+ }
609
+
610
+ // ===== XLRowReverseIterator
611
+ /**
612
+ * @details
613
+ * @pre
614
+ * @post
615
+ */
616
+ XLRowReverseIterator::XLRowReverseIterator(const XLRowRange& rowRange, XLIteratorLocation loc)
617
+ : m_dataNode(std::make_unique<XMLNode>(*rowRange.m_dataNode)),
618
+ m_firstRow(rowRange.m_firstRow),
619
+ m_lastRow(rowRange.m_lastRow),
620
+ m_currentRow(),
621
+ m_sharedStrings(rowRange.m_sharedStrings),
622
+ m_endReached(false),
623
+ m_hintRow(std::make_unique<XMLNode>()),
624
+ m_hintRowNumber(0),
625
+ m_currentRowStatus(XLNotLoaded),
626
+ m_currentRowNumber(0)
627
+ {
628
+ if (loc == XLIteratorLocation::End)
629
+ m_endReached = true;
630
+ else {
631
+ m_currentRowNumber = m_lastRow;
632
+ }
633
+ }
634
+
635
+ /**
636
+ * @details explicit default destructor
637
+ */
638
+ XLRowReverseIterator::~XLRowReverseIterator() = default;
639
+
640
+ /**
641
+ * @details copy constructor
642
+ */
643
+ XLRowReverseIterator::XLRowReverseIterator(const XLRowReverseIterator& other)
644
+ : m_dataNode(std::make_unique<XMLNode>(*other.m_dataNode)),
645
+ m_firstRow(other.m_firstRow),
646
+ m_lastRow(other.m_lastRow),
647
+ m_currentRow(other.m_currentRow),
648
+ m_sharedStrings(other.m_sharedStrings),
649
+ m_endReached(other.m_endReached),
650
+ m_hintRow(std::make_unique<XMLNode>(*other.m_hintRow)),
651
+ m_hintRowNumber(other.m_hintRowNumber),
652
+ m_currentRowStatus(other.m_currentRowStatus),
653
+ m_currentRowNumber(other.m_currentRowNumber)
654
+ {}
655
+
656
+ /**
657
+ * @details explicit default move constructor
658
+ */
659
+ XLRowReverseIterator::XLRowReverseIterator(XLRowReverseIterator&& other) noexcept = default;
660
+
661
+ /**
662
+ * @details copy assignment operator
663
+ */
664
+ XLRowReverseIterator& XLRowReverseIterator::operator=(const XLRowReverseIterator& other)
665
+ {
666
+ if (&other != this) {
667
+ XLRowReverseIterator temp = XLRowReverseIterator(other);
668
+ std::swap(*this, temp);
669
+ }
670
+ return *this;
671
+ }
672
+
673
+ /**
674
+ * @details explicit default move assignment operator
675
+ */
676
+ XLRowReverseIterator& XLRowReverseIterator::operator=(XLRowReverseIterator&& other) noexcept = default;
677
+
678
+ /**
679
+ * @brief update m_currentRow by fetching (or inserting) a row at m_currentRowNumber
680
+ */
681
+ void XLRowReverseIterator::updateCurrentRow(bool createIfMissing)
682
+ {
683
+ // ===== Quick exit checks - can't be true when m_endReached
684
+ if (m_currentRowStatus == XLLoaded) return; // nothing to do, row is already loaded
685
+ if (!createIfMissing && m_currentRowStatus == XLNoSuchRow) return; // nothing to do, row has already been determined as missing
686
+
687
+ // ===== At this stage, m_currentRowStatus is XLUnloaded or XLNoSuchRow and createIfMissing == true
688
+
689
+ if (m_endReached)
690
+ throw XLInputError("XLRowReverseIterator updateCurrentRow: iterator should not be dereferenced when endReached() == true");
691
+
692
+ // ===== Row needs to be updated
693
+
694
+ if (m_hintRow->empty()) { // no hint has been established: fetch first row node the "tedious" way
695
+ if (createIfMissing) // getRowNode creates missing rows
696
+ m_currentRow = XLRow(getRowNode(*m_dataNode, m_currentRowNumber), m_sharedStrings.get());
697
+ else // findRowNode returns an empty row for missing rows
698
+ m_currentRow = XLRow(findRowNode(*m_dataNode, m_currentRowNumber), m_sharedStrings.get());
699
+ }
700
+ else {
701
+ // ===== Find or create, and fetch an XLRow at m_currentRowNumber
702
+ if (m_currentRowNumber < m_hintRowNumber) {
703
+ // ===== Start from m_hintRow and search backwards...
704
+ XMLNode rowNode = m_hintRow->previous_sibling_of_type(pugi::node_element);
705
+ uint32_t rowNo = 0;
706
+ while (not rowNode.empty()) {
707
+ rowNo = rowNode.attribute("r").as_ullong();
708
+ if (rowNo <= m_currentRowNumber) break; // if desired row was reached / passed, break before decrementing rowNode
709
+ rowNode = rowNode.previous_sibling_of_type(pugi::node_element);
710
+ }
711
+ if (rowNo != m_currentRowNumber) rowNode = XMLNode{}; // if a lower row number was found, set empty node (means: "missing")
712
+
713
+ // ===== Create missing row node if createIfMissing == true
714
+ if (createIfMissing && rowNode.empty()) {
715
+ rowNode = m_dataNode->insert_child_before("row", *m_hintRow);
716
+ rowNode.append_attribute("r").set_value(m_currentRowNumber);
717
+ }
718
+ if (rowNode.empty()) // if row could not be found / created
719
+ m_currentRow = XLRow{}; // make sure m_currentRow is set to an empty cell
720
+ else
721
+ m_currentRow = XLRow(rowNode, m_sharedStrings.get());
722
+ }
723
+ else
724
+ throw XLInternalError("XLRowReverseIterator::updateCurrentRow: an internal error occured (m_currentRowNumber >= m_hintRowNumber)");
725
+ }
726
+
727
+ if (m_currentRow.empty()) // if row is confirmed missing
728
+ m_currentRowStatus = XLNoSuchRow; // mark this status for further calls to updateCurrentRow()
729
+ else {
730
+ // ===== If the current row exists, update the hints
731
+ m_hintRow = std::make_unique<XMLNode>(*m_currentRow.m_rowNode); // don't store a full XLRow, just the XMLNode, for better performance
732
+ m_hintRowNumber = m_currentRowNumber;
733
+ m_currentRowStatus = XLLoaded; // mark row status for further calls to updateCurrentRow()
734
+ }
735
+ }
736
+
737
+ /**
738
+ * @details
739
+ * @pre
740
+ * @post
741
+ */
742
+ XLRowReverseIterator& XLRowReverseIterator::operator++()
743
+ {
744
+ if (m_endReached)
745
+ throw XLInputError("XLRowReverseIterator: tried to increment beyond end operator");
746
+
747
+ if(m_currentRowNumber > m_firstRow)
748
+ --m_currentRowNumber;
749
+ else
750
+ m_endReached = true;
751
+
752
+ m_currentRowStatus = XLNotLoaded; // trigger a new attempt to locate / create the row via updateRowCell
753
+
754
+ return *this;
755
+ }
756
+
757
+ /**
758
+ * @details
759
+ * @pre
760
+ * @post
761
+ */
762
+ XLRowReverseIterator XLRowReverseIterator::operator++(int)
763
+ {
764
+ auto oldIter(*this);
765
+ ++(*this);
766
+ return oldIter;
767
+ }
768
+
769
+ /**
770
+ * @details
771
+ * @pre
772
+ * @post
773
+ */
774
+ XLRow& XLRowReverseIterator::operator*()
775
+ {
776
+ updateCurrentRow(XLCreateIfMissing);
777
+ return m_currentRow;
778
+ }
779
+
780
+ /**
781
+ * @details
782
+ * @pre
783
+ * @post
784
+ */
785
+ XLRowReverseIterator::pointer XLRowReverseIterator::operator->()
786
+ {
787
+ updateCurrentRow(XLCreateIfMissing);
788
+ return &m_currentRow;
789
+ }
790
+
791
+ /**
792
+ * @details
793
+ * @pre
794
+ * @post
795
+ */
796
+ bool XLRowReverseIterator::operator==(const XLRowReverseIterator& rhs) const
797
+ {
798
+ if (m_endReached && rhs.m_endReached) return true; // If both iterators are end iterators
799
+
800
+ if (m_currentRowNumber != rhs.m_currentRowNumber) // If iterators point to a different row
801
+ return false; // that means no match
802
+
803
+ // CAUTION: for performance reasons, disabled all checks whether this and rhs are iterators on the same worksheet & row range
804
+ return true;
805
+
806
+ // if (*m_dataNode != *rhs.m_dataNode) return false; // TBD: iterators over different worksheets may never match
807
+ // TBD if iterators shall be considered not equal if they were created on different XLRowRanges
808
+ // this would require checking the m_firstRow and m_lastRow, potentially costing CPU time
809
+
810
+ // return m_currentRow == rhs.m_currentRow; // match only if row nodes are equal
811
+ // CAUTION: in the current code, that means iterators that point to the same row in different worksheets,
812
+ // and rows that do not exist in both sheets, will be considered equal
813
+ }
814
+
815
+ /**
816
+ * @details
817
+ * @pre
818
+ * @post
819
+ */
820
+ bool XLRowReverseIterator::operator!=(const XLRowReverseIterator& rhs) const { return !(*this == rhs); }
821
+
822
+ /**
823
+ * @details
824
+ * @pre
825
+ * @post
826
+ */
827
+ XLRowReverseIterator::operator bool() const { return false; }
828
+
829
+ /**
830
+ * @details
831
+ */
832
+ bool XLRowReverseIterator::rowExists()
833
+ {
834
+ // ===== Update m_currentRow once so that rowExists will always test the correct cell (an empty row if current row doesn't exist)
835
+ updateCurrentRow(XLDoNotCreateIfMissing);
836
+ return not m_currentRow.empty();
837
+ }
838
+ } // namespace OpenXLSX
839
+
840
+ // ========== XLRowRange =================================================== //
841
+ namespace OpenXLSX
842
+ {
843
+ /**
844
+ * @details
845
+ * @pre
846
+ * @post
847
+ */
848
+ XLRowRange::XLRowRange(const XMLNode& dataNode, uint32_t first, uint32_t last, const XLSharedStrings& sharedStrings)
849
+ : m_dataNode(std::make_unique<XMLNode>(dataNode)),
850
+ m_firstRow(first),
851
+ m_lastRow(last),
852
+ m_sharedStrings(sharedStrings)
853
+ {}
854
+
855
+ /**
856
+ * @details copy constructor
857
+ */
858
+ XLRowRange::XLRowRange(const XLRowRange& other)
859
+ : m_dataNode(std::make_unique<XMLNode>(*other.m_dataNode)),
860
+ m_firstRow(other.m_firstRow),
861
+ m_lastRow(other.m_lastRow),
862
+ m_sharedStrings(other.m_sharedStrings)
863
+ {}
864
+
865
+ /**
866
+ * @details explicit default move constructor
867
+ */
868
+ XLRowRange::XLRowRange(XLRowRange&& other) noexcept = default;
869
+
870
+ /**
871
+ * @details explicit default destructor
872
+ */
873
+ XLRowRange::~XLRowRange() = default;
874
+
875
+ /**
876
+ * @details copy assignment operator
877
+ */
878
+ XLRowRange& XLRowRange::operator=(const XLRowRange& other)
879
+ {
880
+ if (&other != this) {
881
+ XLRowRange temp = XLRowRange(other);
882
+ std::swap(*this, temp);
883
+ }
884
+
885
+ return *this;
886
+ }
887
+
888
+ /**
889
+ * @details explicit default move assignment operator
890
+ */
891
+ XLRowRange& XLRowRange::operator=(XLRowRange&& other) noexcept = default;
892
+
893
+ /**
894
+ * @details
895
+ */
896
+ uint32_t XLRowRange::rowCount() const { return m_lastRow - m_firstRow + 1; }
897
+
898
+ /**
899
+ * @details
900
+ */
901
+ XLRowIterator XLRowRange::begin() { return XLRowIterator(*this, XLIteratorLocation::Begin); }
902
+
903
+ /**
904
+ * @details
905
+ */
906
+ XLRowIterator XLRowRange::end() { return XLRowIterator(*this, XLIteratorLocation::End); }
907
+
908
+ /**
909
+ * @details
910
+ */
911
+ XLRowReverseIterator XLRowRange::rbegin() { return XLRowReverseIterator(*this, XLIteratorLocation::Begin); }
912
+
913
+ /**
914
+ * @details
915
+ */
916
+ XLRowReverseIterator XLRowRange::rend() { return XLRowReverseIterator(*this, XLIteratorLocation::End); }
917
+
918
+ } // namespace OpenXLSX