hane 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (488) hide show
  1. package/README.md +32 -0
  2. package/binding.gyp +87 -0
  3. package/dist/index.d.ts +34 -0
  4. package/dist/index.js +1 -0
  5. package/package.json +33 -0
  6. package/src/native/addon.cc +231 -0
  7. package/src/native/zsign_driver.cc +87 -0
  8. package/src/native/zsign_driver.h +38 -0
  9. package/vendor/zlib/.cmake-format.yaml +245 -0
  10. package/vendor/zlib/.github/workflows/c-std.yml +230 -0
  11. package/vendor/zlib/.github/workflows/cmake.yml +112 -0
  12. package/vendor/zlib/.github/workflows/configure.yml +136 -0
  13. package/vendor/zlib/.github/workflows/fuzz.yml +25 -0
  14. package/vendor/zlib/.github/workflows/msys-cygwin.yml +77 -0
  15. package/vendor/zlib/BUILD.bazel +134 -0
  16. package/vendor/zlib/CMakeLists.txt +330 -0
  17. package/vendor/zlib/ChangeLog +1621 -0
  18. package/vendor/zlib/FAQ +367 -0
  19. package/vendor/zlib/INDEX +68 -0
  20. package/vendor/zlib/LICENSE +22 -0
  21. package/vendor/zlib/MODULE.bazel +9 -0
  22. package/vendor/zlib/Makefile.in +419 -0
  23. package/vendor/zlib/README +115 -0
  24. package/vendor/zlib/README-cmake.md +83 -0
  25. package/vendor/zlib/adler32.c +164 -0
  26. package/vendor/zlib/amiga/Makefile.pup +69 -0
  27. package/vendor/zlib/amiga/Makefile.sas +68 -0
  28. package/vendor/zlib/compress.c +75 -0
  29. package/vendor/zlib/configure +966 -0
  30. package/vendor/zlib/contrib/README.contrib +57 -0
  31. package/vendor/zlib/contrib/ada/buffer_demo.adb +106 -0
  32. package/vendor/zlib/contrib/ada/mtest.adb +156 -0
  33. package/vendor/zlib/contrib/ada/read.adb +156 -0
  34. package/vendor/zlib/contrib/ada/readme.txt +65 -0
  35. package/vendor/zlib/contrib/ada/test.adb +463 -0
  36. package/vendor/zlib/contrib/ada/zlib-streams.adb +225 -0
  37. package/vendor/zlib/contrib/ada/zlib-streams.ads +114 -0
  38. package/vendor/zlib/contrib/ada/zlib-thin.adb +142 -0
  39. package/vendor/zlib/contrib/ada/zlib-thin.ads +450 -0
  40. package/vendor/zlib/contrib/ada/zlib.adb +701 -0
  41. package/vendor/zlib/contrib/ada/zlib.ads +328 -0
  42. package/vendor/zlib/contrib/ada/zlib.gpr +20 -0
  43. package/vendor/zlib/contrib/blast/Makefile +8 -0
  44. package/vendor/zlib/contrib/blast/README +4 -0
  45. package/vendor/zlib/contrib/blast/blast.c +466 -0
  46. package/vendor/zlib/contrib/blast/blast.h +83 -0
  47. package/vendor/zlib/contrib/blast/test.pk +0 -0
  48. package/vendor/zlib/contrib/blast/test.txt +1 -0
  49. package/vendor/zlib/contrib/delphi/ZLib.pas +557 -0
  50. package/vendor/zlib/contrib/delphi/ZLibConst.pas +11 -0
  51. package/vendor/zlib/contrib/delphi/readme.txt +76 -0
  52. package/vendor/zlib/contrib/delphi/zlibd32.mak +99 -0
  53. package/vendor/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs +58 -0
  54. package/vendor/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs +202 -0
  55. package/vendor/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs +83 -0
  56. package/vendor/zlib/contrib/dotzlib/DotZLib/CodecBase.cs +198 -0
  57. package/vendor/zlib/contrib/dotzlib/DotZLib/Deflater.cs +106 -0
  58. package/vendor/zlib/contrib/dotzlib/DotZLib/DotZLib.cs +288 -0
  59. package/vendor/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj +141 -0
  60. package/vendor/zlib/contrib/dotzlib/DotZLib/GZipStream.cs +301 -0
  61. package/vendor/zlib/contrib/dotzlib/DotZLib/Inflater.cs +105 -0
  62. package/vendor/zlib/contrib/dotzlib/DotZLib/UnitTests.cs +274 -0
  63. package/vendor/zlib/contrib/dotzlib/DotZLib.build +33 -0
  64. package/vendor/zlib/contrib/dotzlib/DotZLib.chm +0 -0
  65. package/vendor/zlib/contrib/dotzlib/DotZLib.sln +21 -0
  66. package/vendor/zlib/contrib/dotzlib/LICENSE_1_0.txt +23 -0
  67. package/vendor/zlib/contrib/dotzlib/readme.txt +58 -0
  68. package/vendor/zlib/contrib/gcc_gvmat64/gvmat64.S +574 -0
  69. package/vendor/zlib/contrib/infback9/README +1 -0
  70. package/vendor/zlib/contrib/infback9/infback9.c +603 -0
  71. package/vendor/zlib/contrib/infback9/infback9.h +37 -0
  72. package/vendor/zlib/contrib/infback9/inffix9.h +107 -0
  73. package/vendor/zlib/contrib/infback9/inflate9.h +47 -0
  74. package/vendor/zlib/contrib/infback9/inftree9.c +319 -0
  75. package/vendor/zlib/contrib/infback9/inftree9.h +61 -0
  76. package/vendor/zlib/contrib/iostream/test.cpp +24 -0
  77. package/vendor/zlib/contrib/iostream/zfstream.cpp +329 -0
  78. package/vendor/zlib/contrib/iostream/zfstream.h +128 -0
  79. package/vendor/zlib/contrib/iostream2/zstream.h +307 -0
  80. package/vendor/zlib/contrib/iostream2/zstream_test.cpp +25 -0
  81. package/vendor/zlib/contrib/iostream3/README +35 -0
  82. package/vendor/zlib/contrib/iostream3/TODO +17 -0
  83. package/vendor/zlib/contrib/iostream3/test.cc +50 -0
  84. package/vendor/zlib/contrib/iostream3/zfstream.cc +479 -0
  85. package/vendor/zlib/contrib/iostream3/zfstream.h +466 -0
  86. package/vendor/zlib/contrib/minizip/CMakeLists.txt +380 -0
  87. package/vendor/zlib/contrib/minizip/Makefile +37 -0
  88. package/vendor/zlib/contrib/minizip/Makefile.am +45 -0
  89. package/vendor/zlib/contrib/minizip/MiniZip64_Changes.txt +6 -0
  90. package/vendor/zlib/contrib/minizip/MiniZip64_info.txt +74 -0
  91. package/vendor/zlib/contrib/minizip/configure.ac +32 -0
  92. package/vendor/zlib/contrib/minizip/crypt.h +128 -0
  93. package/vendor/zlib/contrib/minizip/ints.h +57 -0
  94. package/vendor/zlib/contrib/minizip/ioapi.c +231 -0
  95. package/vendor/zlib/contrib/minizip/ioapi.h +183 -0
  96. package/vendor/zlib/contrib/minizip/iowin32.c +448 -0
  97. package/vendor/zlib/contrib/minizip/iowin32.h +28 -0
  98. package/vendor/zlib/contrib/minizip/make_vms.com +25 -0
  99. package/vendor/zlib/contrib/minizip/miniunz.c +647 -0
  100. package/vendor/zlib/contrib/minizip/miniunzip.1 +63 -0
  101. package/vendor/zlib/contrib/minizip/minizip.1 +46 -0
  102. package/vendor/zlib/contrib/minizip/minizip.c +512 -0
  103. package/vendor/zlib/contrib/minizip/minizip.pc.in +12 -0
  104. package/vendor/zlib/contrib/minizip/minizip.pc.txt +13 -0
  105. package/vendor/zlib/contrib/minizip/minizipConfig.cmake.in +35 -0
  106. package/vendor/zlib/contrib/minizip/mztools.c +288 -0
  107. package/vendor/zlib/contrib/minizip/mztools.h +37 -0
  108. package/vendor/zlib/contrib/minizip/skipset.h +361 -0
  109. package/vendor/zlib/contrib/minizip/test/CMakeLists.txt +121 -0
  110. package/vendor/zlib/contrib/minizip/test/add_subdirectory_exclude_test.cmake.in +29 -0
  111. package/vendor/zlib/contrib/minizip/test/add_subdirectory_test.cmake.in +28 -0
  112. package/vendor/zlib/contrib/minizip/test/find_package_test.cmake.in +25 -0
  113. package/vendor/zlib/contrib/minizip/test/test_helper.cm +32 -0
  114. package/vendor/zlib/contrib/minizip/unzip.c +1981 -0
  115. package/vendor/zlib/contrib/minizip/unzip.h +441 -0
  116. package/vendor/zlib/contrib/minizip/zip.c +2199 -0
  117. package/vendor/zlib/contrib/minizip/zip.h +370 -0
  118. package/vendor/zlib/contrib/nuget/nuget.csproj +43 -0
  119. package/vendor/zlib/contrib/nuget/nuget.sln +22 -0
  120. package/vendor/zlib/contrib/pascal/example.pas +599 -0
  121. package/vendor/zlib/contrib/pascal/readme.txt +76 -0
  122. package/vendor/zlib/contrib/pascal/zlibd32.mak +99 -0
  123. package/vendor/zlib/contrib/pascal/zlibpas.pas +276 -0
  124. package/vendor/zlib/contrib/puff/Makefile +42 -0
  125. package/vendor/zlib/contrib/puff/README +63 -0
  126. package/vendor/zlib/contrib/puff/puff.c +840 -0
  127. package/vendor/zlib/contrib/puff/puff.h +35 -0
  128. package/vendor/zlib/contrib/puff/pufftest.c +169 -0
  129. package/vendor/zlib/contrib/puff/zeros.raw +0 -0
  130. package/vendor/zlib/contrib/testzlib/testzlib.c +275 -0
  131. package/vendor/zlib/contrib/testzlib/testzlib.txt +10 -0
  132. package/vendor/zlib/contrib/untgz/Makefile +14 -0
  133. package/vendor/zlib/contrib/untgz/Makefile.msc +17 -0
  134. package/vendor/zlib/contrib/untgz/untgz.c +667 -0
  135. package/vendor/zlib/contrib/vstudio/readme.txt +81 -0
  136. package/vendor/zlib/contrib/vstudio/vc10/miniunz.vcxproj +310 -0
  137. package/vendor/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters +22 -0
  138. package/vendor/zlib/contrib/vstudio/vc10/minizip.vcxproj +307 -0
  139. package/vendor/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters +22 -0
  140. package/vendor/zlib/contrib/vstudio/vc10/testzlib.vcxproj +412 -0
  141. package/vendor/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters +55 -0
  142. package/vendor/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj +310 -0
  143. package/vendor/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters +22 -0
  144. package/vendor/zlib/contrib/vstudio/vc10/zlib.rc +32 -0
  145. package/vendor/zlib/contrib/vstudio/vc10/zlibstat.vcxproj +449 -0
  146. package/vendor/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters +74 -0
  147. package/vendor/zlib/contrib/vstudio/vc10/zlibvc.def +161 -0
  148. package/vendor/zlib/contrib/vstudio/vc10/zlibvc.sln +135 -0
  149. package/vendor/zlib/contrib/vstudio/vc10/zlibvc.vcxproj +633 -0
  150. package/vendor/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters +115 -0
  151. package/vendor/zlib/contrib/vstudio/vc11/miniunz.vcxproj +314 -0
  152. package/vendor/zlib/contrib/vstudio/vc11/minizip.vcxproj +311 -0
  153. package/vendor/zlib/contrib/vstudio/vc11/testzlib.vcxproj +418 -0
  154. package/vendor/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj +314 -0
  155. package/vendor/zlib/contrib/vstudio/vc11/zlib.rc +32 -0
  156. package/vendor/zlib/contrib/vstudio/vc11/zlibstat.vcxproj +456 -0
  157. package/vendor/zlib/contrib/vstudio/vc11/zlibvc.def +161 -0
  158. package/vendor/zlib/contrib/vstudio/vc11/zlibvc.sln +117 -0
  159. package/vendor/zlib/contrib/vstudio/vc11/zlibvc.vcxproj +664 -0
  160. package/vendor/zlib/contrib/vstudio/vc12/miniunz.vcxproj +316 -0
  161. package/vendor/zlib/contrib/vstudio/vc12/minizip.vcxproj +313 -0
  162. package/vendor/zlib/contrib/vstudio/vc12/testzlib.vcxproj +422 -0
  163. package/vendor/zlib/contrib/vstudio/vc12/testzlibdll.vcxproj +316 -0
  164. package/vendor/zlib/contrib/vstudio/vc12/zlib.rc +32 -0
  165. package/vendor/zlib/contrib/vstudio/vc12/zlibstat.vcxproj +459 -0
  166. package/vendor/zlib/contrib/vstudio/vc12/zlibvc.def +161 -0
  167. package/vendor/zlib/contrib/vstudio/vc12/zlibvc.sln +119 -0
  168. package/vendor/zlib/contrib/vstudio/vc12/zlibvc.vcxproj +668 -0
  169. package/vendor/zlib/contrib/vstudio/vc14/miniunz.vcxproj +316 -0
  170. package/vendor/zlib/contrib/vstudio/vc14/minizip.vcxproj +313 -0
  171. package/vendor/zlib/contrib/vstudio/vc14/testzlib.vcxproj +422 -0
  172. package/vendor/zlib/contrib/vstudio/vc14/testzlibdll.vcxproj +316 -0
  173. package/vendor/zlib/contrib/vstudio/vc14/zlib.rc +32 -0
  174. package/vendor/zlib/contrib/vstudio/vc14/zlibstat.vcxproj +459 -0
  175. package/vendor/zlib/contrib/vstudio/vc14/zlibvc.def +161 -0
  176. package/vendor/zlib/contrib/vstudio/vc14/zlibvc.sln +119 -0
  177. package/vendor/zlib/contrib/vstudio/vc14/zlibvc.vcxproj +668 -0
  178. package/vendor/zlib/contrib/vstudio/vc17/miniunz.vcxproj +409 -0
  179. package/vendor/zlib/contrib/vstudio/vc17/minizip.vcxproj +405 -0
  180. package/vendor/zlib/contrib/vstudio/vc17/testzlib.vcxproj +473 -0
  181. package/vendor/zlib/contrib/vstudio/vc17/testzlibdll.vcxproj +409 -0
  182. package/vendor/zlib/contrib/vstudio/vc17/zlib.rc +32 -0
  183. package/vendor/zlib/contrib/vstudio/vc17/zlibstat.vcxproj +602 -0
  184. package/vendor/zlib/contrib/vstudio/vc17/zlibvc.def +161 -0
  185. package/vendor/zlib/contrib/vstudio/vc17/zlibvc.sln +179 -0
  186. package/vendor/zlib/contrib/vstudio/vc17/zlibvc.vcxproj +875 -0
  187. package/vendor/zlib/contrib/vstudio/vc9/miniunz.vcproj +565 -0
  188. package/vendor/zlib/contrib/vstudio/vc9/minizip.vcproj +562 -0
  189. package/vendor/zlib/contrib/vstudio/vc9/testzlib.vcproj +796 -0
  190. package/vendor/zlib/contrib/vstudio/vc9/testzlibdll.vcproj +565 -0
  191. package/vendor/zlib/contrib/vstudio/vc9/zlib.rc +32 -0
  192. package/vendor/zlib/contrib/vstudio/vc9/zlibstat.vcproj +781 -0
  193. package/vendor/zlib/contrib/vstudio/vc9/zlibvc.def +161 -0
  194. package/vendor/zlib/contrib/vstudio/vc9/zlibvc.sln +144 -0
  195. package/vendor/zlib/contrib/vstudio/vc9/zlibvc.vcproj +1100 -0
  196. package/vendor/zlib/crc32.c +1049 -0
  197. package/vendor/zlib/crc32.h +9446 -0
  198. package/vendor/zlib/deflate.c +2152 -0
  199. package/vendor/zlib/deflate.h +380 -0
  200. package/vendor/zlib/doc/algorithm.txt +209 -0
  201. package/vendor/zlib/doc/crc-doc.1.0.pdf +0 -0
  202. package/vendor/zlib/doc/rfc1950.txt +619 -0
  203. package/vendor/zlib/doc/rfc1951.txt +955 -0
  204. package/vendor/zlib/doc/rfc1952.txt +675 -0
  205. package/vendor/zlib/doc/txtvsbin.txt +107 -0
  206. package/vendor/zlib/examples/README.examples +54 -0
  207. package/vendor/zlib/examples/enough.c +597 -0
  208. package/vendor/zlib/examples/fitblk.c +233 -0
  209. package/vendor/zlib/examples/gun.c +702 -0
  210. package/vendor/zlib/examples/gzappend.c +504 -0
  211. package/vendor/zlib/examples/gzjoin.c +449 -0
  212. package/vendor/zlib/examples/gzlog.c +1061 -0
  213. package/vendor/zlib/examples/gzlog.h +91 -0
  214. package/vendor/zlib/examples/gznorm.c +474 -0
  215. package/vendor/zlib/examples/zlib_how.html +549 -0
  216. package/vendor/zlib/examples/zpipe.c +209 -0
  217. package/vendor/zlib/examples/zran.c +550 -0
  218. package/vendor/zlib/examples/zran.h +53 -0
  219. package/vendor/zlib/gzclose.c +23 -0
  220. package/vendor/zlib/gzguts.h +215 -0
  221. package/vendor/zlib/gzlib.c +585 -0
  222. package/vendor/zlib/gzread.c +603 -0
  223. package/vendor/zlib/gzwrite.c +631 -0
  224. package/vendor/zlib/infback.c +628 -0
  225. package/vendor/zlib/inffast.c +320 -0
  226. package/vendor/zlib/inffast.h +11 -0
  227. package/vendor/zlib/inffixed.h +94 -0
  228. package/vendor/zlib/inflate.c +1526 -0
  229. package/vendor/zlib/inflate.h +126 -0
  230. package/vendor/zlib/inftrees.c +299 -0
  231. package/vendor/zlib/inftrees.h +62 -0
  232. package/vendor/zlib/make_vms.com +867 -0
  233. package/vendor/zlib/msdos/Makefile.bor +115 -0
  234. package/vendor/zlib/msdos/Makefile.dj2 +104 -0
  235. package/vendor/zlib/msdos/Makefile.emx +69 -0
  236. package/vendor/zlib/msdos/Makefile.msc +112 -0
  237. package/vendor/zlib/msdos/Makefile.tc +100 -0
  238. package/vendor/zlib/nintendods/Makefile +126 -0
  239. package/vendor/zlib/nintendods/README +5 -0
  240. package/vendor/zlib/old/Makefile.emx +69 -0
  241. package/vendor/zlib/old/Makefile.riscos +151 -0
  242. package/vendor/zlib/old/README +3 -0
  243. package/vendor/zlib/old/descrip.mms +48 -0
  244. package/vendor/zlib/old/os2/Makefile.os2 +136 -0
  245. package/vendor/zlib/old/os2/zlib.def +51 -0
  246. package/vendor/zlib/old/visual-basic.txt +160 -0
  247. package/vendor/zlib/os400/README400 +48 -0
  248. package/vendor/zlib/os400/bndsrc +133 -0
  249. package/vendor/zlib/os400/make.sh +366 -0
  250. package/vendor/zlib/os400/zlib.inc +531 -0
  251. package/vendor/zlib/qnx/package.qpg +141 -0
  252. package/vendor/zlib/test/CMakeLists.txt +265 -0
  253. package/vendor/zlib/test/add_subdirectory_exclude_test.cmake.in +29 -0
  254. package/vendor/zlib/test/add_subdirectory_test.cmake.in +28 -0
  255. package/vendor/zlib/test/example.c +552 -0
  256. package/vendor/zlib/test/find_package_test.cmake.in +26 -0
  257. package/vendor/zlib/test/infcover.c +672 -0
  258. package/vendor/zlib/test/minigzip.c +590 -0
  259. package/vendor/zlib/treebuild.xml +116 -0
  260. package/vendor/zlib/trees.c +1119 -0
  261. package/vendor/zlib/trees.h +128 -0
  262. package/vendor/zlib/uncompr.c +85 -0
  263. package/vendor/zlib/watcom/watcom_f.mak +43 -0
  264. package/vendor/zlib/watcom/watcom_l.mak +43 -0
  265. package/vendor/zlib/win32/DLL_FAQ.txt +381 -0
  266. package/vendor/zlib/win32/Makefile.bor +109 -0
  267. package/vendor/zlib/win32/Makefile.gcc +177 -0
  268. package/vendor/zlib/win32/Makefile.msc +159 -0
  269. package/vendor/zlib/win32/README-WIN32.txt +103 -0
  270. package/vendor/zlib/win32/VisualC.txt +3 -0
  271. package/vendor/zlib/win32/zlib.def +98 -0
  272. package/vendor/zlib/win32/zlib1.rc +37 -0
  273. package/vendor/zlib/zconf.h.in +544 -0
  274. package/vendor/zlib/zlib.3 +149 -0
  275. package/vendor/zlib/zlib.3.pdf +0 -0
  276. package/vendor/zlib/zlib.h +1957 -0
  277. package/vendor/zlib/zlib.map +104 -0
  278. package/vendor/zlib/zlib.pc.cmakein +13 -0
  279. package/vendor/zlib/zlib.pc.in +13 -0
  280. package/vendor/zlib/zlibConfig.cmake.in +26 -0
  281. package/vendor/zlib/zutil.c +299 -0
  282. package/vendor/zlib/zutil.h +257 -0
  283. package/vendor/zsign/.gitattributes +4 -0
  284. package/vendor/zsign/LICENSE +21 -0
  285. package/vendor/zsign/README.md +142 -0
  286. package/vendor/zsign/build/linux/Makefile +43 -0
  287. package/vendor/zsign/build/macos/Makefile +43 -0
  288. package/vendor/zsign/build/windows/vs2022/include/minizip/crypt.h +128 -0
  289. package/vendor/zsign/build/windows/vs2022/include/minizip/ioapi.h +216 -0
  290. package/vendor/zsign/build/windows/vs2022/include/minizip/iowin32.h +28 -0
  291. package/vendor/zsign/build/windows/vs2022/include/minizip/mztools.h +37 -0
  292. package/vendor/zsign/build/windows/vs2022/include/minizip/unzip.h +437 -0
  293. package/vendor/zsign/build/windows/vs2022/include/minizip/zip.h +364 -0
  294. package/vendor/zsign/build/windows/vs2022/include/openssl/__DECC_INCLUDE_EPILOGUE.H +22 -0
  295. package/vendor/zsign/build/windows/vs2022/include/openssl/__DECC_INCLUDE_PROLOGUE.H +26 -0
  296. package/vendor/zsign/build/windows/vs2022/include/openssl/aes.h +111 -0
  297. package/vendor/zsign/build/windows/vs2022/include/openssl/applink.c +153 -0
  298. package/vendor/zsign/build/windows/vs2022/include/openssl/asn1.h +1133 -0
  299. package/vendor/zsign/build/windows/vs2022/include/openssl/asn1_mac.h +10 -0
  300. package/vendor/zsign/build/windows/vs2022/include/openssl/asn1err.h +142 -0
  301. package/vendor/zsign/build/windows/vs2022/include/openssl/asn1t.h +946 -0
  302. package/vendor/zsign/build/windows/vs2022/include/openssl/async.h +104 -0
  303. package/vendor/zsign/build/windows/vs2022/include/openssl/asyncerr.h +29 -0
  304. package/vendor/zsign/build/windows/vs2022/include/openssl/bio.h +1015 -0
  305. package/vendor/zsign/build/windows/vs2022/include/openssl/bioerr.h +72 -0
  306. package/vendor/zsign/build/windows/vs2022/include/openssl/blowfish.h +78 -0
  307. package/vendor/zsign/build/windows/vs2022/include/openssl/bn.h +590 -0
  308. package/vendor/zsign/build/windows/vs2022/include/openssl/bnerr.h +47 -0
  309. package/vendor/zsign/build/windows/vs2022/include/openssl/buffer.h +62 -0
  310. package/vendor/zsign/build/windows/vs2022/include/openssl/buffererr.h +25 -0
  311. package/vendor/zsign/build/windows/vs2022/include/openssl/camellia.h +117 -0
  312. package/vendor/zsign/build/windows/vs2022/include/openssl/cast.h +71 -0
  313. package/vendor/zsign/build/windows/vs2022/include/openssl/cmac.h +52 -0
  314. package/vendor/zsign/build/windows/vs2022/include/openssl/cmp.h +727 -0
  315. package/vendor/zsign/build/windows/vs2022/include/openssl/cmp_util.h +56 -0
  316. package/vendor/zsign/build/windows/vs2022/include/openssl/cmperr.h +131 -0
  317. package/vendor/zsign/build/windows/vs2022/include/openssl/cms.h +508 -0
  318. package/vendor/zsign/build/windows/vs2022/include/openssl/cmserr.h +125 -0
  319. package/vendor/zsign/build/windows/vs2022/include/openssl/comp.h +98 -0
  320. package/vendor/zsign/build/windows/vs2022/include/openssl/comperr.h +38 -0
  321. package/vendor/zsign/build/windows/vs2022/include/openssl/conf.h +214 -0
  322. package/vendor/zsign/build/windows/vs2022/include/openssl/conf_api.h +46 -0
  323. package/vendor/zsign/build/windows/vs2022/include/openssl/conferr.h +52 -0
  324. package/vendor/zsign/build/windows/vs2022/include/openssl/configuration.h +188 -0
  325. package/vendor/zsign/build/windows/vs2022/include/openssl/conftypes.h +44 -0
  326. package/vendor/zsign/build/windows/vs2022/include/openssl/core.h +236 -0
  327. package/vendor/zsign/build/windows/vs2022/include/openssl/core_dispatch.h +1022 -0
  328. package/vendor/zsign/build/windows/vs2022/include/openssl/core_names.h +545 -0
  329. package/vendor/zsign/build/windows/vs2022/include/openssl/core_object.h +41 -0
  330. package/vendor/zsign/build/windows/vs2022/include/openssl/crmf.h +260 -0
  331. package/vendor/zsign/build/windows/vs2022/include/openssl/crmferr.h +50 -0
  332. package/vendor/zsign/build/windows/vs2022/include/openssl/crypto.h +580 -0
  333. package/vendor/zsign/build/windows/vs2022/include/openssl/cryptoerr.h +56 -0
  334. package/vendor/zsign/build/windows/vs2022/include/openssl/cryptoerr_legacy.h +1466 -0
  335. package/vendor/zsign/build/windows/vs2022/include/openssl/ct.h +573 -0
  336. package/vendor/zsign/build/windows/vs2022/include/openssl/cterr.h +45 -0
  337. package/vendor/zsign/build/windows/vs2022/include/openssl/decoder.h +133 -0
  338. package/vendor/zsign/build/windows/vs2022/include/openssl/decodererr.h +28 -0
  339. package/vendor/zsign/build/windows/vs2022/include/openssl/des.h +211 -0
  340. package/vendor/zsign/build/windows/vs2022/include/openssl/dh.h +339 -0
  341. package/vendor/zsign/build/windows/vs2022/include/openssl/dherr.h +59 -0
  342. package/vendor/zsign/build/windows/vs2022/include/openssl/dsa.h +280 -0
  343. package/vendor/zsign/build/windows/vs2022/include/openssl/dsaerr.h +44 -0
  344. package/vendor/zsign/build/windows/vs2022/include/openssl/dtls1.h +57 -0
  345. package/vendor/zsign/build/windows/vs2022/include/openssl/e_os2.h +310 -0
  346. package/vendor/zsign/build/windows/vs2022/include/openssl/e_ostime.h +38 -0
  347. package/vendor/zsign/build/windows/vs2022/include/openssl/ebcdic.h +39 -0
  348. package/vendor/zsign/build/windows/vs2022/include/openssl/ec.h +1588 -0
  349. package/vendor/zsign/build/windows/vs2022/include/openssl/ecdh.h +10 -0
  350. package/vendor/zsign/build/windows/vs2022/include/openssl/ecdsa.h +10 -0
  351. package/vendor/zsign/build/windows/vs2022/include/openssl/ecerr.h +104 -0
  352. package/vendor/zsign/build/windows/vs2022/include/openssl/encoder.h +124 -0
  353. package/vendor/zsign/build/windows/vs2022/include/openssl/encodererr.h +28 -0
  354. package/vendor/zsign/build/windows/vs2022/include/openssl/engine.h +833 -0
  355. package/vendor/zsign/build/windows/vs2022/include/openssl/engineerr.h +63 -0
  356. package/vendor/zsign/build/windows/vs2022/include/openssl/err.h +512 -0
  357. package/vendor/zsign/build/windows/vs2022/include/openssl/ess.h +128 -0
  358. package/vendor/zsign/build/windows/vs2022/include/openssl/esserr.h +32 -0
  359. package/vendor/zsign/build/windows/vs2022/include/openssl/evp.h +2231 -0
  360. package/vendor/zsign/build/windows/vs2022/include/openssl/evperr.h +140 -0
  361. package/vendor/zsign/build/windows/vs2022/include/openssl/fips_names.h +50 -0
  362. package/vendor/zsign/build/windows/vs2022/include/openssl/fipskey.h +41 -0
  363. package/vendor/zsign/build/windows/vs2022/include/openssl/hmac.h +62 -0
  364. package/vendor/zsign/build/windows/vs2022/include/openssl/hpke.h +169 -0
  365. package/vendor/zsign/build/windows/vs2022/include/openssl/http.h +118 -0
  366. package/vendor/zsign/build/windows/vs2022/include/openssl/httperr.h +56 -0
  367. package/vendor/zsign/build/windows/vs2022/include/openssl/idea.h +82 -0
  368. package/vendor/zsign/build/windows/vs2022/include/openssl/indicator.h +31 -0
  369. package/vendor/zsign/build/windows/vs2022/include/openssl/kdf.h +138 -0
  370. package/vendor/zsign/build/windows/vs2022/include/openssl/kdferr.h +16 -0
  371. package/vendor/zsign/build/windows/vs2022/include/openssl/lhash.h +398 -0
  372. package/vendor/zsign/build/windows/vs2022/include/openssl/macros.h +338 -0
  373. package/vendor/zsign/build/windows/vs2022/include/openssl/md2.h +56 -0
  374. package/vendor/zsign/build/windows/vs2022/include/openssl/md4.h +63 -0
  375. package/vendor/zsign/build/windows/vs2022/include/openssl/md5.h +62 -0
  376. package/vendor/zsign/build/windows/vs2022/include/openssl/mdc2.h +55 -0
  377. package/vendor/zsign/build/windows/vs2022/include/openssl/modes.h +219 -0
  378. package/vendor/zsign/build/windows/vs2022/include/openssl/obj_mac.h +5820 -0
  379. package/vendor/zsign/build/windows/vs2022/include/openssl/objects.h +184 -0
  380. package/vendor/zsign/build/windows/vs2022/include/openssl/objectserr.h +28 -0
  381. package/vendor/zsign/build/windows/vs2022/include/openssl/ocsp.h +483 -0
  382. package/vendor/zsign/build/windows/vs2022/include/openssl/ocsperr.h +53 -0
  383. package/vendor/zsign/build/windows/vs2022/include/openssl/opensslconf.h +17 -0
  384. package/vendor/zsign/build/windows/vs2022/include/openssl/opensslv.h +114 -0
  385. package/vendor/zsign/build/windows/vs2022/include/openssl/ossl_typ.h +16 -0
  386. package/vendor/zsign/build/windows/vs2022/include/openssl/param_build.h +63 -0
  387. package/vendor/zsign/build/windows/vs2022/include/openssl/params.h +160 -0
  388. package/vendor/zsign/build/windows/vs2022/include/openssl/pem.h +543 -0
  389. package/vendor/zsign/build/windows/vs2022/include/openssl/pem2.h +19 -0
  390. package/vendor/zsign/build/windows/vs2022/include/openssl/pemerr.h +58 -0
  391. package/vendor/zsign/build/windows/vs2022/include/openssl/pkcs12.h +366 -0
  392. package/vendor/zsign/build/windows/vs2022/include/openssl/pkcs12err.h +46 -0
  393. package/vendor/zsign/build/windows/vs2022/include/openssl/pkcs7.h +430 -0
  394. package/vendor/zsign/build/windows/vs2022/include/openssl/pkcs7err.h +63 -0
  395. package/vendor/zsign/build/windows/vs2022/include/openssl/prov_ssl.h +38 -0
  396. package/vendor/zsign/build/windows/vs2022/include/openssl/proverr.h +162 -0
  397. package/vendor/zsign/build/windows/vs2022/include/openssl/provider.h +66 -0
  398. package/vendor/zsign/build/windows/vs2022/include/openssl/quic.h +70 -0
  399. package/vendor/zsign/build/windows/vs2022/include/openssl/rand.h +125 -0
  400. package/vendor/zsign/build/windows/vs2022/include/openssl/randerr.h +69 -0
  401. package/vendor/zsign/build/windows/vs2022/include/openssl/rc2.h +68 -0
  402. package/vendor/zsign/build/windows/vs2022/include/openssl/rc4.h +47 -0
  403. package/vendor/zsign/build/windows/vs2022/include/openssl/rc5.h +79 -0
  404. package/vendor/zsign/build/windows/vs2022/include/openssl/ripemd.h +59 -0
  405. package/vendor/zsign/build/windows/vs2022/include/openssl/rsa.h +615 -0
  406. package/vendor/zsign/build/windows/vs2022/include/openssl/rsaerr.h +107 -0
  407. package/vendor/zsign/build/windows/vs2022/include/openssl/safestack.h +297 -0
  408. package/vendor/zsign/build/windows/vs2022/include/openssl/seed.h +113 -0
  409. package/vendor/zsign/build/windows/vs2022/include/openssl/self_test.h +98 -0
  410. package/vendor/zsign/build/windows/vs2022/include/openssl/sha.h +139 -0
  411. package/vendor/zsign/build/windows/vs2022/include/openssl/srp.h +285 -0
  412. package/vendor/zsign/build/windows/vs2022/include/openssl/srtp.h +68 -0
  413. package/vendor/zsign/build/windows/vs2022/include/openssl/ssl.h +2878 -0
  414. package/vendor/zsign/build/windows/vs2022/include/openssl/ssl2.h +30 -0
  415. package/vendor/zsign/build/windows/vs2022/include/openssl/ssl3.h +357 -0
  416. package/vendor/zsign/build/windows/vs2022/include/openssl/sslerr.h +379 -0
  417. package/vendor/zsign/build/windows/vs2022/include/openssl/sslerr_legacy.h +467 -0
  418. package/vendor/zsign/build/windows/vs2022/include/openssl/stack.h +90 -0
  419. package/vendor/zsign/build/windows/vs2022/include/openssl/store.h +377 -0
  420. package/vendor/zsign/build/windows/vs2022/include/openssl/storeerr.h +49 -0
  421. package/vendor/zsign/build/windows/vs2022/include/openssl/symhacks.h +39 -0
  422. package/vendor/zsign/build/windows/vs2022/include/openssl/thread.h +31 -0
  423. package/vendor/zsign/build/windows/vs2022/include/openssl/tls1.h +1220 -0
  424. package/vendor/zsign/build/windows/vs2022/include/openssl/trace.h +320 -0
  425. package/vendor/zsign/build/windows/vs2022/include/openssl/ts.h +522 -0
  426. package/vendor/zsign/build/windows/vs2022/include/openssl/tserr.h +67 -0
  427. package/vendor/zsign/build/windows/vs2022/include/openssl/txt_db.h +63 -0
  428. package/vendor/zsign/build/windows/vs2022/include/openssl/types.h +245 -0
  429. package/vendor/zsign/build/windows/vs2022/include/openssl/ui.h +407 -0
  430. package/vendor/zsign/build/windows/vs2022/include/openssl/uierr.h +38 -0
  431. package/vendor/zsign/build/windows/vs2022/include/openssl/whrlpool.h +62 -0
  432. package/vendor/zsign/build/windows/vs2022/include/openssl/x509.h +1304 -0
  433. package/vendor/zsign/build/windows/vs2022/include/openssl/x509_acert.h +263 -0
  434. package/vendor/zsign/build/windows/vs2022/include/openssl/x509_vfy.h +902 -0
  435. package/vendor/zsign/build/windows/vs2022/include/openssl/x509err.h +70 -0
  436. package/vendor/zsign/build/windows/vs2022/include/openssl/x509v3.h +1500 -0
  437. package/vendor/zsign/build/windows/vs2022/include/openssl/x509v3err.h +96 -0
  438. package/vendor/zsign/build/windows/vs2022/include/zlib/zconf.h +553 -0
  439. package/vendor/zsign/build/windows/vs2022/include/zlib/zlib.h +1938 -0
  440. package/vendor/zsign/build/windows/vs2022/lib/minizip/x64/mt/minizip.lib +0 -0
  441. package/vendor/zsign/build/windows/vs2022/lib/openssl/x64/mt/libcrypto.lib +0 -0
  442. package/vendor/zsign/build/windows/vs2022/lib/openssl/x64/mt/libssl.lib +0 -0
  443. package/vendor/zsign/build/windows/vs2022/lib/zlib/x64/mt/zlib.lib +0 -0
  444. package/vendor/zsign/build/windows/vs2022/zsign/src/common_win32.h +44 -0
  445. package/vendor/zsign/build/windows/vs2022/zsign/src/getopt.cpp +69 -0
  446. package/vendor/zsign/build/windows/vs2022/zsign/src/getopt.h +20 -0
  447. package/vendor/zsign/build/windows/vs2022/zsign/src/iconv.cpp +138 -0
  448. package/vendor/zsign/build/windows/vs2022/zsign/src/iconv.h +38 -0
  449. package/vendor/zsign/build/windows/vs2022/zsign/zsign.vcxproj +177 -0
  450. package/vendor/zsign/build/windows/vs2022/zsign/zsign.vcxproj.filters +120 -0
  451. package/vendor/zsign/build/windows/vs2022/zsign.sln +28 -0
  452. package/vendor/zsign/src/archo.cpp +742 -0
  453. package/vendor/zsign/src/archo.h +61 -0
  454. package/vendor/zsign/src/bundle.cpp +589 -0
  455. package/vendor/zsign/src/bundle.h +46 -0
  456. package/vendor/zsign/src/common/archive.cpp +246 -0
  457. package/vendor/zsign/src/common/archive.h +22 -0
  458. package/vendor/zsign/src/common/base64.cpp +166 -0
  459. package/vendor/zsign/src/common/base64.h +30 -0
  460. package/vendor/zsign/src/common/common.h +56 -0
  461. package/vendor/zsign/src/common/fs.cpp +573 -0
  462. package/vendor/zsign/src/common/fs.h +50 -0
  463. package/vendor/zsign/src/common/json.cpp +3380 -0
  464. package/vendor/zsign/src/common/json.h +530 -0
  465. package/vendor/zsign/src/common/log.cpp +145 -0
  466. package/vendor/zsign/src/common/log.h +37 -0
  467. package/vendor/zsign/src/common/mach-o.h +585 -0
  468. package/vendor/zsign/src/common/sha.cpp +133 -0
  469. package/vendor/zsign/src/common/sha.h +24 -0
  470. package/vendor/zsign/src/common/timer.cpp +28 -0
  471. package/vendor/zsign/src/common/timer.h +17 -0
  472. package/vendor/zsign/src/common/util.cpp +185 -0
  473. package/vendor/zsign/src/common/util.h +25 -0
  474. package/vendor/zsign/src/macho.cpp +273 -0
  475. package/vendor/zsign/src/macho.h +38 -0
  476. package/vendor/zsign/src/openssl.cpp +698 -0
  477. package/vendor/zsign/src/openssl.h +71 -0
  478. package/vendor/zsign/src/signing.cpp +745 -0
  479. package/vendor/zsign/src/signing.h +59 -0
  480. package/vendor/zsign/src/zsign.cpp +317 -0
  481. package/vendor/zsign/test/dylib/bin/demo1.dylib +0 -0
  482. package/vendor/zsign/test/dylib/bin/demo2.dylib +0 -0
  483. package/vendor/zsign/test/dylib/demo/Makefile +12 -0
  484. package/vendor/zsign/test/dylib/demo/control +9 -0
  485. package/vendor/zsign/test/dylib/demo/demo.m +21 -0
  486. package/vendor/zsign/test/linux/test.sh +19 -0
  487. package/vendor/zsign/test/macos/test.sh +19 -0
  488. package/vendor/zsign/test/windows/test.ps1 +17 -0
@@ -0,0 +1,3380 @@
1
+ #include "json.h"
2
+ #include "base64.h"
3
+ #include <time.h>
4
+ #include <math.h>
5
+ #include <assert.h>
6
+ #include <stdarg.h>
7
+ #include <limits>
8
+ using namespace std;
9
+
10
+ #ifdef _WIN32
11
+
12
+ #define _fopen64(fp, path, mode) { fopen_s(&fp, path, mode); }
13
+ #define PRId64 "lld"
14
+
15
+ #else
16
+
17
+ #ifdef __APPLE__
18
+ #define PRId64 "lld"
19
+ #else
20
+ #define PRId64 "ld"
21
+ #endif
22
+
23
+ #define _fseeki64 fseeko
24
+ #define _ftelli64 ftello
25
+ #define _atoi64(val) strtoll(val, NULL, 10)
26
+ #define sscanf_s sscanf
27
+ #define _fopen64(fp, path, mode) {fp = fopen(path, mode); }
28
+
29
+ #endif
30
+
31
+
32
+ const jvalue jvalue::null;
33
+ const string jvalue::null_data;
34
+
35
+ jvalue::jvalue(jtype type)
36
+ {
37
+ m_type = type;
38
+ m_value.v_double = 0;
39
+ }
40
+
41
+ jvalue::jvalue(int val)
42
+ {
43
+ m_type = E_INT;
44
+ m_value.v_int64 = val;
45
+ }
46
+
47
+ jvalue::jvalue(int64_t val)
48
+ {
49
+ m_type = E_INT;
50
+ m_value.v_int64 = val;
51
+ }
52
+
53
+ jvalue::jvalue(bool val)
54
+ {
55
+ m_type = E_BOOL;
56
+ m_value.v_bool = val;
57
+ }
58
+
59
+ jvalue::jvalue(double val)
60
+ {
61
+ m_type = E_FLOAT;
62
+ m_value.v_double = val;
63
+ }
64
+
65
+ jvalue::jvalue(const char* val)
66
+ {
67
+ m_type = E_STRING;
68
+ m_value.p_string = _new_string(val);
69
+ }
70
+
71
+ jvalue::jvalue(const string& val)
72
+ {
73
+ m_type = E_STRING;
74
+ m_value.p_string = _new_string(val.c_str());
75
+ }
76
+
77
+ jvalue::jvalue(const jvalue& other)
78
+ {
79
+ _copy_value(other);
80
+ }
81
+
82
+ jvalue::jvalue(const char* val, size_t len)
83
+ {
84
+ m_type = E_DATA;
85
+ m_value.p_data = new string();
86
+ m_value.p_data->append(val, len);
87
+ }
88
+
89
+ jvalue::~jvalue()
90
+ {
91
+ _free();
92
+ }
93
+
94
+ void jvalue::clear()
95
+ {
96
+ _free();
97
+ }
98
+
99
+ bool jvalue::is_int() const
100
+ {
101
+ return (E_INT == m_type);
102
+ }
103
+
104
+ bool jvalue::is_null() const
105
+ {
106
+ return (E_NULL == m_type);
107
+ }
108
+
109
+ bool jvalue::is_bool() const
110
+ {
111
+ return (E_BOOL == m_type);
112
+ }
113
+
114
+ bool jvalue::is_double() const
115
+ {
116
+ return (E_FLOAT == m_type);
117
+ }
118
+
119
+ bool jvalue::is_string() const
120
+ {
121
+ return (E_STRING == m_type);
122
+ }
123
+
124
+ bool jvalue::is_array() const
125
+ {
126
+ return (E_ARRAY == m_type);
127
+ }
128
+
129
+ bool jvalue::is_object() const
130
+ {
131
+ return (E_OBJECT == m_type);
132
+ }
133
+
134
+ bool jvalue::is_empty() const
135
+ {
136
+ switch (m_type) {
137
+ case E_NULL:
138
+ return true;
139
+ break;
140
+ case E_INT:
141
+ return (0 == m_value.v_int64);
142
+ break;
143
+ case E_BOOL:
144
+ return (false == m_value.v_bool);
145
+ break;
146
+ case E_FLOAT:
147
+ return (0 == m_value.v_double);
148
+ break;
149
+ case E_ARRAY:
150
+ case E_OBJECT:
151
+ return (0 == size());
152
+ break;
153
+ case E_STRING:
154
+ return (0 == strlen(as_cstr()));
155
+ case E_DATE:
156
+ return (0 == m_value.v_date);
157
+ break;
158
+ case E_DATA:
159
+ return (NULL == m_value.p_data) ? true : m_value.p_data->empty();
160
+ break;
161
+ }
162
+ return true;
163
+ }
164
+
165
+ jvalue::operator const char* () const
166
+ {
167
+ return as_cstr();
168
+ }
169
+
170
+ jvalue::operator int() const
171
+ {
172
+ return as_int();
173
+ }
174
+
175
+ jvalue::operator int64_t() const
176
+ {
177
+ return as_int64();
178
+ }
179
+
180
+ jvalue::operator double() const
181
+ {
182
+ return as_double();
183
+ }
184
+
185
+ jvalue::operator string() const
186
+ {
187
+ return as_cstr();
188
+ }
189
+
190
+ jvalue::operator bool() const
191
+ {
192
+ return as_bool();
193
+ }
194
+
195
+ char* jvalue::_new_string(const char* cstr)
196
+ {
197
+ char* str = NULL;
198
+ if (NULL != cstr) {
199
+ size_t len = (strlen(cstr) + 1) * sizeof(char);
200
+ str = (char*)::malloc(len);
201
+ if (NULL != str) {
202
+ ::memcpy(str, cstr, len);
203
+ }
204
+ }
205
+ return str;
206
+ }
207
+
208
+ void jvalue::_copy_value(const jvalue& src)
209
+ {
210
+ m_type = src.m_type;
211
+ switch (m_type) {
212
+ case E_ARRAY:
213
+ m_value.p_array = (NULL == src.m_value.p_array) ? NULL : new array(*(src.m_value.p_array));
214
+ break;
215
+ case E_OBJECT:
216
+ {
217
+ m_value.p_object = (NULL == src.m_value.p_object) ? NULL : new object();
218
+ if (NULL != m_value.p_object) {
219
+ *m_value.p_object = *src.m_value.p_object;
220
+ }
221
+ }
222
+ break;
223
+ case E_STRING:
224
+ m_value.p_string = (NULL == src.m_value.p_string) ? NULL : _new_string(src.m_value.p_string);
225
+ break;
226
+ case E_DATA:
227
+ {
228
+ if (NULL != src.m_value.p_data) {
229
+ m_value.p_data = new string();
230
+ *m_value.p_data = *src.m_value.p_data;
231
+ } else {
232
+ m_value.p_data = NULL;
233
+ }
234
+ }
235
+ break;
236
+ default:
237
+ m_value = src.m_value;
238
+ break;
239
+ }
240
+ }
241
+
242
+ void jvalue::_free()
243
+ {
244
+ switch (m_type) {
245
+ case E_INT:
246
+ {
247
+ m_value.v_int64 = 0;
248
+ }
249
+ break;
250
+ case E_BOOL:
251
+ {
252
+ m_value.v_bool = false;
253
+ }
254
+ break;
255
+ case E_FLOAT:
256
+ {
257
+ m_value.v_double = 0.0;
258
+ }
259
+ break;
260
+ case E_STRING:
261
+ {
262
+ if (NULL != m_value.p_string) {
263
+ ::free(m_value.p_string);
264
+ m_value.p_string = NULL;
265
+ }
266
+ }
267
+ break;
268
+ case E_ARRAY:
269
+ {
270
+ if (NULL != m_value.p_array) {
271
+ delete m_value.p_array;
272
+ m_value.p_array = NULL;
273
+ }
274
+ }
275
+ break;
276
+ case E_OBJECT:
277
+ {
278
+ if (NULL != m_value.p_object) {
279
+ delete m_value.p_object;
280
+ m_value.p_object = NULL;
281
+ }
282
+
283
+ }
284
+ break;
285
+ case E_DATE:
286
+ {
287
+ m_value.v_date = 0;
288
+ }
289
+ break;
290
+ case E_DATA:
291
+ {
292
+ if (NULL != m_value.p_data) {
293
+ delete m_value.p_data;
294
+ m_value.p_data = NULL;
295
+ }
296
+ }
297
+ break;
298
+ default:
299
+ break;
300
+ }
301
+ m_type = E_NULL;
302
+ }
303
+
304
+ jvalue::jtype jvalue::type() const
305
+ {
306
+ return m_type;
307
+ }
308
+
309
+ int jvalue::as_int() const
310
+ {
311
+ return (int)as_int64();
312
+ }
313
+
314
+ int64_t jvalue::as_int64() const
315
+ {
316
+ switch (m_type) {
317
+ case E_INT:
318
+ return m_value.v_int64;
319
+ break;
320
+ case E_BOOL:
321
+ return m_value.v_bool ? 1 : 0;
322
+ break;
323
+ case E_FLOAT:
324
+ return int(m_value.v_double);
325
+ break;
326
+ case E_STRING:
327
+ return _atoi64(as_cstr());
328
+ break;
329
+ default:
330
+ break;
331
+ }
332
+ return 0;
333
+ }
334
+
335
+ double jvalue::as_double() const
336
+ {
337
+ switch (m_type) {
338
+ case E_INT:
339
+ return double(m_value.v_int64);
340
+ break;
341
+ case E_BOOL:
342
+ return m_value.v_bool ? 1.0 : 0.0;
343
+ break;
344
+ case E_FLOAT:
345
+ return m_value.v_double;
346
+ break;
347
+ case E_STRING:
348
+ return atof(as_cstr());
349
+ break;
350
+ default:
351
+ break;
352
+ }
353
+ return 0.0;
354
+ }
355
+
356
+ bool jvalue::as_bool() const
357
+ {
358
+ switch (m_type) {
359
+ case E_BOOL:
360
+ return m_value.v_bool;
361
+ break;
362
+ case E_INT:
363
+ return (0 != m_value.v_int64);
364
+ break;
365
+ case E_FLOAT:
366
+ return (0.0 != m_value.v_double);
367
+ break;
368
+ case E_ARRAY:
369
+ return (NULL == m_value.p_array) ? false : (m_value.p_array->size() > 0);
370
+ break;
371
+ case E_OBJECT:
372
+ return (NULL == m_value.p_object) ? false : (m_value.p_object->size() > 0);
373
+ break;
374
+ case E_STRING:
375
+ return (NULL == m_value.p_string) ? false : (strlen(m_value.p_string) > 0);
376
+ break;
377
+ case E_DATE:
378
+ return (m_value.v_date > 0);
379
+ break;
380
+ case E_DATA:
381
+ return (NULL == m_value.p_data) ? false : (m_value.p_data->size() > 0);
382
+ break;
383
+ default:
384
+ break;
385
+ }
386
+ return false;
387
+ }
388
+
389
+ string jvalue::as_string() const
390
+ {
391
+ switch (m_type) {
392
+ case E_BOOL:
393
+ return m_value.v_bool ? "true" : "false";
394
+ break;
395
+ case E_INT:
396
+ {
397
+ char buf[32];
398
+ ::snprintf(buf, 32, "%" PRId64, m_value.v_int64);
399
+ return buf;
400
+ }
401
+ break;
402
+ case E_FLOAT:
403
+ {
404
+ char buf[256];
405
+ ::snprintf(buf, 256, "%lf", m_value.v_double);
406
+ return buf;
407
+ }
408
+ break;
409
+ case E_ARRAY:
410
+ return "array";
411
+ break;
412
+ case E_OBJECT:
413
+ return "object";
414
+ break;
415
+ case E_STRING:
416
+ return (NULL == m_value.p_string) ? "" : m_value.p_string;
417
+ break;
418
+ case E_DATE:
419
+ {
420
+ char buf[256];
421
+ #ifdef _WIN32
422
+ ::snprintf(buf, 256, "%lld", m_value.v_date);
423
+ #else
424
+ ::snprintf(buf, 256, "%ld", m_value.v_date);
425
+ #endif
426
+ return buf;
427
+ }
428
+ break;
429
+ case E_DATA:
430
+ return as_data();
431
+ break;
432
+ default:
433
+ break;
434
+ }
435
+ return "";
436
+ }
437
+
438
+ const char* jvalue::as_cstr() const
439
+ {
440
+ if (E_STRING == m_type && NULL != m_value.p_string) {
441
+ return m_value.p_string;
442
+ }
443
+ return "";
444
+ }
445
+
446
+ size_t jvalue::size() const
447
+ {
448
+ switch (m_type) {
449
+ case E_ARRAY:
450
+ return (NULL == m_value.p_array) ? 0 : m_value.p_array->size();
451
+ break;
452
+ case E_OBJECT:
453
+ return (NULL == m_value.p_object) ? 0 : m_value.p_object->size();
454
+ break;
455
+ case E_DATA:
456
+ return (NULL == m_value.p_data) ? 0 : m_value.p_data->size();
457
+ break;
458
+ default:
459
+ break;
460
+ }
461
+ return 0;
462
+ }
463
+
464
+ jvalue& jvalue::operator=(const jvalue& other)
465
+ {
466
+ if (this != &other) {
467
+ _free();
468
+ _copy_value(other);
469
+ }
470
+ return (*this);
471
+ }
472
+
473
+ jvalue& jvalue::operator[](int index)
474
+ {
475
+ return (*this)[(size_t)(index < 0 ? 0 : index)];
476
+ }
477
+
478
+ const jvalue& jvalue::operator[](int index) const
479
+ {
480
+ return (*this)[(size_t)(index < 0 ? 0 : index)];
481
+ }
482
+
483
+ jvalue& jvalue::operator[](int64_t index)
484
+ {
485
+ return (*this)[(size_t)(index < 0 ? 0 : index)];
486
+ }
487
+
488
+ const jvalue& jvalue::operator[](int64_t index) const
489
+ {
490
+ return (*this)[(size_t)(index < 0 ? 0 : index)];
491
+ }
492
+
493
+ jvalue& jvalue::operator[](size_t index)
494
+ {
495
+ if (E_ARRAY != m_type || NULL == m_value.p_array) {
496
+ _free();
497
+ m_type = E_ARRAY;
498
+ m_value.p_array = new array();
499
+ }
500
+
501
+ size_t sum = m_value.p_array->size();
502
+ if (sum <= index) {
503
+ size_t fill = index - sum;
504
+ for (size_t i = 0; i <= fill; i++) {
505
+ m_value.p_array->push_back(null);
506
+ }
507
+ }
508
+
509
+ return m_value.p_array->at(index);
510
+ }
511
+
512
+ const jvalue& jvalue::operator[](size_t index) const
513
+ {
514
+ if (E_ARRAY == m_type && NULL != m_value.p_array) {
515
+ if (index < m_value.p_array->size()) {
516
+ return m_value.p_array->at(index);
517
+ }
518
+ }
519
+ return null;
520
+ }
521
+
522
+ jvalue& jvalue::operator[](const string& key)
523
+ {
524
+ return (*this)[key.c_str()];
525
+ }
526
+
527
+ const jvalue& jvalue::operator[](const string& key) const
528
+ {
529
+ return (*this)[key.c_str()];
530
+ }
531
+
532
+ jvalue& jvalue::operator[](const char* key)
533
+ {
534
+ if (E_OBJECT != m_type || NULL == m_value.p_object) {
535
+ _free();
536
+ m_type = E_OBJECT;
537
+ m_value.p_object = new object();
538
+ } else {
539
+ auto it = m_value.p_object->find(key);
540
+ if (it != m_value.p_object->end()) {
541
+ return it->second;
542
+ }
543
+ }
544
+ auto it = m_value.p_object->insert(m_value.p_object->end(), make_pair(key, null));
545
+ return it->second;
546
+ }
547
+
548
+ const jvalue& jvalue::operator[](const char* key) const
549
+ {
550
+ if (E_OBJECT == m_type && NULL != m_value.p_object) {
551
+ auto it = m_value.p_object->find(key);
552
+ if (it != m_value.p_object->end()) {
553
+ return it->second;
554
+ }
555
+ }
556
+ return null;
557
+ }
558
+
559
+ bool jvalue::has(int index) const
560
+ {
561
+ if (index >= 0) {
562
+ return has((size_t)index);
563
+ }
564
+ return false;
565
+ }
566
+
567
+ bool jvalue::has(size_t index) const
568
+ {
569
+ if (E_ARRAY == m_type && NULL != m_value.p_array) {
570
+ if (index < size()) {
571
+ return true;
572
+ }
573
+ }
574
+ return false;
575
+ }
576
+
577
+ bool jvalue::has(const char* key) const
578
+ {
579
+ if (E_OBJECT == m_type && NULL != m_value.p_object) {
580
+ if (m_value.p_object->end() != m_value.p_object->find(key)) {
581
+ return true;
582
+ }
583
+ }
584
+ return false;
585
+ }
586
+
587
+ bool jvalue::has(const string& key) const
588
+ {
589
+ return has(key.c_str());
590
+ }
591
+
592
+ const jvalue& jvalue::at(int index) const
593
+ {
594
+ return (*this)[(size_t)(index < 0 ? 0 : index)];
595
+ }
596
+
597
+ const jvalue& jvalue::at(size_t index) const
598
+ {
599
+ return (*this)[index];
600
+ }
601
+
602
+ const jvalue& jvalue::at(const char* key) const
603
+ {
604
+ return (*this)[key];
605
+ }
606
+
607
+ bool jvalue::erase(int index)
608
+ {
609
+ if (index >= 0) {
610
+ return erase((size_t)index);
611
+ }
612
+ return false;
613
+ }
614
+
615
+ bool jvalue::erase(size_t index)
616
+ {
617
+ if (E_ARRAY == m_type && NULL != m_value.p_array) {
618
+ if (index < m_value.p_array->size()) {
619
+ m_value.p_array->erase(m_value.p_array->begin() + index);
620
+ return true;
621
+ }
622
+ }
623
+ return false;
624
+ }
625
+
626
+ bool jvalue::erase(const char* key)
627
+ {
628
+ if (E_OBJECT == m_type && NULL != m_value.p_object) {
629
+ if (m_value.p_object->end() != m_value.p_object->find(key)) {
630
+ m_value.p_object->erase(key);
631
+ return !has(key);
632
+ }
633
+ }
634
+ return false;
635
+ }
636
+
637
+ bool jvalue::get_keys(vector<string>& keys) const
638
+ {
639
+ if (E_OBJECT == m_type && NULL != m_value.p_object) {
640
+ return _map_keys(keys);
641
+ }
642
+ return false;
643
+ }
644
+
645
+ bool jvalue::_map_keys(vector<string>& keys) const
646
+ {
647
+ if (E_OBJECT == m_type && NULL != m_value.p_object) {
648
+ keys.reserve(m_value.p_object->size());
649
+ auto itbeg = m_value.p_object->begin();
650
+ auto itend = m_value.p_object->end();
651
+ for (; itbeg != itend; itbeg++) {
652
+ keys.push_back((itbeg->first).c_str());
653
+ }
654
+ return true;
655
+ }
656
+ return false;
657
+ }
658
+
659
+ int jvalue::index(const char* elem) const
660
+ {
661
+ if (E_ARRAY == m_type && NULL != m_value.p_array) {
662
+ for (size_t i = 0; i < m_value.p_array->size(); i++) {
663
+ if (elem == (*m_value.p_array)[i].as_string()) {
664
+ return (int)i;
665
+ }
666
+ }
667
+ }
668
+ return -1;
669
+ }
670
+
671
+ string jvalue::write() const
672
+ {
673
+ string strdoc;
674
+ return write(strdoc);
675
+ }
676
+
677
+ const char* jvalue::write(string& strdoc) const
678
+ {
679
+ strdoc.clear();
680
+ jwriter::write((*this), strdoc);
681
+ return strdoc.c_str();
682
+ }
683
+
684
+ bool jvalue::read(const string& strdoc, string* pstrerr)
685
+ {
686
+ return read(strdoc.c_str(), pstrerr);
687
+ }
688
+
689
+ bool jvalue::read(const char* pdoc, string* pstrerr)
690
+ {
691
+ jreader reader;
692
+ bool bret = reader.parse(pdoc, *this);
693
+ if (!bret) {
694
+ if (NULL != pstrerr) {
695
+ reader.error(*pstrerr);
696
+ }
697
+ }
698
+ return bret;
699
+ }
700
+
701
+ jvalue& jvalue::front()
702
+ {
703
+ if (E_ARRAY == m_type) {
704
+ if (size() > 0) {
705
+ return *(m_value.p_array->begin());
706
+ }
707
+ } else if (E_OBJECT == m_type) {
708
+ if (size() > 0) {
709
+ return m_value.p_object->begin()->second;
710
+ }
711
+ }
712
+ return (*this);
713
+ }
714
+
715
+ jvalue& jvalue::back()
716
+ {
717
+ if (E_ARRAY == m_type) {
718
+ if (size() > 0) {
719
+ return *(m_value.p_array->rbegin());
720
+ }
721
+ } else if (E_OBJECT == m_type) {
722
+ if (size() > 0) {
723
+ return prev(m_value.p_object->end())->second;
724
+ }
725
+ }
726
+ return (*this);
727
+ }
728
+
729
+ bool jvalue::append(jvalue& jv)
730
+ {
731
+ if ((E_OBJECT == m_type || E_NULL == m_type) && E_OBJECT == jv.type()) {
732
+ vector<string> keys;
733
+ jv.get_keys(keys);
734
+ for (size_t i = 0; i < keys.size(); i++) {
735
+ (*this)[keys[i]] = jv[keys[i]];
736
+ }
737
+ return true;
738
+ } else if ((E_ARRAY == m_type || E_NULL == m_type) && E_ARRAY == jv.type()) {
739
+ size_t count = this->size();
740
+ for (size_t i = 0; i < jv.size(); i++) {
741
+ (*this)[count] = jv[i];
742
+ count++;
743
+ }
744
+ return true;
745
+ }
746
+
747
+ return false;
748
+ }
749
+
750
+ bool jvalue::push_back(int val)
751
+ {
752
+ return push_back(jvalue(val));
753
+ }
754
+
755
+ bool jvalue::push_back(bool val)
756
+ {
757
+ return push_back(jvalue(val));
758
+ }
759
+
760
+ bool jvalue::push_back(double val)
761
+ {
762
+ return push_back(jvalue(val));
763
+ }
764
+
765
+ bool jvalue::push_back(int64_t val)
766
+ {
767
+ return push_back(jvalue(val));
768
+ }
769
+
770
+ bool jvalue::push_back(const char* val)
771
+ {
772
+ return push_back(jvalue(val));
773
+ }
774
+
775
+ bool jvalue::push_back(const string& val)
776
+ {
777
+ return push_back(jvalue(val));
778
+ }
779
+
780
+ bool jvalue::push_back(const jvalue& jval)
781
+ {
782
+ if (E_ARRAY == m_type || E_NULL == m_type) {
783
+ (*this)[size()] = jval;
784
+ return true;
785
+ }
786
+ return false;
787
+ }
788
+
789
+ bool jvalue::push_back(const char* val, size_t len)
790
+ {
791
+ return push_back(jvalue(val, len));
792
+ }
793
+
794
+ string jvalue::style_write() const
795
+ {
796
+ string strdoc;
797
+ return style_write(strdoc);
798
+ }
799
+
800
+ const char* jvalue::style_write(string& strdoc) const
801
+ {
802
+ strdoc.clear();
803
+ jwriter jw;
804
+ strdoc = jw.style_write(*this);
805
+ return strdoc.c_str();
806
+ }
807
+
808
+ void jvalue::assign_date(time_t val)
809
+ {
810
+ _free();
811
+ m_type = E_DATE;
812
+ m_value.v_date = val;
813
+ }
814
+
815
+ void jvalue::assign_data(const uint8_t* data, size_t size)
816
+ {
817
+ _free();
818
+ m_type = E_DATA;
819
+ m_value.p_data = new string();
820
+ m_value.p_data->append((const char*)data, size);
821
+ }
822
+
823
+ void jvalue::assign_data(const char* base64)
824
+ {
825
+ jbase64 b64;
826
+ string output;
827
+ b64.decode(base64, output);
828
+ assign_data(output);
829
+ }
830
+
831
+ void jvalue::assign_data(const string& data)
832
+ {
833
+ return assign_data(data.data(), data.size());
834
+ }
835
+
836
+ void jvalue::assign_data(const char* data, size_t size)
837
+ {
838
+ return assign_data((const uint8_t*)data, size);
839
+ }
840
+
841
+ void jvalue::assign_date_string(time_t val)
842
+ {
843
+ _free();
844
+ m_type = E_STRING;
845
+ m_value.p_string = _new_string(jwriter::d2s(val).c_str());
846
+ }
847
+
848
+ time_t jvalue::as_date() const
849
+ {
850
+ switch (m_type) {
851
+ case E_DATE:
852
+ return m_value.v_date;
853
+ break;
854
+ case E_STRING:
855
+ {
856
+ if (is_date_string()) {
857
+ tm ft = { 0 };
858
+ sscanf_s(m_value.p_string + 5, "%04d-%02d-%02dT%02d:%02d:%02dZ", &ft.tm_year, &ft.tm_mon, &ft.tm_mday, &ft.tm_hour, &ft.tm_min, &ft.tm_sec);
859
+ ft.tm_mon -= 1;
860
+ ft.tm_year -= 1900;
861
+ return mktime(&ft);
862
+ }
863
+ }
864
+ break;
865
+ case E_NULL:
866
+ case E_INT:
867
+ case E_FLOAT:
868
+ case E_BOOL:
869
+ case E_ARRAY:
870
+ case E_OBJECT:
871
+ case E_DATA:
872
+ break;
873
+ }
874
+ return 0;
875
+ }
876
+
877
+ string jvalue::as_data() const
878
+ {
879
+ switch (m_type) {
880
+ case E_DATA:
881
+ return (NULL == m_value.p_data) ? null_data : *m_value.p_data;
882
+ break;
883
+ case E_STRING:
884
+ {
885
+ string data;
886
+ as_data(data);
887
+ return data;
888
+ }
889
+ break;
890
+ case E_NULL:
891
+ case E_INT:
892
+ case E_FLOAT:
893
+ case E_BOOL:
894
+ case E_ARRAY:
895
+ case E_OBJECT:
896
+ case E_DATE:
897
+ break;
898
+ }
899
+ return null_data;
900
+ }
901
+
902
+ bool jvalue::as_data(string& data) const
903
+ {
904
+ switch (m_type) {
905
+ case E_DATA:
906
+ {
907
+ data = (NULL == m_value.p_data) ? null_data : *m_value.p_data;
908
+ return true;
909
+ }
910
+ break;
911
+ case E_STRING:
912
+ {
913
+ if (is_data_string()) {
914
+ jbase64 b64;
915
+ int data_len = 0;
916
+ const char* pdata = b64.decode(m_value.p_string + 5, 0, &data_len);
917
+ data.append(pdata, data_len);
918
+ return true;
919
+ }
920
+ }
921
+ break;
922
+ case E_NULL:
923
+ case E_INT:
924
+ case E_FLOAT:
925
+ case E_BOOL:
926
+ case E_ARRAY:
927
+ case E_OBJECT:
928
+ case E_DATE:
929
+ break;
930
+ }
931
+ return false;
932
+ }
933
+
934
+ bool jvalue::is_data() const
935
+ {
936
+ return (E_DATA == m_type);
937
+ }
938
+
939
+ bool jvalue::is_date() const
940
+ {
941
+ return (E_DATE == m_type);
942
+ }
943
+
944
+ bool jvalue::is_data_string() const
945
+ {
946
+ if (E_STRING == m_type) {
947
+ if (NULL != m_value.p_string) {
948
+ if (strlen(m_value.p_string) >= 5) {
949
+ if (0 == memcmp(m_value.p_string, "data:", 5)) {
950
+ return true;
951
+ }
952
+ }
953
+ }
954
+ }
955
+
956
+ return false;
957
+ }
958
+
959
+ bool jvalue::is_date_string() const
960
+ {
961
+ if (E_STRING == m_type) {
962
+ if (NULL != m_value.p_string) {
963
+ if (25 == strlen(m_value.p_string)) {
964
+ if (0 == memcmp(m_value.p_string, "date:", 5)) {
965
+ const char* pdate = m_value.p_string + 5;
966
+ if ('T' == pdate[10] && 'Z' == pdate[19]) {
967
+ return true;
968
+ }
969
+ }
970
+ }
971
+ }
972
+ }
973
+
974
+ return false;
975
+ }
976
+
977
+ bool jvalue::read_plist(const string& strdoc, string* pstrerr /*= NULL*/, bool* is_binary /*= NULL*/)
978
+ {
979
+ return read_plist(strdoc.data(), strdoc.size(), pstrerr, is_binary);
980
+ }
981
+
982
+ bool jvalue::read_plist(const char* pdoc, size_t len /*= 0*/, string* pstrerr /*= NULL*/, bool* is_binary /*= NULL*/)
983
+ {
984
+ if (NULL == pdoc) {
985
+ return false;
986
+ }
987
+
988
+ if (0 == len) {
989
+ len = strlen(pdoc);
990
+ }
991
+
992
+ jpreader reader;
993
+ bool bret = reader.parse(pdoc, len, *this, is_binary);
994
+ if (!bret) {
995
+ if (NULL != pstrerr) {
996
+ reader.error(*pstrerr);
997
+ }
998
+ }
999
+
1000
+ return bret;
1001
+ }
1002
+
1003
+ bool jvalue::_read_data_from_file(const char* path, string& data)
1004
+ {
1005
+ data.clear();
1006
+ FILE* fp = NULL;
1007
+ _fopen64(fp, path, "rb");
1008
+ if (NULL != fp) {
1009
+ _fseeki64(fp, 0, SEEK_END);
1010
+ int64_t to_read = _ftelli64(fp);
1011
+ _fseeki64(fp, 0, SEEK_SET);
1012
+ to_read = (to_read > 0 ? to_read : 0);
1013
+ data.resize(to_read);
1014
+ if (data.capacity() >= (size_t)to_read) {
1015
+ int64_t readed = 0;
1016
+ while (readed < to_read) {
1017
+ size_t ret = fread(&(data[readed]), 1, to_read - readed, fp);
1018
+ if (ret <= 0) {
1019
+ break;
1020
+ }
1021
+ readed += ret;
1022
+ }
1023
+ }
1024
+ fclose(fp);
1025
+ return (data.size() == to_read);
1026
+ }
1027
+ return false;
1028
+ }
1029
+
1030
+ bool jvalue::read_from_file(const char* path, ...)
1031
+ {
1032
+ char file[1024] = { 0 };
1033
+ va_list args;
1034
+ va_start(args, path);
1035
+ vsnprintf(file, 1024, path, args);
1036
+ va_end(args);
1037
+
1038
+ string data;
1039
+ if (_read_data_from_file(file, data)) {
1040
+ return read(data);
1041
+ }
1042
+ return false;
1043
+ }
1044
+
1045
+ bool jvalue::read_plist_from_file(const char* path, ...)
1046
+ {
1047
+ char file[1024] = { 0 };
1048
+ va_list args;
1049
+ va_start(args, path);
1050
+ vsnprintf(file, 1024, path, args);
1051
+ va_end(args);
1052
+
1053
+ string data;
1054
+ if (_read_data_from_file(file, data)) {
1055
+ return read_plist(data);
1056
+ }
1057
+ return false;
1058
+ }
1059
+
1060
+ bool jvalue::_write_data_to_file(const char* path, string& data)
1061
+ {
1062
+ FILE* fp = NULL;
1063
+ _fopen64(fp, path, "wb");
1064
+ if (NULL != fp) {
1065
+ size_t written = 0;
1066
+ size_t to_write = data.size();
1067
+ while (written < to_write) {
1068
+ size_t ret = fwrite(data.data() + written, 1, to_write - written, fp);
1069
+ if (ret <= 0) {
1070
+ break;
1071
+ }
1072
+ written += ret;
1073
+ }
1074
+ fclose(fp);
1075
+ return (written == to_write);
1076
+ }
1077
+ return false;
1078
+ }
1079
+
1080
+ bool jvalue::write_to_file(const char* path, ...)
1081
+ {
1082
+ char file[1024] = { 0 };
1083
+ va_list args;
1084
+ va_start(args, path);
1085
+ vsnprintf(file, 1024, path, args);
1086
+ va_end(args);
1087
+
1088
+ string data;
1089
+ write(data);
1090
+ return _write_data_to_file(file, data);
1091
+ }
1092
+
1093
+ bool jvalue::write_plist_to_file(const char* path, ...)
1094
+ {
1095
+ char file[1024] = { 0 };
1096
+ va_list args;
1097
+ va_start(args, path);
1098
+ vsnprintf(file, 1024, path, args);
1099
+ va_end(args);
1100
+
1101
+ string data;
1102
+ write_plist(data);
1103
+ return _write_data_to_file(file, data);
1104
+ }
1105
+
1106
+ bool jvalue::write_bplist_to_file(const char* path, ...)
1107
+ {
1108
+ char file[1024] = { 0 };
1109
+ va_list args;
1110
+ va_start(args, path);
1111
+ vsnprintf(file, 1024, path, args);
1112
+ va_end(args);
1113
+
1114
+ string data;
1115
+ write_bplist(data);
1116
+ return _write_data_to_file(file, data);
1117
+ }
1118
+
1119
+ bool jvalue::style_write_to_file(const char* path, ...)
1120
+ {
1121
+ char file[1024] = { 0 };
1122
+ va_list args;
1123
+ va_start(args, path);
1124
+ vsnprintf(file, 1024, path, args);
1125
+ va_end(args);
1126
+
1127
+ string data;
1128
+ style_write(data);
1129
+ return _write_data_to_file(file, data);
1130
+ }
1131
+
1132
+ bool jvalue::style_write_plist_to_file(const char* path, ...)
1133
+ {
1134
+ char file[1024] = { 0 };
1135
+ va_list args;
1136
+ va_start(args, path);
1137
+ vsnprintf(file, 1024, path, args);
1138
+ va_end(args);
1139
+
1140
+ string data;
1141
+ style_write_plist(data);
1142
+ return _write_data_to_file(file, data);
1143
+ }
1144
+
1145
+ string jvalue::write_plist() const
1146
+ {
1147
+ string strdoc;
1148
+ return write_plist(strdoc);
1149
+ }
1150
+
1151
+ const char* jvalue::write_plist(string& strdoc) const
1152
+ {
1153
+ strdoc.clear();
1154
+ jpwriter pw;
1155
+ pw.write((*this), strdoc);
1156
+ return strdoc.c_str();
1157
+ }
1158
+
1159
+ string jvalue::style_write_plist() const
1160
+ {
1161
+ string strdoc;
1162
+ return style_write_plist(strdoc);
1163
+ }
1164
+
1165
+ const char* jvalue::style_write_plist(string& strdoc) const
1166
+ {
1167
+ strdoc.clear();
1168
+ jpwriter pw;
1169
+ strdoc = pw.style_write(*this);
1170
+ return strdoc.c_str();
1171
+ }
1172
+
1173
+ bool jvalue::write_bplist(string& strdoc) const
1174
+ {
1175
+ strdoc.clear();
1176
+ jpwriter pw;
1177
+ pw.write_to_binary((*this), strdoc);
1178
+ return !strdoc.empty();
1179
+ }
1180
+
1181
+ string jvalue::write_to_html() const
1182
+ {
1183
+ string strdoc;
1184
+ jwriter::write_to_html((*this), strdoc);
1185
+ return strdoc;
1186
+ }
1187
+
1188
+
1189
+ // Class Reader
1190
+ // //////////////////////////////////////////////////////////////////
1191
+ jreader::jreader()
1192
+ {
1193
+ m_pbegin = NULL;
1194
+ m_pend = NULL;
1195
+ m_pcursor = NULL;
1196
+ m_perror = NULL;
1197
+ }
1198
+
1199
+ bool jreader::parse(const char* pdoc, jvalue& root)
1200
+ {
1201
+ if (NULL != pdoc) {
1202
+ m_pbegin = pdoc;
1203
+ m_pend = m_pbegin + strlen(pdoc);
1204
+ m_pcursor = m_pbegin;
1205
+ m_perror = m_pbegin;
1206
+ m_strerr = "null";
1207
+
1208
+ root.clear();
1209
+ return _read_value(root);
1210
+ }
1211
+ return false;
1212
+ }
1213
+
1214
+ bool jreader::_read_value(jvalue& jval)
1215
+ {
1216
+ jtoken token;
1217
+ _read_token(token);
1218
+ switch (token.type) {
1219
+ case jtoken::E_JTOKEN_TRUE:
1220
+ jval = true;
1221
+ break;
1222
+ case jtoken::E_JTOKEN_FALSE:
1223
+ jval = false;
1224
+ break;
1225
+ case jtoken::E_JTOKEN_NULL:
1226
+ jval = jvalue();
1227
+ break;
1228
+ case jtoken::E_JTOKEN_NUMBER:
1229
+ return _decode_number(token, jval);
1230
+ break;
1231
+ case jtoken::E_JTOKEN_ARRAY_BEGIN:
1232
+ return _read_array(jval);
1233
+ break;
1234
+ case jtoken::E_JTOKEN_OBJECT_BEGIN:
1235
+ return _read_object(jval);
1236
+ break;
1237
+ case jtoken::E_JTOKEN_STRING:
1238
+ {
1239
+ string strval;
1240
+ bool bok = _decode_string(token, strval);
1241
+ if (bok) {
1242
+ jval = strval.c_str();
1243
+ }
1244
+ return bok;
1245
+ }
1246
+ break;
1247
+ default:
1248
+ return _add_error("Syntax error: value, object or array expected.", token.pbegin);
1249
+ break;
1250
+ }
1251
+ return true;
1252
+ }
1253
+
1254
+ bool jreader::_read_token(jtoken& token)
1255
+ {
1256
+ _skip_spaces();
1257
+ token.pbegin = m_pcursor;
1258
+ switch (_get_next_char()) {
1259
+ case '{':
1260
+ token.type = jtoken::E_JTOKEN_OBJECT_BEGIN;
1261
+ break;
1262
+ case '}':
1263
+ token.type = jtoken::E_JTOKEN_OBJECT_END;
1264
+ break;
1265
+ case '[':
1266
+ token.type = jtoken::E_JTOKEN_ARRAY_BEGIN;
1267
+ break;
1268
+ case ']':
1269
+ token.type = jtoken::E_JTOKEN_ARRAY_END;
1270
+ break;
1271
+ case ',':
1272
+ token.type = jtoken::E_JTOKEN_ARRAY_SEPARATOR;
1273
+ break;
1274
+ case ':':
1275
+ token.type = jtoken::E_JTOKEN_MEMBER_SEPARATOR;
1276
+ break;
1277
+ case 0:
1278
+ token.type = jtoken::E_JTOKEN_END;
1279
+ break;
1280
+ case '"':
1281
+ token.type = _read_string() ? jtoken::E_JTOKEN_STRING : jtoken::E_JTOKEN_ERROR;
1282
+ break;
1283
+ case '/':
1284
+ case '#':
1285
+ case ';':
1286
+ {
1287
+ _skip_comment();
1288
+ return _read_token(token);
1289
+ }
1290
+ break;
1291
+ case '0':
1292
+ case '1':
1293
+ case '2':
1294
+ case '3':
1295
+ case '4':
1296
+ case '5':
1297
+ case '6':
1298
+ case '7':
1299
+ case '8':
1300
+ case '9':
1301
+ case '-':
1302
+ {
1303
+ token.type = jtoken::E_JTOKEN_NUMBER;
1304
+ _read_number();
1305
+ }
1306
+ break;
1307
+ case 't':
1308
+ token.type = _match("rue", 3) ? jtoken::E_JTOKEN_TRUE : jtoken::E_JTOKEN_ERROR;
1309
+ break;
1310
+ case 'f':
1311
+ token.type = _match("alse", 4) ? jtoken::E_JTOKEN_FALSE : jtoken::E_JTOKEN_ERROR;
1312
+ break;
1313
+ case 'n':
1314
+ token.type = _match("ull", 3) ? jtoken::E_JTOKEN_NULL : jtoken::E_JTOKEN_ERROR;
1315
+ break;
1316
+ default:
1317
+ token.type = jtoken::E_JTOKEN_ERROR;
1318
+ break;
1319
+ }
1320
+ token.pend = m_pcursor;
1321
+ return true;
1322
+ }
1323
+
1324
+ void jreader::_skip_spaces()
1325
+ {
1326
+ while (m_pcursor != m_pend) {
1327
+ char c = *m_pcursor;
1328
+ if (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
1329
+ m_pcursor++;
1330
+ } else {
1331
+ break;
1332
+ }
1333
+ }
1334
+ }
1335
+
1336
+ bool jreader::_match(const char* pattern, int pattern_length)
1337
+ {
1338
+ if (m_pend - m_pcursor < pattern_length) {
1339
+ return false;
1340
+ }
1341
+ int index = pattern_length;
1342
+ while (index--) {
1343
+ if (m_pcursor[index] != pattern[index]) {
1344
+ return false;
1345
+ }
1346
+ }
1347
+ m_pcursor += pattern_length;
1348
+ return true;
1349
+ }
1350
+
1351
+ void jreader::_skip_comment()
1352
+ {
1353
+ char c = _get_next_char();
1354
+ if (c == '*') {
1355
+ while (m_pcursor != m_pend) {
1356
+ char c = _get_next_char();
1357
+ if (c == '*' && *m_pcursor == '/') {
1358
+ break;
1359
+ }
1360
+ }
1361
+ } else if (c == '/') {
1362
+ while (m_pcursor != m_pend) {
1363
+ char c = _get_next_char();
1364
+ if (c == '\r' || c == '\n') {
1365
+ break;
1366
+ }
1367
+ }
1368
+ }
1369
+ }
1370
+
1371
+ void jreader::_read_number()
1372
+ {
1373
+ while (m_pcursor != m_pend) {
1374
+ char c = *m_pcursor;
1375
+ if ((c >= '0' && c <= '9') || (c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-')) {
1376
+ ++m_pcursor;
1377
+ } else {
1378
+ break;
1379
+ }
1380
+ }
1381
+ }
1382
+
1383
+ bool jreader::_read_string()
1384
+ {
1385
+ char c = 0;
1386
+ while (m_pcursor != m_pend) {
1387
+ c = _get_next_char();
1388
+ if ('\\' == c) {
1389
+ _get_next_char();
1390
+ } else if ('"' == c) {
1391
+ break;
1392
+ }
1393
+ }
1394
+ return ('"' == c);
1395
+ }
1396
+
1397
+ bool jreader::_read_object(jvalue& jval)
1398
+ {
1399
+ string name;
1400
+ jtoken token_name;
1401
+ if (jvalue::E_OBJECT != jval.type()) {
1402
+ jval = jvalue(jvalue::E_OBJECT);
1403
+ }
1404
+ while (_read_token(token_name)) {
1405
+ if (jtoken::E_JTOKEN_OBJECT_END == token_name.type) {//empty
1406
+ return true;
1407
+ }
1408
+
1409
+ if (jtoken::E_JTOKEN_STRING != token_name.type) {
1410
+ break;
1411
+ }
1412
+
1413
+ if (!_decode_string(token_name, name)) {
1414
+ return false;
1415
+ }
1416
+
1417
+ jtoken colon;
1418
+ _read_token(colon);
1419
+ if (jtoken::E_JTOKEN_MEMBER_SEPARATOR != colon.type) {
1420
+ return _add_error("missing ':' after object member name", colon.pbegin);
1421
+ }
1422
+
1423
+ if (!_read_value(jval[name.c_str()])) {// error already set
1424
+ return false;
1425
+ }
1426
+
1427
+ jtoken comma;
1428
+ _read_token(comma);
1429
+ if (jtoken::E_JTOKEN_OBJECT_END == comma.type) {
1430
+ return true;
1431
+ }
1432
+
1433
+ if (jtoken::E_JTOKEN_ARRAY_SEPARATOR != comma.type) {
1434
+ return _add_error("missing ',' or '}' in object declaration", comma.pbegin);
1435
+ }
1436
+ }
1437
+ return _add_error("missing '}' or object member name", token_name.pbegin);
1438
+ }
1439
+
1440
+
1441
+ bool jreader::_read_array(jvalue& jval)
1442
+ {
1443
+ jval = jvalue(jvalue::E_ARRAY);
1444
+ _skip_spaces();
1445
+ if (']' == *m_pcursor) // empty array
1446
+ {
1447
+ jtoken endArray;
1448
+ _read_token(endArray);
1449
+ return true;
1450
+ }
1451
+
1452
+ size_t index = 0;
1453
+ while (true) {
1454
+ if (!_read_value(jval[index++])) {//error already set
1455
+ return false;
1456
+ }
1457
+
1458
+ jtoken token;
1459
+ _read_token(token);
1460
+ if (jtoken::E_JTOKEN_ARRAY_END == token.type) {
1461
+ break;
1462
+ }
1463
+ if (jtoken::E_JTOKEN_ARRAY_SEPARATOR != token.type) {
1464
+ return _add_error("missing ',' or ']' in array declaration", token.pbegin);
1465
+ }
1466
+ }
1467
+ return true;
1468
+ }
1469
+
1470
+ bool jreader::_decode_number(jtoken& token, jvalue& jval)
1471
+ {
1472
+ int64_t val = 0;
1473
+ bool isNeg = false;
1474
+ const char* pcur = token.pbegin;
1475
+ if ('-' == *pcur) {
1476
+ pcur++;
1477
+ isNeg = true;
1478
+ }
1479
+ for (const char* p = pcur; p != token.pend; p++) {
1480
+ char c = *p;
1481
+ if ('.' == c || 'e' == c || 'E' == c) {
1482
+ return _decode_double(token, jval);
1483
+ } else if (c < '0' || c > '9') {
1484
+ return _add_error("'" + string(token.pbegin, token.pend) + "' is not a number.", token.pbegin);
1485
+ } else {
1486
+ val = val * 10 + (c - '0');
1487
+ }
1488
+ }
1489
+ jval = isNeg ? -val : val;
1490
+ return true;
1491
+ }
1492
+
1493
+ bool jreader::_decode_double(jtoken& token, jvalue& jval)
1494
+ {
1495
+ const size_t buf_len = 64;
1496
+ size_t len = size_t(token.pend - token.pbegin);
1497
+ if (len < buf_len) {
1498
+ char buf[buf_len] = { 0 };
1499
+ ::memcpy(buf, token.pbegin, len);
1500
+ buf[len] = 0;
1501
+ double val = 0;
1502
+ if (1 == sscanf_s(buf, "%lf", &val)) {
1503
+ jval = val;
1504
+ return true;
1505
+ }
1506
+ }
1507
+ return _add_error("'" + string(token.pbegin, token.pend) + "' is too large or not a number.", token.pbegin);
1508
+ }
1509
+
1510
+ bool jreader::_decode_string(jtoken& token, string& strdec)
1511
+ {
1512
+ strdec = "";
1513
+ const char* pcur = token.pbegin + 1;
1514
+ const char* pend = token.pend - 1;
1515
+ strdec.reserve(size_t(token.pend - token.pbegin));
1516
+ while (pcur != pend) {
1517
+ char c = *pcur++;
1518
+ if ('\\' == c) {
1519
+ if (pcur != pend) {
1520
+ char escape = *pcur++;
1521
+ switch (escape) {
1522
+ case '"':
1523
+ strdec += '"';
1524
+ break;
1525
+ case '\\':
1526
+ strdec += '\\';
1527
+ break;
1528
+ case 'b':
1529
+ strdec += '\b';
1530
+ break;
1531
+ case 'f':
1532
+ strdec += '\f';
1533
+ break;
1534
+ case 'n':
1535
+ strdec += '\n';
1536
+ break;
1537
+ case 'r':
1538
+ strdec += '\r';
1539
+ break;
1540
+ case 't':
1541
+ strdec += '\t';
1542
+ break;
1543
+ case '/':
1544
+ strdec += '/';
1545
+ break;
1546
+ case 'u':
1547
+ {// based on description from http://en.wikipedia.org/wiki/UTF-8
1548
+
1549
+ string strUnic;
1550
+ strUnic.append(pcur, 4);
1551
+
1552
+ pcur += 4;
1553
+
1554
+ unsigned int cp = 0;
1555
+ if (1 != sscanf_s(strUnic.c_str(), "%x", &cp)) {
1556
+ return _add_error("Bad escape sequence in string", pcur);
1557
+ }
1558
+
1559
+ string strUTF8;
1560
+
1561
+ if (cp <= 0x7f) {
1562
+ strUTF8.resize(1);
1563
+ strUTF8[0] = static_cast<char>(cp);
1564
+ } else if (cp <= 0x7FF) {
1565
+ strUTF8.resize(2);
1566
+ strUTF8[1] = static_cast<char>(0x80 | (0x3f & cp));
1567
+ strUTF8[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
1568
+ } else if (cp <= 0xFFFF) {
1569
+ strUTF8.resize(3);
1570
+ strUTF8[2] = static_cast<char>(0x80 | (0x3f & cp));
1571
+ strUTF8[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6)));
1572
+ strUTF8[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12)));
1573
+ } else if (cp <= 0x10FFFF) {
1574
+ strUTF8.resize(4);
1575
+ strUTF8[3] = static_cast<char>(0x80 | (0x3f & cp));
1576
+ strUTF8[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
1577
+ strUTF8[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
1578
+ strUTF8[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
1579
+ }
1580
+
1581
+ strdec += strUTF8;
1582
+ }
1583
+ break;
1584
+ default:
1585
+ return _add_error("Bad escape sequence in string", pcur);
1586
+ break;
1587
+ }
1588
+ } else {
1589
+ return _add_error("Empty escape sequence in string", pcur);
1590
+ }
1591
+ } else if ('"' == c) {
1592
+ break;
1593
+ } else {
1594
+ strdec += c;
1595
+ }
1596
+ }
1597
+ return true;
1598
+ }
1599
+
1600
+ bool jreader::_add_error(const string& message, const char* ploc)
1601
+ {
1602
+ m_perror = ploc;
1603
+ m_strerr = message;
1604
+ return false;
1605
+ }
1606
+
1607
+ char jreader::_get_next_char()
1608
+ {
1609
+ return (m_pcursor == m_pend) ? 0 : *m_pcursor++;
1610
+ }
1611
+
1612
+ void jreader::error(string& strmsg) const
1613
+ {
1614
+ strmsg = "";
1615
+ int row = 1;
1616
+ const char* pcur = m_pbegin;
1617
+ const char* plast = m_pbegin;
1618
+ while (pcur < m_perror && pcur <= m_pend) {
1619
+ char c = *pcur++;
1620
+ if (c == '\r' || c == '\n') {
1621
+ if (c == '\r' && *pcur == '\n') {
1622
+ pcur++;
1623
+ }
1624
+ row++;
1625
+ plast = pcur;
1626
+ }
1627
+ }
1628
+ char msg[64] = { 0 };
1629
+ ::snprintf(msg, 64, "error: line %d, column %d, ", row, int(m_perror - plast) + 1);
1630
+ strmsg += msg + m_strerr + "\n";
1631
+ }
1632
+
1633
+ jwriter::jwriter()
1634
+ {
1635
+ m_tab = "\t";
1636
+ m_add_child = false;
1637
+ }
1638
+
1639
+ // Class Writer
1640
+ // //////////////////////////////////////////////////////////////////
1641
+ void jwriter::write(const jvalue& jval, string& strdoc)
1642
+ {
1643
+ strdoc = "";
1644
+ _write_value(jval, strdoc);
1645
+ }
1646
+
1647
+ void jwriter::_write_value(const jvalue& jval, string& strdoc)
1648
+ {
1649
+ switch (jval.type()) {
1650
+ case jvalue::E_NULL:
1651
+ strdoc += "null";
1652
+ break;
1653
+ case jvalue::E_INT:
1654
+ strdoc += v2s(jval.as_int64());
1655
+ break;
1656
+ case jvalue::E_BOOL:
1657
+ strdoc += jval.as_bool() ? "true" : "false";
1658
+ break;
1659
+ case jvalue::E_FLOAT:
1660
+ strdoc += v2s(jval.as_double());
1661
+ break;
1662
+ case jvalue::E_STRING:
1663
+ strdoc += v2s(jval.as_cstr());
1664
+ break;
1665
+ case jvalue::E_ARRAY:
1666
+ {
1667
+ strdoc += "[";
1668
+ size_t usize = jval.size();
1669
+ for (size_t i = 0; i < usize; i++) {
1670
+ strdoc += (i > 0) ? "," : "";
1671
+ _write_value(jval[i], strdoc);
1672
+ }
1673
+ strdoc += "]";
1674
+ }
1675
+ break;
1676
+ case jvalue::E_OBJECT:
1677
+ {
1678
+ strdoc += "{";
1679
+ vector<string> keys;
1680
+ jval.get_keys(keys);
1681
+ size_t num_key = keys.size();
1682
+ for (size_t i = 0; i < num_key; i++) {
1683
+ const string& key_name = keys[i];
1684
+ strdoc += (i > 0) ? "," : "";
1685
+ strdoc += v2s(key_name.c_str()) + ":";
1686
+ _write_value(jval[key_name.c_str()], strdoc);
1687
+ }
1688
+ strdoc += "}";
1689
+ }
1690
+ break;
1691
+ case jvalue::E_DATE:
1692
+ {
1693
+ strdoc += "\"date:";
1694
+ strdoc += d2s(jval.as_date());
1695
+ strdoc += "\"";
1696
+ }
1697
+ break;
1698
+ case jvalue::E_DATA:
1699
+ {
1700
+ strdoc += "\"data:";
1701
+ const string& data = jval.as_data();
1702
+ jbase64 b64;
1703
+ strdoc += b64.encode(data.data(), (int)data.size());
1704
+ strdoc += "\"";
1705
+ }
1706
+ break;
1707
+ }
1708
+ }
1709
+
1710
+ const string& jwriter::style_write(const jvalue& jval)
1711
+ {
1712
+ m_strdoc = "";
1713
+ m_indent = "";
1714
+ m_add_child = false;
1715
+ _style_write_value(jval);
1716
+ m_strdoc += "\n";
1717
+ return m_strdoc;
1718
+ }
1719
+
1720
+ void jwriter::_style_write_value(const jvalue& jval)
1721
+ {
1722
+ switch (jval.type()) {
1723
+ case jvalue::E_NULL:
1724
+ _push_value("null");
1725
+ break;
1726
+ case jvalue::E_INT:
1727
+ _push_value(v2s(jval.as_int64()));
1728
+ break;
1729
+ case jvalue::E_BOOL:
1730
+ _push_value(jval.as_bool() ? "true" : "false");
1731
+ break;
1732
+ case jvalue::E_FLOAT:
1733
+ _push_value(v2s(jval.as_double()));
1734
+ break;
1735
+ case jvalue::E_STRING:
1736
+ _push_value(v2s(jval.as_cstr()));
1737
+ break;
1738
+ case jvalue::E_ARRAY:
1739
+ _style_write_array_value(jval);
1740
+ break;
1741
+ case jvalue::E_OBJECT:
1742
+ {
1743
+ vector<string> keys;
1744
+ jval.get_keys(keys);
1745
+ if (!keys.empty()) {
1746
+ m_strdoc += "{";
1747
+ m_indent += m_tab;
1748
+ size_t num_key = keys.size();
1749
+ for (size_t i = 0; i < num_key; i++) {
1750
+ const string& key_name = keys[i];
1751
+ m_strdoc += (i > 0) ? "," : "";
1752
+ m_strdoc += '\n' + m_indent + v2s(key_name.c_str()) + ": ";
1753
+ _style_write_value(jval[key_name]);
1754
+ }
1755
+ m_indent.resize(m_indent.size() - 1);
1756
+ m_strdoc += '\n' + m_indent + "}";
1757
+ } else {
1758
+ _push_value("{}");
1759
+ }
1760
+ }
1761
+ break;
1762
+ case jvalue::E_DATE:
1763
+ {
1764
+ string strdoc;
1765
+ strdoc += "\"date:";
1766
+ strdoc += d2s(jval.as_date());
1767
+ strdoc += "\"";
1768
+ _push_value(strdoc);
1769
+ }
1770
+ break;
1771
+ case jvalue::E_DATA:
1772
+ {
1773
+ string strdoc;
1774
+ strdoc += "\"data:";
1775
+ const string& data = jval.as_data();
1776
+ jbase64 b64;
1777
+ strdoc += b64.encode(data.data(), (int)data.size());
1778
+ strdoc += "\"";
1779
+ _push_value(strdoc);
1780
+ }
1781
+ break;
1782
+ }
1783
+ }
1784
+
1785
+ void jwriter::_style_write_array_value(const jvalue& jval)
1786
+ {
1787
+ size_t usize = jval.size();
1788
+ if (usize > 0) {
1789
+ bool isArrayMultiLine = _is_multiline_array(jval);
1790
+ if (isArrayMultiLine) {
1791
+ m_strdoc += "[";
1792
+ m_indent += m_tab;
1793
+ bool hasChildValue = !m_child_values.empty();
1794
+ for (size_t i = 0; i < usize; i++) {
1795
+ m_strdoc += (i > 0) ? "," : "";
1796
+ if (hasChildValue) {
1797
+ m_strdoc += '\n' + m_indent + m_child_values[i];
1798
+ } else {
1799
+ m_strdoc += '\n' + m_indent;
1800
+ _style_write_value(jval[i]);
1801
+ }
1802
+ }
1803
+ m_indent.resize(m_indent.size() - 1);
1804
+ m_strdoc += '\n' + m_indent + "]";
1805
+ } else {
1806
+ m_strdoc += "[ ";
1807
+ for (size_t i = 0; i < usize; ++i) {
1808
+ m_strdoc += (i > 0) ? ", " : "";
1809
+ m_strdoc += m_child_values[i];
1810
+ }
1811
+ m_strdoc += " ]";
1812
+ }
1813
+ } else {
1814
+ _push_value("[]");
1815
+ }
1816
+ }
1817
+
1818
+ bool jwriter::_is_multiline_array(const jvalue& jval)
1819
+ {
1820
+ m_child_values.clear();
1821
+ size_t usize = jval.size();
1822
+ bool is_multiline = (usize >= 25);
1823
+ if (!is_multiline) {
1824
+ for (size_t i = 0; i < usize; i++) {
1825
+ if (jval[i].size() > 0) {
1826
+ is_multiline = true;
1827
+ break;
1828
+ }
1829
+ }
1830
+ }
1831
+ if (!is_multiline) {
1832
+ m_add_child = true;
1833
+ m_child_values.reserve(usize);
1834
+ size_t lineLength = 4 + (usize - 1) * 2; // '[ ' + ', '*n + ' ]'
1835
+ for (size_t i = 0; i < usize; i++) {
1836
+ _style_write_value(jval[i]);
1837
+ lineLength += m_child_values[i].length();
1838
+ }
1839
+ m_add_child = false;
1840
+ is_multiline = lineLength >= 75;
1841
+ }
1842
+ return is_multiline;
1843
+ }
1844
+
1845
+ void jwriter::_push_value(const string& strval)
1846
+ {
1847
+ if (!m_add_child) {
1848
+ m_strdoc += strval;
1849
+ } else {
1850
+ m_child_values.push_back(strval);
1851
+ }
1852
+ }
1853
+
1854
+ string jwriter::v2s(int64_t val)
1855
+ {
1856
+ char buf[32] = { 0 };
1857
+ snprintf(buf, 32, "%" PRId64, val);
1858
+ return buf;
1859
+ }
1860
+
1861
+ string jwriter::v2s(double val)
1862
+ {
1863
+ char buf[128] = { 0 };
1864
+ snprintf(buf, 128, "%g", val);
1865
+ return buf;
1866
+ }
1867
+
1868
+ string jwriter::d2s(time_t t)
1869
+ {
1870
+ t = (t > 0x7933F8EFF) ? (0x7933F8EFF - 1) : t;
1871
+
1872
+ tm ft = { 0 };
1873
+
1874
+ #ifdef _WIN32
1875
+ localtime_s(&ft, &t);
1876
+ #else
1877
+ localtime_r(&t, &ft);
1878
+ #endif
1879
+
1880
+ ft.tm_year = (ft.tm_year < 0) ? 0 : ft.tm_year;
1881
+ ft.tm_mon = (ft.tm_mon < 0) ? 0 : ft.tm_mon;
1882
+ ft.tm_mday = (ft.tm_mday < 0) ? 0 : ft.tm_mday;
1883
+ ft.tm_hour = (ft.tm_hour < 0) ? 0 : ft.tm_hour;
1884
+ ft.tm_min = (ft.tm_min < 0) ? 0 : ft.tm_min;
1885
+ ft.tm_sec = (ft.tm_sec < 0) ? 0 : ft.tm_sec;
1886
+
1887
+ char date[64] = { 0 };
1888
+ snprintf(date, 64, "%04d-%02d-%02dT%02d:%02d:%02dZ", ft.tm_year + 1900, ft.tm_mon + 1, ft.tm_mday, ft.tm_hour, ft.tm_min, ft.tm_sec);
1889
+ return date;
1890
+ }
1891
+
1892
+ string jwriter::v2s(const char* pstr)
1893
+ {
1894
+ if (NULL != strpbrk(pstr, "\"\\\b\f\n\r\t")) {
1895
+ string ret;
1896
+ ret.reserve(strlen(pstr) * 2 + 3);
1897
+ ret += "\"";
1898
+ for (const char* c = pstr; 0 != *c; c++) {
1899
+ switch (*c) {
1900
+ case '\\':
1901
+ {
1902
+ c++;
1903
+ bool is_unicode = false;
1904
+ if ('u' == *c) {
1905
+ bool bFlag = true;
1906
+ for (int i = 1; i <= 4; i++) {
1907
+ if (!isdigit(*(c + i))) {
1908
+ bFlag = false;
1909
+ break;
1910
+ }
1911
+ }
1912
+ is_unicode = bFlag;
1913
+ }
1914
+
1915
+ if (true == is_unicode) {
1916
+ ret += "\\u";
1917
+ } else {
1918
+ ret += "\\\\";
1919
+ c--;
1920
+ }
1921
+ }
1922
+ break;
1923
+ case '\"':
1924
+ ret += "\\\"";
1925
+ break;
1926
+ case '\b':
1927
+ ret += "\\b";
1928
+ break;
1929
+ case '\f':
1930
+ ret += "\\f";
1931
+ break;
1932
+ case '\n':
1933
+ ret += "\\n";
1934
+ break;
1935
+ case '\r':
1936
+ ret += "\\r";
1937
+ break;
1938
+ case '\t':
1939
+ ret += "\\t";
1940
+ break;
1941
+ default:
1942
+ ret += *c;
1943
+ break;
1944
+ }
1945
+ }
1946
+ ret += "\"";
1947
+ return ret;
1948
+ } else {
1949
+ return string("\"") + pstr + "\"";
1950
+ }
1951
+ }
1952
+
1953
+ void jwriter::write_to_html(const jvalue& jval, string& strdoc)
1954
+ {
1955
+ strdoc = "";
1956
+ _write_value_to_html(jval, strdoc);
1957
+ strdoc += "\n";
1958
+ }
1959
+
1960
+ void jwriter::_write_value_to_html(const jvalue& jval, string& strdoc)
1961
+ {
1962
+
1963
+ switch (jval.type()) {
1964
+ case jvalue::E_NULL:
1965
+ strdoc += "null";
1966
+ break;
1967
+ case jvalue::E_INT:
1968
+ strdoc += v2s(jval.as_int64());
1969
+ break;
1970
+ case jvalue::E_BOOL:
1971
+ strdoc += jval.as_bool() ? "true" : "false";
1972
+ break;
1973
+ case jvalue::E_FLOAT:
1974
+ strdoc += v2s(jval.as_double());
1975
+ break;
1976
+ case jvalue::E_STRING:
1977
+ strdoc += vstring2s(jval.as_cstr()); //don't escape here, escape before
1978
+ break;
1979
+ case jvalue::E_ARRAY:
1980
+ {
1981
+ strdoc += "[";
1982
+ size_t usize = jval.size();
1983
+ for (size_t i = 0; i < usize; i++) {
1984
+ strdoc += (i > 0) ? "," : "";
1985
+ _write_value_to_html(jval[i], strdoc);
1986
+ }
1987
+ strdoc += "]";
1988
+ }
1989
+ break;
1990
+ case jvalue::E_OBJECT:
1991
+ {
1992
+ strdoc += "{";
1993
+ vector<string> keys;
1994
+ jval.get_keys(keys);
1995
+ size_t num_key = keys.size();
1996
+ for (size_t i = 0; i < num_key; i++) {
1997
+ const string& key_name = keys[i];
1998
+ strdoc += (i > 0) ? "," : "";
1999
+ strdoc += vstring2s(key_name.c_str()) + ":";
2000
+ _write_value_to_html(jval[key_name.c_str()], strdoc);
2001
+ }
2002
+ strdoc += "}";
2003
+ }
2004
+ break;
2005
+ case jvalue::E_DATE:
2006
+ {
2007
+ strdoc += "\\\"date:";
2008
+ strdoc += d2s(jval.as_date());
2009
+ strdoc += "\\\"";
2010
+ }
2011
+ break;
2012
+ case jvalue::E_DATA:
2013
+ {
2014
+ strdoc += "\\\"data:";
2015
+ const string& data = jval.as_data();
2016
+ jbase64 b64;
2017
+ strdoc += b64.encode(data.data(), (int)data.size());
2018
+ strdoc += "\\\"";
2019
+ }
2020
+ break;
2021
+ }
2022
+ }
2023
+
2024
+ string jwriter::vstring2s(const char* pstr)
2025
+ {
2026
+ return string("\\\"") + pstr + "\\\"";
2027
+
2028
+ }
2029
+
2030
+ string jwriter::vstring2html(const char* pstr)
2031
+ {
2032
+
2033
+ if (NULL != strpbrk(pstr, "<>\"")) {
2034
+ string ret;
2035
+ ret.reserve(strlen(pstr) * 2 + 3);
2036
+ ret += "\\\"";
2037
+ for (const char* c = pstr; 0 != *c; c++) {
2038
+ switch (*c) {
2039
+ case '<':
2040
+ ret += "&lt;";
2041
+ break;
2042
+ case '>':
2043
+ ret += "&gt;";
2044
+ break;
2045
+ case '\"':
2046
+ ret += "&quot;";
2047
+ break;
2048
+ // case '&': ret += "&amp;"; break;
2049
+ default:
2050
+ ret += *c;
2051
+ break;
2052
+ }
2053
+ }
2054
+ ret += "\\\"";
2055
+ return ret;
2056
+ } else {
2057
+ return string("\\\"") + pstr + "\\\"";
2058
+ }
2059
+
2060
+ }
2061
+
2062
+ //////////////////////////////////////////////////////////////////////////
2063
+ jpreader::jpreader()
2064
+ {
2065
+ //xml
2066
+ m_pbegin = NULL;
2067
+ m_pend = NULL;
2068
+ m_pcursor = NULL;
2069
+ m_perror = NULL;
2070
+
2071
+ //binary
2072
+ m_ptrailer = NULL;
2073
+ m_num_objects = 0;
2074
+ m_offset_table_offset_size = 0;
2075
+ m_poffset_table = 0;
2076
+ m_object_ref_size = 0;
2077
+ m_top_object_offset = 0;
2078
+ }
2079
+
2080
+ bool jpreader::parse(const char* pdoc, size_t len, jvalue& root, bool* is_binary)
2081
+ {
2082
+ root.clear();
2083
+ if (NULL == pdoc) {
2084
+ return false;
2085
+ }
2086
+
2087
+ if (len < 30) {
2088
+ return false;
2089
+ }
2090
+
2091
+ if (0 == ::memcmp(pdoc, "bplist00", 8)) {
2092
+ if (NULL != is_binary) {
2093
+ *is_binary = true;
2094
+ }
2095
+ return parse_binary(pdoc, len, root);
2096
+ } else {
2097
+ if (NULL != is_binary) {
2098
+ *is_binary = false;
2099
+ }
2100
+ m_pbegin = pdoc;
2101
+ m_pend = m_pbegin + len;
2102
+ m_pcursor = m_pbegin;
2103
+ m_perror = m_pbegin;
2104
+ m_strerr = "null";
2105
+
2106
+ ptoken token;
2107
+ _read_token(token);
2108
+ return _read_value(root, token);
2109
+ }
2110
+ }
2111
+
2112
+ bool jpreader::_read_value(jvalue& pval, ptoken& token)
2113
+ {
2114
+ switch (token.type) {
2115
+ case ptoken::E_PTOKEN_TRUE:
2116
+ pval = true;
2117
+ break;
2118
+ case ptoken::E_PTOKEN_FALSE:
2119
+ pval = false;
2120
+ break;
2121
+ case ptoken::E_PTOKEN_NULL:
2122
+ pval = jvalue();
2123
+ break;
2124
+ case ptoken::E_PTOKEN_STRING_NULL:
2125
+ pval = jvalue(jvalue::E_STRING);
2126
+ break;
2127
+ case ptoken::E_PTOKEN_DICTIONARY_NULL:
2128
+ pval = jvalue(jvalue::E_OBJECT);
2129
+ break;
2130
+ case ptoken::E_PTOKEN_ARRAY_NULL:
2131
+ pval = jvalue(jvalue::E_ARRAY);
2132
+ break;
2133
+ case ptoken::E_PTOKEN_DATA_NULL:
2134
+ pval = jvalue(jvalue::E_DATA);
2135
+ break;
2136
+ case ptoken::E_PTOKEN_DATE_NULL:
2137
+ pval = jvalue(jvalue::E_DATE);
2138
+ break;
2139
+ case ptoken::E_PTOKEN_INTEGER_NULL:
2140
+ pval = jvalue(jvalue::E_INT);
2141
+ break;
2142
+ case ptoken::E_PTOKEN_REAL_NULL:
2143
+ pval = jvalue(jvalue::E_FLOAT);
2144
+ break;
2145
+ case ptoken::E_PTOKEN_NUMBER:
2146
+ return _decode_number(token, pval);
2147
+ break;
2148
+ case ptoken::E_PTOKEN_ARRAY_BEGIN:
2149
+ return _read_array(pval);
2150
+ break;
2151
+ case ptoken::E_PTOKEN_DICTIONARY_BEGIN:
2152
+ return _read_dictionary(pval);
2153
+ break;
2154
+ case ptoken::E_PTOKEN_DATE:
2155
+ {
2156
+ string strval;
2157
+ _decode_string(token, strval);
2158
+
2159
+ tm ft = { 0 };
2160
+ ::sscanf_s(strval.c_str(), "%04d-%02d-%02dT%02d:%02d:%02dZ", &ft.tm_year, &ft.tm_mon, &ft.tm_mday, &ft.tm_hour, &ft.tm_min, &ft.tm_sec);
2161
+ ft.tm_mon -= 1;
2162
+ ft.tm_year -= 1900;
2163
+ pval.assign_date(mktime(&ft));
2164
+ }
2165
+ break;
2166
+ case ptoken::E_PTOKEN_DATA:
2167
+ {
2168
+ string strval;
2169
+ _decode_string(token, strval);
2170
+ pval.assign_data(strval.c_str());
2171
+ }
2172
+ break;
2173
+ case ptoken::E_PTOKEN_STRING:
2174
+ {
2175
+ string strval;
2176
+ _decode_string(token, strval);
2177
+ pval = strval.c_str();
2178
+ }
2179
+ break;
2180
+ default:
2181
+ return _add_error("Syntax error: value, dictionary or array expected.", token.pbegin);
2182
+ break;
2183
+ }
2184
+ return true;
2185
+ }
2186
+
2187
+ bool jpreader::_read_label(string& label)
2188
+ {
2189
+ _skip_spaces();
2190
+
2191
+ char c = *m_pcursor++;
2192
+ if ('<' != c) {
2193
+ return false;
2194
+ }
2195
+
2196
+ label.clear();
2197
+ label.reserve(10);
2198
+ label += c;
2199
+
2200
+ bool bEnd = false;
2201
+ while (m_pcursor != m_pend) {
2202
+ c = *m_pcursor++;
2203
+ if ('>' == c) {
2204
+ if ('/' == *(m_pcursor - 1) || '?' == *(m_pcursor - 1)) {
2205
+ label += *(m_pcursor - 1);
2206
+ }
2207
+
2208
+ label += c;
2209
+ break;
2210
+ } else if (' ' == c) {
2211
+ bEnd = true;
2212
+ } else if (!bEnd) {
2213
+ label += c;
2214
+ }
2215
+ }
2216
+
2217
+ if ('>' != c) {
2218
+ label.clear();
2219
+ return false;
2220
+ }
2221
+
2222
+ return (!label.empty());
2223
+ }
2224
+
2225
+ void jpreader::_end_label(ptoken& token, const char* end_label)
2226
+ {
2227
+ string label;
2228
+ _read_label(label);
2229
+ if (end_label != label) {
2230
+ token.type = ptoken::E_PTOKEN_ERROR;
2231
+ }
2232
+ }
2233
+
2234
+ bool jpreader::_read_token(ptoken& token)
2235
+ {
2236
+ string label;
2237
+ if (!_read_label(label)) {
2238
+ token.type = ptoken::E_PTOKEN_ERROR;
2239
+ return false;
2240
+ }
2241
+
2242
+ if ('?' == label.at(1) || '!' == label.at(1)) {
2243
+ return _read_token(token);
2244
+ }
2245
+
2246
+ if ("<dict>" == label) {
2247
+ token.type = ptoken::E_PTOKEN_DICTIONARY_BEGIN;
2248
+ } else if ("</dict>" == label) {
2249
+ token.type = ptoken::E_PTOKEN_DICTIONARY_END;
2250
+ } else if ("<array>" == label) {
2251
+ token.type = ptoken::E_PTOKEN_ARRAY_BEGIN;
2252
+ } else if ("</array>" == label) {
2253
+ token.type = ptoken::E_PTOKEN_ARRAY_END;
2254
+ } else if ("<key>" == label) {
2255
+ token.pbegin = m_pcursor;
2256
+ token.type = _read_string() ? ptoken::E_PTOKEN_KEY : ptoken::E_PTOKEN_ERROR;
2257
+ token.pend = m_pcursor;
2258
+ _end_label(token, "</key>");
2259
+ } else if ("<string>" == label) {
2260
+ token.pbegin = m_pcursor;
2261
+ token.type = _read_string() ? ptoken::E_PTOKEN_STRING : ptoken::E_PTOKEN_ERROR;
2262
+ token.pend = m_pcursor;
2263
+ _end_label(token, "</string>");
2264
+ } else if ("<date>" == label) {
2265
+ token.pbegin = m_pcursor;
2266
+ token.type = _read_string() ? ptoken::E_PTOKEN_DATE : ptoken::E_PTOKEN_ERROR;
2267
+ token.pend = m_pcursor;
2268
+ _end_label(token, "</date>");
2269
+ } else if ("<data>" == label) {
2270
+ token.pbegin = m_pcursor;
2271
+ token.type = _read_string() ? ptoken::E_PTOKEN_DATA : ptoken::E_PTOKEN_ERROR;
2272
+ token.pend = m_pcursor;
2273
+ _end_label(token, "</data>");
2274
+ } else if ("<integer>" == label) {
2275
+ token.pbegin = m_pcursor;
2276
+ token.type = _read_number() ? ptoken::E_PTOKEN_NUMBER : ptoken::E_PTOKEN_ERROR;
2277
+ token.pend = m_pcursor;
2278
+ _end_label(token, "</integer>");
2279
+ } else if ("<real>" == label) {
2280
+ token.pbegin = m_pcursor;
2281
+ token.type = _read_number() ? ptoken::E_PTOKEN_NUMBER : ptoken::E_PTOKEN_ERROR;
2282
+ token.pend = m_pcursor;
2283
+ _end_label(token, "</real>");
2284
+ } else if ("<true/>" == label) {
2285
+ token.type = ptoken::E_PTOKEN_TRUE;
2286
+ } else if ("<false/>" == label) {
2287
+ token.type = ptoken::E_PTOKEN_FALSE;
2288
+ } else if ("<dict/>" == label) {
2289
+ token.type = ptoken::E_PTOKEN_DICTIONARY_NULL;
2290
+ } else if ("<array/>" == label) {
2291
+ token.type = ptoken::E_PTOKEN_ARRAY_NULL;
2292
+ } else if ("<data/>" == label) {
2293
+ token.type = ptoken::E_PTOKEN_DATA_NULL;
2294
+ } else if ("<date/>" == label) {
2295
+ token.type = ptoken::E_PTOKEN_DATE_NULL;
2296
+ } else if ("<integer/>" == label) {
2297
+ token.type = ptoken::E_PTOKEN_INTEGER_NULL;
2298
+ } else if ("<real/>" == label) {
2299
+ token.type = ptoken::E_PTOKEN_REAL_NULL;
2300
+ } else if ("<string/>" == label) {
2301
+ token.type = ptoken::E_PTOKEN_STRING_NULL;
2302
+ } else if ("<plist>" == label) {
2303
+ return _read_token(token);
2304
+ } else if ("</plist>" == label || "<plist/>" == label) {
2305
+ token.type = ptoken::E_PTOKEN_END;
2306
+ } else {
2307
+ token.type = ptoken::E_PTOKEN_ERROR;
2308
+ }
2309
+
2310
+ return true;
2311
+ }
2312
+
2313
+ void jpreader::_skip_spaces()
2314
+ {
2315
+ while (m_pcursor != m_pend) {
2316
+ char c = *m_pcursor;
2317
+ if (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
2318
+ m_pcursor++;
2319
+ } else {
2320
+ break;
2321
+ }
2322
+ }
2323
+ }
2324
+
2325
+ bool jpreader::_read_number()
2326
+ {
2327
+ while (m_pcursor != m_pend) {
2328
+ char c = *m_pcursor;
2329
+ if ((c >= '0' && c <= '9') || (c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-')) {
2330
+ ++m_pcursor;
2331
+ } else {
2332
+ break;
2333
+ }
2334
+ }
2335
+ return true;
2336
+ }
2337
+
2338
+ bool jpreader::_read_string()
2339
+ {
2340
+ while (m_pcursor != m_pend) {
2341
+ if ('<' == *m_pcursor) {
2342
+ break;
2343
+ }
2344
+ m_pcursor++;
2345
+ }
2346
+ return ('<' == *m_pcursor);
2347
+ }
2348
+
2349
+ bool jpreader::_read_dictionary(jvalue& pval)
2350
+ {
2351
+ ptoken key;
2352
+ string strkey;
2353
+ if (jvalue::E_OBJECT != pval.type()) {
2354
+ pval = jvalue(jvalue::E_OBJECT);
2355
+ }
2356
+ while (_read_token(key)) {
2357
+ if (ptoken::E_PTOKEN_DICTIONARY_END == key.type) {//empty
2358
+ return true;
2359
+ }
2360
+
2361
+ if (ptoken::E_PTOKEN_KEY != key.type) {
2362
+ break;
2363
+ }
2364
+
2365
+ strkey = "";
2366
+ if (!_decode_string(key, strkey)) {
2367
+ return false;
2368
+ }
2369
+
2370
+ ptoken val;
2371
+ _read_token(val);
2372
+ if (!_read_value(pval[strkey.c_str()], val)) {
2373
+ return false;
2374
+ }
2375
+ }
2376
+ return _add_error("missing '</dict>' or dictionary member name", key.pbegin);
2377
+ }
2378
+
2379
+ bool jpreader::_read_array(jvalue& pval)
2380
+ {
2381
+ pval = jvalue(jvalue::E_ARRAY);
2382
+
2383
+ size_t index = 0;
2384
+ while (true) {
2385
+ ptoken elem;
2386
+ _read_token(elem);
2387
+ if (ptoken::E_PTOKEN_ARRAY_END == elem.type) {
2388
+ return true;
2389
+ } else if (ptoken::E_PTOKEN_KEY == elem.type) { //dictionary, found in ipod nano 1
2390
+ string strkey = "";
2391
+ if (!_decode_string(elem, strkey)) {
2392
+ return false;
2393
+ }
2394
+ ptoken tval;
2395
+ _read_token(tval);
2396
+ if (!_read_value(pval[index++][strkey.c_str()], tval)) {
2397
+ return false;
2398
+ }
2399
+ } else {
2400
+ if (!_read_value(pval[index++], elem)) {
2401
+ return false;
2402
+ }
2403
+ }
2404
+ }
2405
+
2406
+ return true;
2407
+ }
2408
+
2409
+ bool jpreader::_decode_number(ptoken& token, jvalue& pval)
2410
+ {
2411
+ int64_t val = 0;
2412
+ bool is_negative = false;
2413
+ const char* pcursor = token.pbegin;
2414
+ if ('-' == *pcursor) {
2415
+ pcursor++;
2416
+ is_negative = true;
2417
+ }
2418
+ for (const char* p = pcursor; p != token.pend; p++) {
2419
+ char c = *p;
2420
+ if ('.' == c || 'e' == c || 'E' == c) {
2421
+ return _decode_double(token, pval);
2422
+ } else if (c < '0' || c > '9') {
2423
+ return _add_error("'" + string(token.pbegin, token.pend) + "' is not a number.", token.pbegin);
2424
+ } else {
2425
+ val = val * 10 + (c - '0');
2426
+ }
2427
+ }
2428
+ pval = is_negative ? -val : val;
2429
+ return true;
2430
+ }
2431
+
2432
+ bool jpreader::_decode_double(ptoken& token, jvalue& pval)
2433
+ {
2434
+ const size_t buf_len = 64;
2435
+ size_t len = size_t(token.pend - token.pbegin);
2436
+ if (len < buf_len) {
2437
+ char buf[buf_len] = { 0 };
2438
+ ::memcpy(buf, token.pbegin, len);
2439
+ buf[len] = 0;
2440
+ double val = 0;
2441
+ if (1 == sscanf_s(buf, "%lf", &val)) {
2442
+ pval = val;
2443
+ return true;
2444
+ }
2445
+ }
2446
+ return _add_error("'" + string(token.pbegin, token.pend) + "' is too large or not a number.", token.pbegin);
2447
+ }
2448
+
2449
+ bool jpreader::_decode_string(ptoken& token, string& strdec)
2450
+ {
2451
+ const char* pcursor = token.pbegin;
2452
+ const char* pend = token.pend;
2453
+ strdec.reserve(size_t(token.pend - token.pbegin) + 6);
2454
+ while (pcursor != pend) {
2455
+ char c = *pcursor++;
2456
+ if ('\n' != c && '\r' != c && '\t' != c) {
2457
+ strdec += c;
2458
+ }
2459
+ }
2460
+ return true;
2461
+ }
2462
+
2463
+ bool jpreader::_add_error(const string& message, const char* ploc)
2464
+ {
2465
+ m_perror = ploc;
2466
+ m_strerr = message;
2467
+ return false;
2468
+ }
2469
+
2470
+ void jpreader::error(string& strmsg) const
2471
+ {
2472
+ strmsg = "";
2473
+ int row = 1;
2474
+ const char* pcursor = m_pbegin;
2475
+ const char* plast = m_pbegin;
2476
+ while (pcursor < m_perror && pcursor <= m_pend) {
2477
+ char c = *pcursor++;
2478
+ if (c == '\r' || c == '\n') {
2479
+ if (c == '\r' && *pcursor == '\n') {
2480
+ pcursor++;
2481
+ }
2482
+ row++;
2483
+ plast = pcursor;
2484
+ }
2485
+ }
2486
+ char msg[64] = { 0 };
2487
+ ::snprintf(msg, 64, "error: line %d, column %d, ", row, int(m_perror - plast) + 1);
2488
+ strmsg += msg + m_strerr + "\n";
2489
+ }
2490
+
2491
+ //////////////////////////////////////////////////////////////////////////
2492
+ uint32_t jpreader::_get_uint24_from_be(const char* v)
2493
+ {
2494
+ uint32_t ret = 0;
2495
+ ::memcpy(&ret, v, 3);
2496
+ jpwriter::_byte_convert((uint8_t*)&ret, sizeof(ret));
2497
+ return ret;
2498
+ }
2499
+
2500
+ uint64_t jpreader::_get_uint_val(const char* v, size_t size)
2501
+ {
2502
+ if (8 == size)
2503
+ return jpwriter::_swap(*((uint64_t*)v));
2504
+ else if (4 == size)
2505
+ return jpwriter::_swap(*((uint32_t*)v));
2506
+ else if (3 == size)
2507
+ return _get_uint24_from_be(v);
2508
+ else if (2 == size)
2509
+ return jpwriter::_swap(*((uint16_t*)v));
2510
+ else
2511
+ return *((uint8_t*)v);
2512
+ }
2513
+
2514
+ bool jpreader::_read_uint_size(const char*& pcur, size_t& size)
2515
+ {
2516
+ jvalue temp;
2517
+ _read_binary_value(pcur, temp);
2518
+ if (temp.is_int()) {
2519
+ size = (size_t)temp.as_int64();
2520
+ return true;
2521
+ }
2522
+ assert(0);
2523
+ return false;
2524
+ }
2525
+
2526
+ bool jpreader::_read_unicode(const char* pcursor, size_t size, jvalue& pv)
2527
+ {
2528
+ if (0 == size) {
2529
+ pv = "";
2530
+ return false;
2531
+ }
2532
+
2533
+ uint16_t* unistr = (uint16_t*)::malloc(2 * size);
2534
+ if (NULL == unistr) {
2535
+ return false;
2536
+ }
2537
+
2538
+ ::memcpy(unistr, pcursor, 2 * size);
2539
+ for (size_t i = 0; i < size; i++) {
2540
+ jpwriter::_byte_convert((uint8_t*)(unistr + i), 2);
2541
+ }
2542
+
2543
+ char* outbuf = (char*)::malloc(3 * (size + 1));
2544
+ if (NULL == outbuf) {
2545
+ return false;
2546
+ }
2547
+
2548
+ size_t p = 0;
2549
+ size_t i = 0;
2550
+ uint16_t wc = 0;
2551
+ while (i < size) {
2552
+ wc = unistr[i++];
2553
+ if (wc >= 0x800) {
2554
+ outbuf[p++] = (char)(0xE0 + ((wc >> 12) & 0xF));
2555
+ outbuf[p++] = (char)(0x80 + ((wc >> 6) & 0x3F));
2556
+ outbuf[p++] = (char)(0x80 + (wc & 0x3F));
2557
+ } else if (wc >= 0x80) {
2558
+ outbuf[p++] = (char)(0xC0 + ((wc >> 6) & 0x1F));
2559
+ outbuf[p++] = (char)(0x80 + (wc & 0x3F));
2560
+ } else {
2561
+ outbuf[p++] = (char)(wc & 0x7F);
2562
+ }
2563
+ }
2564
+
2565
+ outbuf[p] = 0;
2566
+ pv = outbuf;
2567
+ ::free(outbuf);
2568
+ outbuf = NULL;
2569
+
2570
+ ::free(unistr);
2571
+ unistr = NULL;
2572
+ return true;
2573
+ }
2574
+
2575
+ bool jpreader::_read_binary_value(const char*& pcursor, jvalue& pv)
2576
+ {
2577
+ uint8_t c = *pcursor++;
2578
+ uint8_t type = c & 0xF0;
2579
+ uint8_t value = c & 0x0F;
2580
+
2581
+ switch (type) {
2582
+ case BPLIST_NULL:
2583
+ {
2584
+ switch (value) {
2585
+ case BPLIST_NULL:
2586
+ pv = jvalue(jvalue::E_NULL);
2587
+ break;
2588
+ case NS_NUMBER_FALSE:
2589
+ pv = false;
2590
+ break;
2591
+ case NS_NUMBER_TRUE:
2592
+ pv = true;
2593
+ break;
2594
+ case NS_URL_BASE_STRING:
2595
+ case NS_URL_STRING:
2596
+ case NS_UUID:
2597
+ pv = jvalue(jvalue::E_NULL);
2598
+ break;
2599
+ default:
2600
+ pv = jvalue(jvalue::E_NULL);
2601
+ break;
2602
+ }
2603
+ }
2604
+ break;
2605
+ case NS_NUMBER_INT:
2606
+ {
2607
+ uint8_t size = 1 << value;
2608
+ switch (size) {
2609
+ case sizeof(uint8_t) :
2610
+ case sizeof(uint16_t) :
2611
+ case sizeof(uint32_t) :
2612
+ case sizeof(uint64_t) :
2613
+ pv = (int64_t)_get_uint_val(pcursor, size);
2614
+ break;
2615
+ default:
2616
+ pv = 0;
2617
+ break;
2618
+ };
2619
+ pcursor += size;
2620
+ }
2621
+ break;
2622
+ case NS_NUMBER_REAL:
2623
+ {
2624
+ if (2 == value) {
2625
+ float real = 0;
2626
+ ::memcpy(&real, pcursor, sizeof(float));
2627
+ pv = (double)jpwriter::_swap(real);
2628
+ } else if (3 == value) {
2629
+ double real = 0;
2630
+ ::memcpy(&real, pcursor, sizeof(double));
2631
+ pv = jpwriter::_swap(real);
2632
+ } else {
2633
+ return false;
2634
+ }
2635
+ }
2636
+ break;
2637
+ case NS_DATE:
2638
+ {
2639
+ if (3 == value) {
2640
+ double date = 0;
2641
+ ::memcpy(&date, pcursor, sizeof(double));
2642
+ date = jpwriter::_swap(date);
2643
+ pv.assign_date(((time_t)date) + 978278400);
2644
+ }
2645
+ }
2646
+ break;
2647
+ case NS_DATA:
2648
+ {
2649
+ size_t size = value;
2650
+ if (0x0F == value) {
2651
+ if (!_read_uint_size(pcursor, size)) {
2652
+ return false;
2653
+ }
2654
+ }
2655
+ pv.assign_data((const uint8_t*)pcursor, size);
2656
+ }
2657
+ break;
2658
+ case NS_STRING_ASCII:
2659
+ case NS_STRING_UTF8:
2660
+ {
2661
+ size_t size = value;
2662
+ if (0x0F == value) {
2663
+ if (!_read_uint_size(pcursor, size)) {
2664
+ return false;
2665
+ }
2666
+ }
2667
+
2668
+ string strval;
2669
+ strval.append(pcursor, size);
2670
+ strval.append(1, 0);
2671
+ pv = strval.c_str();
2672
+ }
2673
+ break;
2674
+ case NS_STRING_UNICODE:
2675
+ {
2676
+ size_t size = value;
2677
+ if (0x0F == value) {
2678
+ if (!_read_uint_size(pcursor, size)) {
2679
+ return false;
2680
+ }
2681
+ }
2682
+
2683
+ _read_unicode(pcursor, size, pv);
2684
+ }
2685
+ break;
2686
+ case NS_ARRAY:
2687
+ case NS_SET:
2688
+ {
2689
+ size_t size = value;
2690
+ if (0x0F == value) {
2691
+ if (!_read_uint_size(pcursor, size)) {
2692
+ return false;
2693
+ }
2694
+ }
2695
+
2696
+ pv = jvalue(jvalue::E_ARRAY);
2697
+ for (size_t i = 0; i < size; i++) {
2698
+ uint64_t index = _get_uint_val((const char*)pcursor + i * m_object_ref_size, m_object_ref_size);
2699
+ if (index < m_num_objects) {
2700
+ const char* paddr = (m_pbegin + _get_uint_val(m_poffset_table + index * m_offset_table_offset_size, m_offset_table_offset_size));
2701
+ _read_binary_value(paddr, pv[i]);
2702
+ } else {
2703
+ assert(0);
2704
+ return false;
2705
+ }
2706
+ }
2707
+ }
2708
+ break;
2709
+ case NS_DICTIONARY:
2710
+ {
2711
+ size_t size = value;
2712
+ if (0x0F == value) {
2713
+ if (!_read_uint_size(pcursor, size)) {
2714
+ return false;
2715
+ }
2716
+ }
2717
+
2718
+ if (jvalue::E_OBJECT != pv.type()) {
2719
+ pv = jvalue(jvalue::E_OBJECT);
2720
+ }
2721
+
2722
+ for (size_t i = 0; i < size; i++) {
2723
+ jvalue jkey;
2724
+ jvalue jval;
2725
+
2726
+ uint64_t key_index = _get_uint_val((const char*)pcursor + i * m_object_ref_size, m_object_ref_size);
2727
+ uint64_t value_index = _get_uint_val((const char*)pcursor + (i + size) * m_object_ref_size, m_object_ref_size);
2728
+
2729
+ if (key_index < m_num_objects) {
2730
+ const char* paddr = (m_pbegin + _get_uint_val(m_poffset_table + key_index * m_offset_table_offset_size, m_offset_table_offset_size));
2731
+ _read_binary_value(paddr, jkey);
2732
+ }
2733
+
2734
+ if (value_index < m_num_objects) {
2735
+ const char* paddr = (m_pbegin + _get_uint_val(m_poffset_table + value_index * m_offset_table_offset_size, m_offset_table_offset_size));
2736
+ _read_binary_value(paddr, jval);
2737
+ }
2738
+
2739
+ if (jkey.is_string() && !jval.is_null()) {
2740
+ pv[jkey.as_cstr()] = jval;
2741
+ }
2742
+ }
2743
+ }
2744
+ break;
2745
+ case BPLIST_UID:
2746
+ {
2747
+ uint8_t size = value + 1;
2748
+ switch (size) {
2749
+ case sizeof(uint8_t) :
2750
+ case sizeof(uint16_t) :
2751
+ case sizeof(uint32_t) :
2752
+ case sizeof(uint64_t) :
2753
+ pv = (int64_t)_get_uint_val(pcursor, size);
2754
+ break;
2755
+ default:
2756
+ pv = 0;
2757
+ break;
2758
+ };
2759
+ pcursor += size;
2760
+ }
2761
+ break;
2762
+ case BPLIST_FILL:
2763
+ {
2764
+
2765
+ }
2766
+ break;
2767
+ default:
2768
+ {
2769
+ assert(0);
2770
+ return false;
2771
+ }
2772
+ break;
2773
+ }
2774
+
2775
+ return true;
2776
+ }
2777
+
2778
+ bool jpreader::parse_binary(const char* pbdoc, size_t len, jvalue& pv)
2779
+ {
2780
+ m_pbegin = pbdoc;
2781
+
2782
+ m_ptrailer = m_pbegin + len - 26;
2783
+
2784
+ m_offset_table_offset_size = m_ptrailer[0];
2785
+ m_object_ref_size = m_ptrailer[1];
2786
+ m_num_objects = _get_uint_val(m_ptrailer + 2, 8);
2787
+ m_top_object_offset = _get_uint_val(m_ptrailer + 10, 8);
2788
+
2789
+ if (0 == m_num_objects) {
2790
+ return false;
2791
+ }
2792
+
2793
+ m_poffset_table = m_pbegin + _get_uint_val(m_ptrailer + 18, 8);
2794
+ const char* pval = (m_pbegin + _get_uint_val(m_poffset_table + m_offset_table_offset_size * m_top_object_offset, m_offset_table_offset_size));
2795
+ return _read_binary_value(pval, pv);
2796
+ }
2797
+
2798
+ jpwriter::jpwriter()
2799
+ {
2800
+ m_tab = "\t";
2801
+ m_line = "\n";
2802
+ }
2803
+
2804
+ //////////////////////////////////////////////////////////////////////////
2805
+ void jpwriter::write(const jvalue& pval, string& strdoc)
2806
+ {
2807
+ m_tab = "";
2808
+ m_line = "";
2809
+ strdoc = _style_write(pval);
2810
+ }
2811
+
2812
+ uint8_t jpwriter::_get_integer_length(int64_t value)
2813
+ {
2814
+ if (value > 0 && value < (1 << 8)) {
2815
+ return 0;
2816
+ } else if (value > 0 && value < (1 << 16)) {
2817
+ return 1;
2818
+ } else if (value > 0 && value < ((int64_t)1 << 32)) {
2819
+ return 2;
2820
+ } else {
2821
+ return 3;
2822
+ }
2823
+ }
2824
+
2825
+ void jpwriter::_byte_convert(uint8_t* v, size_t size)
2826
+ {
2827
+ uint8_t tmp = 0;
2828
+ for (size_t i = 0, j = 0; i < (size / 2); i++) {
2829
+ tmp = v[i];
2830
+ j = (size - 1) - i;
2831
+ v[i] = v[j];
2832
+ v[j] = tmp;
2833
+ }
2834
+ }
2835
+
2836
+ uint16_t jpwriter::_swap(uint16_t value)
2837
+ {
2838
+ return ((((value) & 0xFF00) >> 8) | (((value) & 0x00FF) << 8));
2839
+ }
2840
+
2841
+ uint32_t jpwriter::_swap(uint32_t value)
2842
+ {
2843
+ return ((((value) & 0xFF000000) >> 24) |
2844
+ (((value) & 0x00FF0000) >> 8) |
2845
+ (((value) & 0x0000FF00) << 8) |
2846
+ (((value) & 0x000000FF) << 24));
2847
+ }
2848
+
2849
+ uint64_t jpwriter::_swap(uint64_t value)
2850
+ {
2851
+ return ((((value) & 0xFF00000000000000ull) >> 56) |
2852
+ (((value) & 0x00FF000000000000ull) >> 40) |
2853
+ (((value) & 0x0000FF0000000000ull) >> 24) |
2854
+ (((value) & 0x000000FF00000000ull) >> 8) |
2855
+ (((value) & 0x00000000FF000000ull) << 8) |
2856
+ (((value) & 0x0000000000FF0000ull) << 24) |
2857
+ (((value) & 0x000000000000FF00ull) << 40) |
2858
+ (((value) & 0x00000000000000FFull) << 56));
2859
+ }
2860
+
2861
+ float jpwriter::_swap(float value)
2862
+ {
2863
+ _byte_convert((uint8_t*)&value, sizeof(value));
2864
+ return value;
2865
+ }
2866
+
2867
+ double jpwriter::_swap(double value)
2868
+ {
2869
+ _byte_convert((uint8_t*)&value, sizeof(value));
2870
+ return value;
2871
+ }
2872
+
2873
+ uint8_t jpwriter::_get_integer_bytes(int64_t value)
2874
+ {
2875
+ if (value > 0 && value < (1 << 8)) {
2876
+ return 1;
2877
+ } else if (value > 0 && value < (1 << 16)) {
2878
+ return 2;
2879
+ } else if (value > 0 && value < ((int64_t)1 << 32)) {
2880
+ return 4;
2881
+ } else {
2882
+ return 8;
2883
+ }
2884
+ }
2885
+
2886
+ int jpwriter::_get_serialize_integer(uint8_t* data, uint8_t length, int64_t value)
2887
+ {
2888
+ switch (length) {
2889
+ case 1:
2890
+ data[0] = (uint8_t)value;
2891
+ break;
2892
+ case 2:
2893
+ data[0] = (uint8_t)(value >> 8);
2894
+ data[1] = (uint8_t)value;
2895
+ break;
2896
+ case 4:
2897
+ data[0] = (uint8_t)(value >> 24);
2898
+ data[1] = (uint8_t)(value >> 16);
2899
+ data[2] = (uint8_t)(value >> 8);
2900
+ data[3] = (uint8_t)value;
2901
+ break;
2902
+ case 8:
2903
+ data[0] = (uint8_t)(value >> 56);
2904
+ data[1] = (uint8_t)(value >> 48);
2905
+ data[2] = (uint8_t)(value >> 40);
2906
+ data[3] = (uint8_t)(value >> 32);
2907
+ data[4] = (uint8_t)(value >> 24);
2908
+ data[5] = (uint8_t)(value >> 16);
2909
+ data[6] = (uint8_t)(value >> 8);
2910
+ data[7] = (uint8_t)value;
2911
+ break;
2912
+ default:
2913
+ return -1;
2914
+ }
2915
+ return length;
2916
+ }
2917
+
2918
+ void jpwriter::write_to_binary(const jvalue& pval, string& strdoc)
2919
+ {
2920
+ strdoc.clear();
2921
+
2922
+ vector<bplist_object> array_objects;
2923
+ vector<uint64_t> array_offset_indexes;
2924
+ _write_value_to_binary(pval, array_objects, array_offset_indexes);
2925
+
2926
+ //check object ref size
2927
+ uint8_t object_ref_size = 1;
2928
+ uint64_t offset_table_size = array_offset_indexes.size();
2929
+ if (offset_table_size < (1 << 8)) {
2930
+ object_ref_size = 1;
2931
+ } else if (offset_table_size < (1 << 16)) {
2932
+ object_ref_size = 2;
2933
+ } else if (offset_table_size < ((int64_t)1 << 32)) {
2934
+ object_ref_size = 4;
2935
+ } else {
2936
+ object_ref_size = 8;
2937
+ }
2938
+
2939
+ //rebuild dictionary and array object data ad build address
2940
+ uint64_t start_address = 0x08;
2941
+ vector<uint64_t> array_offset_addresses;
2942
+ for (size_t i = 0; i < array_objects.size(); i++) {
2943
+
2944
+ //rebuild dictionary and array object data
2945
+ bplist_object& object = array_objects[i];
2946
+ if (jpreader::NS_DICTIONARY == object.type || jpreader::NS_ARRAY == object.type) {
2947
+
2948
+ object.data.clear();
2949
+ if (jpreader::NS_ARRAY == object.type) {
2950
+ _serialize_object_size(object.data, jpreader::NS_ARRAY, object.indexes.size());
2951
+ } else if (jpreader::NS_DICTIONARY == object.type) {
2952
+ _serialize_object_size(object.data, jpreader::NS_DICTIONARY, (object.indexes.size() / 2));
2953
+ }
2954
+ for (size_t j = 0; j < object.indexes.size(); j++) {
2955
+ if (1 == object_ref_size) {
2956
+ uint8_t index = (uint8_t)object.indexes[j];
2957
+ object.data.append((const char*)&index, sizeof(index));
2958
+ } else if (2 == object_ref_size) {
2959
+ uint16_t index = _swap((uint16_t)object.indexes[j]);
2960
+ object.data.append((const char*)&index, sizeof(index));
2961
+ } else if (4 == object_ref_size) {
2962
+ uint32_t index = _swap((uint32_t)object.indexes[j]);
2963
+ object.data.append((const char*)&index, sizeof(index));
2964
+ } else {
2965
+ uint64_t index = _swap((uint64_t)object.indexes[j]);
2966
+ object.data.append((const char*)&index, sizeof(index));
2967
+ }
2968
+ }
2969
+
2970
+ }
2971
+
2972
+ //build offset table address
2973
+ array_offset_addresses.push_back(start_address);
2974
+ start_address += object.data.size();
2975
+ }
2976
+
2977
+ //header
2978
+ strdoc.append("bplist00", 8);
2979
+
2980
+ //objects
2981
+ for (size_t i = 0; i < array_objects.size(); i++) {
2982
+ strdoc.append(array_objects[i].data);
2983
+ }
2984
+
2985
+ uint64_t offset_table_start = strdoc.size();
2986
+
2987
+ //offset table
2988
+ uint8_t offset_table_offset_size = 1;
2989
+ if (start_address < (1 << 8)) {
2990
+ offset_table_offset_size = 1;
2991
+
2992
+ uint8_t root = (uint8_t)array_offset_addresses[(size_t)array_offset_indexes.back()];
2993
+ strdoc.append((const char*)&root, sizeof(root));
2994
+
2995
+ for (size_t i = 0; i < array_offset_indexes.size() - 1; i++) {
2996
+ uint8_t index = (uint8_t)array_offset_addresses[(size_t)array_offset_indexes[i]];
2997
+ strdoc.append((const char*)&index, sizeof(index));
2998
+ }
2999
+
3000
+ } else if (start_address < (1 << 16)) {
3001
+ offset_table_offset_size = 2;
3002
+
3003
+ uint16_t root = _swap((uint16_t)array_offset_addresses[(size_t)array_offset_indexes.back()]);
3004
+ strdoc.append((const char*)&root, sizeof(root));
3005
+
3006
+ for (size_t i = 0; i < array_offset_indexes.size() - 1; i++) {
3007
+ uint16_t index = _swap((uint16_t)array_offset_addresses[(size_t)array_offset_indexes[i]]);
3008
+ strdoc.append((const char*)&index, sizeof(index));
3009
+ }
3010
+
3011
+ } else if (start_address < ((int64_t)1 << 32)) {
3012
+ offset_table_offset_size = 4;
3013
+
3014
+ uint32_t root = _swap((uint32_t)array_offset_addresses[(size_t)array_offset_indexes.back()]);
3015
+ strdoc.append((const char*)&root, sizeof(root));
3016
+
3017
+ for (size_t i = 0; i < array_offset_indexes.size() - 1; i++) {
3018
+ uint32_t index = _swap((uint32_t)array_offset_addresses[(size_t)array_offset_indexes[i]]);
3019
+ strdoc.append((const char*)&index, sizeof(index));
3020
+ }
3021
+ } else {
3022
+ offset_table_offset_size = 8;
3023
+
3024
+ uint64_t root = _swap((uint64_t)array_offset_addresses[(size_t)array_offset_indexes.back()]);
3025
+ strdoc.append((const char*)&root, sizeof(root));
3026
+
3027
+ for (size_t i = 0; i < array_offset_indexes.size() - 1; i++) {
3028
+ uint64_t index = _swap((uint64_t)array_offset_addresses[(size_t)array_offset_indexes[i]]);
3029
+ strdoc.append((const char*)&index, sizeof(index));
3030
+ }
3031
+ }
3032
+
3033
+ //tailer
3034
+ strdoc.append(6, '\0');
3035
+
3036
+ uint8_t val[2] = { 0 };
3037
+ val[0] = offset_table_offset_size;
3038
+ val[1] = object_ref_size;
3039
+
3040
+ strdoc.append((const char*)val, 2);
3041
+
3042
+ uint64_t num_objects = array_objects.size();
3043
+ num_objects = _swap(num_objects);
3044
+ strdoc.append((const char*)&num_objects, sizeof(uint64_t));
3045
+
3046
+ uint64_t top_object_offset = 0;
3047
+ top_object_offset = _swap(top_object_offset);
3048
+ strdoc.append((const char*)&top_object_offset, sizeof(uint64_t));
3049
+
3050
+ offset_table_start = _swap(offset_table_start);
3051
+ strdoc.append((const char*)&offset_table_start, sizeof(uint64_t));
3052
+ }
3053
+
3054
+ void jpwriter::_serialize_object_size(string& data, jpreader::bplist_object_type object_type, int64_t object_size)
3055
+ {
3056
+ if (jpreader::NS_NUMBER_INT != object_type) {
3057
+ if (object_size < 15) {
3058
+ uint8_t type = (uint8_t)(object_type | object_size);
3059
+ data.append((const char*)&type, sizeof(type));
3060
+ return;
3061
+ } else {
3062
+ uint8_t type = object_type | 0x0F;
3063
+ data.append((const char*)&type, sizeof(type));
3064
+ }
3065
+ }
3066
+
3067
+ uint8_t value[9] = { 0 };
3068
+ value[0] = jpreader::NS_NUMBER_INT | _get_integer_length(object_size);
3069
+
3070
+ uint8_t length = _get_integer_bytes(object_size);
3071
+ _get_serialize_integer(value + 1, length, object_size);
3072
+ data.append((const char*)value, length + 1);
3073
+ }
3074
+
3075
+ bool jpwriter::_contains_unicode_char(const char* str, size_t len)
3076
+ {
3077
+ for (size_t i = 0; i < len; i++) {
3078
+ uint8_t c = (uint8_t)str[i];
3079
+ if (c & 0x80) {
3080
+ return true;
3081
+ }
3082
+ }
3083
+ return false;
3084
+ }
3085
+
3086
+ bool jpwriter::_utf8_to_utf16(const char* utf8, size_t len, string& utf16)
3087
+ {
3088
+ size_t i = 0;
3089
+ while (i < len) {
3090
+ uint32_t codepoint = 0;
3091
+ size_t extra_bytes = 0;
3092
+ uint8_t first = (uint8_t)utf8[i];
3093
+ if (first <= 0x7F) {
3094
+ codepoint = first;
3095
+ extra_bytes = 0;
3096
+ } else if ((first & 0xE0) == 0xC0) {
3097
+ codepoint = first & 0x1F;
3098
+ extra_bytes = 1;
3099
+ } else if ((first & 0xF0) == 0xE0) {
3100
+ codepoint = first & 0x0F;
3101
+ extra_bytes = 2;
3102
+ } else if ((first & 0xF8) == 0xF0) {
3103
+ codepoint = first & 0x07;
3104
+ extra_bytes = 3;
3105
+ } else {
3106
+ return false;
3107
+ }
3108
+
3109
+ if (i + extra_bytes >= len) {
3110
+ return false;
3111
+ }
3112
+
3113
+ for (size_t j = 1; j <= extra_bytes; ++j) {
3114
+ codepoint = (codepoint << 6) | (((uint8_t)utf8[i + j]) & 0x3F);
3115
+ }
3116
+
3117
+ uint16_t uc = 0;
3118
+ if (codepoint <= 0xFFFF) {
3119
+ uc = _swap(static_cast<uint16_t>(codepoint));
3120
+ utf16.append((const char*)&uc, sizeof(uc));
3121
+ } else {
3122
+ codepoint -= 0x10000;
3123
+ uc = _swap(static_cast<uint16_t>(0xD800 + (codepoint >> 10)));
3124
+ utf16.append((const char*)&uc, sizeof(uc));
3125
+ uc = _swap(static_cast<uint16_t>(0xDC00 + (codepoint & 0x3FF)));
3126
+ utf16.append((const char*)&uc, sizeof(uc));
3127
+ }
3128
+
3129
+ i += extra_bytes + 1;
3130
+ }
3131
+
3132
+ return true;
3133
+ }
3134
+
3135
+ int64_t jpwriter::_write_value_to_binary(const jvalue& pval, vector<bplist_object>& array_objects, vector<uint64_t>& array_offset_indexes)
3136
+ {
3137
+ bplist_object object;
3138
+ if (pval.is_object()) {
3139
+ object.type = jpreader::NS_DICTIONARY;
3140
+ vector<string> keys;
3141
+ pval.get_keys(keys);
3142
+ size_t obj_size = keys.size();
3143
+ _serialize_object_size(object.data, jpreader::NS_DICTIONARY, obj_size);
3144
+
3145
+ vector<int64_t> key_indexes;
3146
+ vector<int64_t> val_indexes;
3147
+ for (size_t i = 0; i < obj_size; i++) {
3148
+ int64_t key_index = _write_value_to_binary(keys[i].c_str(), array_objects, array_offset_indexes);
3149
+ int64_t val_index = _write_value_to_binary(pval[keys[i].c_str()], array_objects, array_offset_indexes);
3150
+ key_indexes.push_back(key_index);
3151
+ val_indexes.push_back(val_index);
3152
+ }
3153
+
3154
+ for (size_t i = 0; i < key_indexes.size(); i++) {
3155
+ int64_t& index = key_indexes[i];
3156
+ object.indexes.push_back(index);
3157
+ object.data.append((const char*)&index, sizeof(index));
3158
+ }
3159
+ for (size_t i = 0; i < val_indexes.size(); i++) {
3160
+ int64_t& index = val_indexes[i];
3161
+ object.indexes.push_back(index);
3162
+ object.data.append((const char*)&index, sizeof(index));
3163
+ }
3164
+
3165
+ } else if (pval.is_array()) {
3166
+ object.type = jpreader::NS_ARRAY;
3167
+ size_t obj_size = pval.size();
3168
+ _serialize_object_size(object.data, jpreader::NS_ARRAY, obj_size);
3169
+ for (size_t i = 0; i < obj_size; i++) {
3170
+ int64_t index = _write_value_to_binary(pval[i], array_objects, array_offset_indexes);
3171
+ object.indexes.push_back(index);
3172
+ object.data.append((const char*)&index, sizeof(index));
3173
+ }
3174
+ } else if (pval.is_date()) {
3175
+ object.type = jpreader::NS_DATE;
3176
+ double dval = _swap((double)(pval.as_date() - 978278400));
3177
+ uint8_t type = jpreader::NS_DATE | 3;
3178
+ object.data.append((const char*)&type, 1);
3179
+ object.data.append((const char*)&dval, sizeof(double));
3180
+ } else if (pval.is_data()) {
3181
+ object.type = jpreader::NS_DATA;
3182
+ string strData = pval.as_data();
3183
+ size_t obj_size = strData.size();
3184
+ _serialize_object_size(object.data, jpreader::NS_DATA, obj_size);
3185
+ object.data.append(strData.data(), obj_size);
3186
+ } else if (pval.is_string()) { //must behind date and data
3187
+ const char* szVal = pval.as_cstr();
3188
+ size_t obj_size = strlen(szVal);
3189
+ bool unicode = false;
3190
+ if (_contains_unicode_char(szVal, obj_size)) {
3191
+ string utf16;
3192
+ if (_utf8_to_utf16(szVal, obj_size, utf16)) {
3193
+ unicode = true;
3194
+ object.type = jpreader::NS_STRING_UNICODE;
3195
+ obj_size = utf16.size() / 2;
3196
+ _serialize_object_size(object.data, jpreader::NS_STRING_UNICODE, obj_size);
3197
+ object.data.append(utf16);
3198
+ }
3199
+ }
3200
+ if (!unicode) {
3201
+ object.type = jpreader::NS_STRING_ASCII;
3202
+ _serialize_object_size(object.data, jpreader::NS_STRING_ASCII, obj_size);
3203
+ object.data.append((const char*)szVal, obj_size);
3204
+ }
3205
+ } else if (pval.is_bool()) {
3206
+ object.type = jpreader::BPLIST_NULL;
3207
+ uint8_t type = jpreader::BPLIST_NULL | (pval.as_bool() ? jpreader::NS_NUMBER_TRUE : jpreader::NS_NUMBER_FALSE);
3208
+ object.data.append((const char*)&type, 1);
3209
+ } else if (pval.is_int()) {
3210
+ object.type = jpreader::NS_NUMBER_INT;
3211
+ _serialize_object_size(object.data, jpreader::NS_NUMBER_INT, pval.as_int64());
3212
+ } else if (pval.is_double()) {
3213
+ object.type = jpreader::NS_NUMBER_REAL;
3214
+ double dval = _swap(pval.as_double());
3215
+ uint8_t type = jpreader::NS_NUMBER_REAL | 3;
3216
+ object.data.append((const char*)&type, 1);
3217
+ object.data.append((const char*)&dval, sizeof(double));
3218
+ } else if (pval.is_null()) {
3219
+ object.type = jpreader::BPLIST_NULL;
3220
+ object.data.append(1, '\0');
3221
+ } else {
3222
+ assert(0);
3223
+ object.type = jpreader::BPLIST_NULL;
3224
+ object.data.append(1, '\0');
3225
+ }
3226
+
3227
+ int64_t offset_index = -1;
3228
+ size_t object_size = object.data.size();
3229
+ for (size_t i = 0; i < array_objects.size(); i++) {
3230
+ if (array_objects[i].type == object.type) {
3231
+ if (array_objects[i].data.size() == object_size) {
3232
+ if (0 == ::memcmp(array_objects[i].data.data(), object.data.data(), object_size)) {
3233
+ offset_index = i;
3234
+ }
3235
+ }
3236
+ }
3237
+ }
3238
+
3239
+ if (offset_index < 0) {
3240
+ array_objects.push_back(object);
3241
+ offset_index = array_objects.size() - 1;
3242
+ array_offset_indexes.push_back(offset_index);
3243
+ }
3244
+
3245
+ return offset_index + 1;
3246
+ }
3247
+
3248
+ const string& jpwriter::style_write(const jvalue& pval)
3249
+ {
3250
+ m_tab = "\t";
3251
+ m_line = "\n";
3252
+ return _style_write(pval);
3253
+ }
3254
+
3255
+ const string& jpwriter::_style_write(const jvalue& pval)
3256
+ {
3257
+ m_indent = "";
3258
+ m_strdoc = "";
3259
+ m_strdoc += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + m_line;
3260
+ m_strdoc += "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" + m_line;
3261
+ m_strdoc += "<plist version=\"1.0\">" + m_line;
3262
+ _style_write_value(pval);
3263
+ m_strdoc += "</plist>" + m_line;
3264
+ return m_strdoc;
3265
+ }
3266
+
3267
+ void jpwriter::_style_write_value(const jvalue& pval)
3268
+ {
3269
+ if (pval.is_object()) {
3270
+ vector<string> keys;
3271
+ pval.get_keys(keys);
3272
+ if (!keys.empty()) {
3273
+ m_strdoc += m_indent + "<dict>" + m_line;
3274
+ m_indent += m_tab;
3275
+ for (size_t i = 0; i < keys.size(); i++) {
3276
+ string strkey = keys[i];
3277
+ _xml_escape(strkey);
3278
+ m_strdoc += m_indent + "<key>";
3279
+ m_strdoc += strkey;
3280
+ m_strdoc += "</key>" + m_line;
3281
+ _style_write_value(pval[keys[i].c_str()]);
3282
+ }
3283
+ if (!m_indent.empty()) {
3284
+ m_indent.resize(m_indent.size() - 1);
3285
+ }
3286
+ m_strdoc += m_indent + "</dict>" + m_line;
3287
+ } else {
3288
+ m_strdoc += m_indent + "<dict/>" + m_line;
3289
+ }
3290
+ } else if (pval.is_array()) {
3291
+ if (pval.size() > 0) {
3292
+ m_strdoc += m_indent + "<array>" + m_line;
3293
+ m_indent += m_tab;
3294
+ for (size_t i = 0; i < pval.size(); i++) {
3295
+ _style_write_value(pval[i]);
3296
+ }
3297
+ if (!m_indent.empty()) {
3298
+ m_indent.resize(m_indent.size() - 1);
3299
+ }
3300
+ m_strdoc += m_indent + "</array>" + m_line;
3301
+ } else {
3302
+ m_strdoc += m_indent + "<array/>" + m_line;
3303
+ }
3304
+ } else if (pval.is_date()) {
3305
+ m_strdoc += m_indent + "<date>";
3306
+ m_strdoc += jwriter::d2s(pval.as_date());
3307
+ m_strdoc += "</date>" + m_line;
3308
+ } else if (pval.is_data()) {
3309
+ m_strdoc += m_indent + "<data>" + m_line;
3310
+ m_strdoc += m_indent;
3311
+ jbase64 b64;
3312
+ string strdata = pval.as_data();
3313
+ m_strdoc += b64.encode(strdata.data(), (int32_t)strdata.size());
3314
+ m_strdoc += m_line;
3315
+ m_strdoc += m_indent + "</data>" + m_line;
3316
+ } else if (pval.is_string()) {
3317
+ if (pval.is_date_string()) {
3318
+ m_strdoc += m_indent + "<date>";
3319
+ m_strdoc += pval.as_string().c_str() + 5;
3320
+ m_strdoc += "</date>" + m_line;
3321
+ } else if (pval.is_data_string()) {
3322
+ m_strdoc += m_indent + "<data>" + m_line;
3323
+ m_strdoc += m_indent;
3324
+ m_strdoc += pval.as_string().c_str() + 5;
3325
+ m_strdoc += m_line;
3326
+ m_strdoc += m_indent + "</data>" + m_line;
3327
+ } else {
3328
+ string strval = pval.as_cstr();
3329
+ _xml_escape(strval);
3330
+ m_strdoc += m_indent + "<string>";
3331
+ m_strdoc += strval;
3332
+ m_strdoc += "</string>" + m_line;
3333
+ }
3334
+ } else if (pval.is_bool()) {
3335
+ m_strdoc += m_indent + (pval.as_bool() ? "<true/>" : "<false/>") + m_line;
3336
+ } else if (pval.is_int()) {
3337
+ m_strdoc += m_indent + "<integer>";
3338
+ char temp[32];
3339
+ snprintf(temp, 32, "%" PRId64, pval.as_int64());
3340
+ m_strdoc += temp;
3341
+ m_strdoc += "</integer>" + m_line;
3342
+ } else if (pval.is_double()) {
3343
+ m_strdoc += m_indent + "<real>";
3344
+ double v = pval.as_double();
3345
+ if (numeric_limits<double>::infinity() == v) {
3346
+ m_strdoc += "+infinity";
3347
+ } else {
3348
+ char temp[32];
3349
+ if (floor(v) == v) {
3350
+ snprintf(temp, sizeof(temp), "%" PRId64, (int64_t)v);
3351
+ } else {
3352
+ snprintf(temp, sizeof(temp), "%.15lf", v);
3353
+ }
3354
+ m_strdoc += temp;
3355
+ }
3356
+ m_strdoc += "</real>" + m_line;
3357
+ } else {
3358
+ m_strdoc += m_indent + "<integer>0</integer>" + m_line;
3359
+ }
3360
+ }
3361
+
3362
+ void jpwriter::_xml_escape(string& str)
3363
+ {
3364
+ _string_replace(str, "&", "&amp;");
3365
+ _string_replace(str, "<", "&lt;");
3366
+ //_string_replace(str, ">", "&gt;"); //optional
3367
+ //_string_replace(str, "'", "&apos;"); //optional
3368
+ //_string_replace(str, "\"", "&quot;"); //optional
3369
+ }
3370
+
3371
+ string& jpwriter::_string_replace(string& context, const string& from, const string& to)
3372
+ {
3373
+ size_t query = 0;
3374
+ size_t found = 0;
3375
+ while ((found = context.find(from, query)) != string::npos) {
3376
+ context.replace(found, from.size(), to);
3377
+ query = found + to.size();
3378
+ }
3379
+ return context;
3380
+ }