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.
- package/README.md +32 -0
- package/binding.gyp +87 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +1 -0
- package/package.json +33 -0
- package/src/native/addon.cc +231 -0
- package/src/native/zsign_driver.cc +87 -0
- package/src/native/zsign_driver.h +38 -0
- package/vendor/zlib/.cmake-format.yaml +245 -0
- package/vendor/zlib/.github/workflows/c-std.yml +230 -0
- package/vendor/zlib/.github/workflows/cmake.yml +112 -0
- package/vendor/zlib/.github/workflows/configure.yml +136 -0
- package/vendor/zlib/.github/workflows/fuzz.yml +25 -0
- package/vendor/zlib/.github/workflows/msys-cygwin.yml +77 -0
- package/vendor/zlib/BUILD.bazel +134 -0
- package/vendor/zlib/CMakeLists.txt +330 -0
- package/vendor/zlib/ChangeLog +1621 -0
- package/vendor/zlib/FAQ +367 -0
- package/vendor/zlib/INDEX +68 -0
- package/vendor/zlib/LICENSE +22 -0
- package/vendor/zlib/MODULE.bazel +9 -0
- package/vendor/zlib/Makefile.in +419 -0
- package/vendor/zlib/README +115 -0
- package/vendor/zlib/README-cmake.md +83 -0
- package/vendor/zlib/adler32.c +164 -0
- package/vendor/zlib/amiga/Makefile.pup +69 -0
- package/vendor/zlib/amiga/Makefile.sas +68 -0
- package/vendor/zlib/compress.c +75 -0
- package/vendor/zlib/configure +966 -0
- package/vendor/zlib/contrib/README.contrib +57 -0
- package/vendor/zlib/contrib/ada/buffer_demo.adb +106 -0
- package/vendor/zlib/contrib/ada/mtest.adb +156 -0
- package/vendor/zlib/contrib/ada/read.adb +156 -0
- package/vendor/zlib/contrib/ada/readme.txt +65 -0
- package/vendor/zlib/contrib/ada/test.adb +463 -0
- package/vendor/zlib/contrib/ada/zlib-streams.adb +225 -0
- package/vendor/zlib/contrib/ada/zlib-streams.ads +114 -0
- package/vendor/zlib/contrib/ada/zlib-thin.adb +142 -0
- package/vendor/zlib/contrib/ada/zlib-thin.ads +450 -0
- package/vendor/zlib/contrib/ada/zlib.adb +701 -0
- package/vendor/zlib/contrib/ada/zlib.ads +328 -0
- package/vendor/zlib/contrib/ada/zlib.gpr +20 -0
- package/vendor/zlib/contrib/blast/Makefile +8 -0
- package/vendor/zlib/contrib/blast/README +4 -0
- package/vendor/zlib/contrib/blast/blast.c +466 -0
- package/vendor/zlib/contrib/blast/blast.h +83 -0
- package/vendor/zlib/contrib/blast/test.pk +0 -0
- package/vendor/zlib/contrib/blast/test.txt +1 -0
- package/vendor/zlib/contrib/delphi/ZLib.pas +557 -0
- package/vendor/zlib/contrib/delphi/ZLibConst.pas +11 -0
- package/vendor/zlib/contrib/delphi/readme.txt +76 -0
- package/vendor/zlib/contrib/delphi/zlibd32.mak +99 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs +58 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs +202 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs +83 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib/CodecBase.cs +198 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib/Deflater.cs +106 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib/DotZLib.cs +288 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj +141 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib/GZipStream.cs +301 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib/Inflater.cs +105 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib/UnitTests.cs +274 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib.build +33 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib.chm +0 -0
- package/vendor/zlib/contrib/dotzlib/DotZLib.sln +21 -0
- package/vendor/zlib/contrib/dotzlib/LICENSE_1_0.txt +23 -0
- package/vendor/zlib/contrib/dotzlib/readme.txt +58 -0
- package/vendor/zlib/contrib/gcc_gvmat64/gvmat64.S +574 -0
- package/vendor/zlib/contrib/infback9/README +1 -0
- package/vendor/zlib/contrib/infback9/infback9.c +603 -0
- package/vendor/zlib/contrib/infback9/infback9.h +37 -0
- package/vendor/zlib/contrib/infback9/inffix9.h +107 -0
- package/vendor/zlib/contrib/infback9/inflate9.h +47 -0
- package/vendor/zlib/contrib/infback9/inftree9.c +319 -0
- package/vendor/zlib/contrib/infback9/inftree9.h +61 -0
- package/vendor/zlib/contrib/iostream/test.cpp +24 -0
- package/vendor/zlib/contrib/iostream/zfstream.cpp +329 -0
- package/vendor/zlib/contrib/iostream/zfstream.h +128 -0
- package/vendor/zlib/contrib/iostream2/zstream.h +307 -0
- package/vendor/zlib/contrib/iostream2/zstream_test.cpp +25 -0
- package/vendor/zlib/contrib/iostream3/README +35 -0
- package/vendor/zlib/contrib/iostream3/TODO +17 -0
- package/vendor/zlib/contrib/iostream3/test.cc +50 -0
- package/vendor/zlib/contrib/iostream3/zfstream.cc +479 -0
- package/vendor/zlib/contrib/iostream3/zfstream.h +466 -0
- package/vendor/zlib/contrib/minizip/CMakeLists.txt +380 -0
- package/vendor/zlib/contrib/minizip/Makefile +37 -0
- package/vendor/zlib/contrib/minizip/Makefile.am +45 -0
- package/vendor/zlib/contrib/minizip/MiniZip64_Changes.txt +6 -0
- package/vendor/zlib/contrib/minizip/MiniZip64_info.txt +74 -0
- package/vendor/zlib/contrib/minizip/configure.ac +32 -0
- package/vendor/zlib/contrib/minizip/crypt.h +128 -0
- package/vendor/zlib/contrib/minizip/ints.h +57 -0
- package/vendor/zlib/contrib/minizip/ioapi.c +231 -0
- package/vendor/zlib/contrib/minizip/ioapi.h +183 -0
- package/vendor/zlib/contrib/minizip/iowin32.c +448 -0
- package/vendor/zlib/contrib/minizip/iowin32.h +28 -0
- package/vendor/zlib/contrib/minizip/make_vms.com +25 -0
- package/vendor/zlib/contrib/minizip/miniunz.c +647 -0
- package/vendor/zlib/contrib/minizip/miniunzip.1 +63 -0
- package/vendor/zlib/contrib/minizip/minizip.1 +46 -0
- package/vendor/zlib/contrib/minizip/minizip.c +512 -0
- package/vendor/zlib/contrib/minizip/minizip.pc.in +12 -0
- package/vendor/zlib/contrib/minizip/minizip.pc.txt +13 -0
- package/vendor/zlib/contrib/minizip/minizipConfig.cmake.in +35 -0
- package/vendor/zlib/contrib/minizip/mztools.c +288 -0
- package/vendor/zlib/contrib/minizip/mztools.h +37 -0
- package/vendor/zlib/contrib/minizip/skipset.h +361 -0
- package/vendor/zlib/contrib/minizip/test/CMakeLists.txt +121 -0
- package/vendor/zlib/contrib/minizip/test/add_subdirectory_exclude_test.cmake.in +29 -0
- package/vendor/zlib/contrib/minizip/test/add_subdirectory_test.cmake.in +28 -0
- package/vendor/zlib/contrib/minizip/test/find_package_test.cmake.in +25 -0
- package/vendor/zlib/contrib/minizip/test/test_helper.cm +32 -0
- package/vendor/zlib/contrib/minizip/unzip.c +1981 -0
- package/vendor/zlib/contrib/minizip/unzip.h +441 -0
- package/vendor/zlib/contrib/minizip/zip.c +2199 -0
- package/vendor/zlib/contrib/minizip/zip.h +370 -0
- package/vendor/zlib/contrib/nuget/nuget.csproj +43 -0
- package/vendor/zlib/contrib/nuget/nuget.sln +22 -0
- package/vendor/zlib/contrib/pascal/example.pas +599 -0
- package/vendor/zlib/contrib/pascal/readme.txt +76 -0
- package/vendor/zlib/contrib/pascal/zlibd32.mak +99 -0
- package/vendor/zlib/contrib/pascal/zlibpas.pas +276 -0
- package/vendor/zlib/contrib/puff/Makefile +42 -0
- package/vendor/zlib/contrib/puff/README +63 -0
- package/vendor/zlib/contrib/puff/puff.c +840 -0
- package/vendor/zlib/contrib/puff/puff.h +35 -0
- package/vendor/zlib/contrib/puff/pufftest.c +169 -0
- package/vendor/zlib/contrib/puff/zeros.raw +0 -0
- package/vendor/zlib/contrib/testzlib/testzlib.c +275 -0
- package/vendor/zlib/contrib/testzlib/testzlib.txt +10 -0
- package/vendor/zlib/contrib/untgz/Makefile +14 -0
- package/vendor/zlib/contrib/untgz/Makefile.msc +17 -0
- package/vendor/zlib/contrib/untgz/untgz.c +667 -0
- package/vendor/zlib/contrib/vstudio/readme.txt +81 -0
- package/vendor/zlib/contrib/vstudio/vc10/miniunz.vcxproj +310 -0
- package/vendor/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters +22 -0
- package/vendor/zlib/contrib/vstudio/vc10/minizip.vcxproj +307 -0
- package/vendor/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters +22 -0
- package/vendor/zlib/contrib/vstudio/vc10/testzlib.vcxproj +412 -0
- package/vendor/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters +55 -0
- package/vendor/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj +310 -0
- package/vendor/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters +22 -0
- package/vendor/zlib/contrib/vstudio/vc10/zlib.rc +32 -0
- package/vendor/zlib/contrib/vstudio/vc10/zlibstat.vcxproj +449 -0
- package/vendor/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters +74 -0
- package/vendor/zlib/contrib/vstudio/vc10/zlibvc.def +161 -0
- package/vendor/zlib/contrib/vstudio/vc10/zlibvc.sln +135 -0
- package/vendor/zlib/contrib/vstudio/vc10/zlibvc.vcxproj +633 -0
- package/vendor/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters +115 -0
- package/vendor/zlib/contrib/vstudio/vc11/miniunz.vcxproj +314 -0
- package/vendor/zlib/contrib/vstudio/vc11/minizip.vcxproj +311 -0
- package/vendor/zlib/contrib/vstudio/vc11/testzlib.vcxproj +418 -0
- package/vendor/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj +314 -0
- package/vendor/zlib/contrib/vstudio/vc11/zlib.rc +32 -0
- package/vendor/zlib/contrib/vstudio/vc11/zlibstat.vcxproj +456 -0
- package/vendor/zlib/contrib/vstudio/vc11/zlibvc.def +161 -0
- package/vendor/zlib/contrib/vstudio/vc11/zlibvc.sln +117 -0
- package/vendor/zlib/contrib/vstudio/vc11/zlibvc.vcxproj +664 -0
- package/vendor/zlib/contrib/vstudio/vc12/miniunz.vcxproj +316 -0
- package/vendor/zlib/contrib/vstudio/vc12/minizip.vcxproj +313 -0
- package/vendor/zlib/contrib/vstudio/vc12/testzlib.vcxproj +422 -0
- package/vendor/zlib/contrib/vstudio/vc12/testzlibdll.vcxproj +316 -0
- package/vendor/zlib/contrib/vstudio/vc12/zlib.rc +32 -0
- package/vendor/zlib/contrib/vstudio/vc12/zlibstat.vcxproj +459 -0
- package/vendor/zlib/contrib/vstudio/vc12/zlibvc.def +161 -0
- package/vendor/zlib/contrib/vstudio/vc12/zlibvc.sln +119 -0
- package/vendor/zlib/contrib/vstudio/vc12/zlibvc.vcxproj +668 -0
- package/vendor/zlib/contrib/vstudio/vc14/miniunz.vcxproj +316 -0
- package/vendor/zlib/contrib/vstudio/vc14/minizip.vcxproj +313 -0
- package/vendor/zlib/contrib/vstudio/vc14/testzlib.vcxproj +422 -0
- package/vendor/zlib/contrib/vstudio/vc14/testzlibdll.vcxproj +316 -0
- package/vendor/zlib/contrib/vstudio/vc14/zlib.rc +32 -0
- package/vendor/zlib/contrib/vstudio/vc14/zlibstat.vcxproj +459 -0
- package/vendor/zlib/contrib/vstudio/vc14/zlibvc.def +161 -0
- package/vendor/zlib/contrib/vstudio/vc14/zlibvc.sln +119 -0
- package/vendor/zlib/contrib/vstudio/vc14/zlibvc.vcxproj +668 -0
- package/vendor/zlib/contrib/vstudio/vc17/miniunz.vcxproj +409 -0
- package/vendor/zlib/contrib/vstudio/vc17/minizip.vcxproj +405 -0
- package/vendor/zlib/contrib/vstudio/vc17/testzlib.vcxproj +473 -0
- package/vendor/zlib/contrib/vstudio/vc17/testzlibdll.vcxproj +409 -0
- package/vendor/zlib/contrib/vstudio/vc17/zlib.rc +32 -0
- package/vendor/zlib/contrib/vstudio/vc17/zlibstat.vcxproj +602 -0
- package/vendor/zlib/contrib/vstudio/vc17/zlibvc.def +161 -0
- package/vendor/zlib/contrib/vstudio/vc17/zlibvc.sln +179 -0
- package/vendor/zlib/contrib/vstudio/vc17/zlibvc.vcxproj +875 -0
- package/vendor/zlib/contrib/vstudio/vc9/miniunz.vcproj +565 -0
- package/vendor/zlib/contrib/vstudio/vc9/minizip.vcproj +562 -0
- package/vendor/zlib/contrib/vstudio/vc9/testzlib.vcproj +796 -0
- package/vendor/zlib/contrib/vstudio/vc9/testzlibdll.vcproj +565 -0
- package/vendor/zlib/contrib/vstudio/vc9/zlib.rc +32 -0
- package/vendor/zlib/contrib/vstudio/vc9/zlibstat.vcproj +781 -0
- package/vendor/zlib/contrib/vstudio/vc9/zlibvc.def +161 -0
- package/vendor/zlib/contrib/vstudio/vc9/zlibvc.sln +144 -0
- package/vendor/zlib/contrib/vstudio/vc9/zlibvc.vcproj +1100 -0
- package/vendor/zlib/crc32.c +1049 -0
- package/vendor/zlib/crc32.h +9446 -0
- package/vendor/zlib/deflate.c +2152 -0
- package/vendor/zlib/deflate.h +380 -0
- package/vendor/zlib/doc/algorithm.txt +209 -0
- package/vendor/zlib/doc/crc-doc.1.0.pdf +0 -0
- package/vendor/zlib/doc/rfc1950.txt +619 -0
- package/vendor/zlib/doc/rfc1951.txt +955 -0
- package/vendor/zlib/doc/rfc1952.txt +675 -0
- package/vendor/zlib/doc/txtvsbin.txt +107 -0
- package/vendor/zlib/examples/README.examples +54 -0
- package/vendor/zlib/examples/enough.c +597 -0
- package/vendor/zlib/examples/fitblk.c +233 -0
- package/vendor/zlib/examples/gun.c +702 -0
- package/vendor/zlib/examples/gzappend.c +504 -0
- package/vendor/zlib/examples/gzjoin.c +449 -0
- package/vendor/zlib/examples/gzlog.c +1061 -0
- package/vendor/zlib/examples/gzlog.h +91 -0
- package/vendor/zlib/examples/gznorm.c +474 -0
- package/vendor/zlib/examples/zlib_how.html +549 -0
- package/vendor/zlib/examples/zpipe.c +209 -0
- package/vendor/zlib/examples/zran.c +550 -0
- package/vendor/zlib/examples/zran.h +53 -0
- package/vendor/zlib/gzclose.c +23 -0
- package/vendor/zlib/gzguts.h +215 -0
- package/vendor/zlib/gzlib.c +585 -0
- package/vendor/zlib/gzread.c +603 -0
- package/vendor/zlib/gzwrite.c +631 -0
- package/vendor/zlib/infback.c +628 -0
- package/vendor/zlib/inffast.c +320 -0
- package/vendor/zlib/inffast.h +11 -0
- package/vendor/zlib/inffixed.h +94 -0
- package/vendor/zlib/inflate.c +1526 -0
- package/vendor/zlib/inflate.h +126 -0
- package/vendor/zlib/inftrees.c +299 -0
- package/vendor/zlib/inftrees.h +62 -0
- package/vendor/zlib/make_vms.com +867 -0
- package/vendor/zlib/msdos/Makefile.bor +115 -0
- package/vendor/zlib/msdos/Makefile.dj2 +104 -0
- package/vendor/zlib/msdos/Makefile.emx +69 -0
- package/vendor/zlib/msdos/Makefile.msc +112 -0
- package/vendor/zlib/msdos/Makefile.tc +100 -0
- package/vendor/zlib/nintendods/Makefile +126 -0
- package/vendor/zlib/nintendods/README +5 -0
- package/vendor/zlib/old/Makefile.emx +69 -0
- package/vendor/zlib/old/Makefile.riscos +151 -0
- package/vendor/zlib/old/README +3 -0
- package/vendor/zlib/old/descrip.mms +48 -0
- package/vendor/zlib/old/os2/Makefile.os2 +136 -0
- package/vendor/zlib/old/os2/zlib.def +51 -0
- package/vendor/zlib/old/visual-basic.txt +160 -0
- package/vendor/zlib/os400/README400 +48 -0
- package/vendor/zlib/os400/bndsrc +133 -0
- package/vendor/zlib/os400/make.sh +366 -0
- package/vendor/zlib/os400/zlib.inc +531 -0
- package/vendor/zlib/qnx/package.qpg +141 -0
- package/vendor/zlib/test/CMakeLists.txt +265 -0
- package/vendor/zlib/test/add_subdirectory_exclude_test.cmake.in +29 -0
- package/vendor/zlib/test/add_subdirectory_test.cmake.in +28 -0
- package/vendor/zlib/test/example.c +552 -0
- package/vendor/zlib/test/find_package_test.cmake.in +26 -0
- package/vendor/zlib/test/infcover.c +672 -0
- package/vendor/zlib/test/minigzip.c +590 -0
- package/vendor/zlib/treebuild.xml +116 -0
- package/vendor/zlib/trees.c +1119 -0
- package/vendor/zlib/trees.h +128 -0
- package/vendor/zlib/uncompr.c +85 -0
- package/vendor/zlib/watcom/watcom_f.mak +43 -0
- package/vendor/zlib/watcom/watcom_l.mak +43 -0
- package/vendor/zlib/win32/DLL_FAQ.txt +381 -0
- package/vendor/zlib/win32/Makefile.bor +109 -0
- package/vendor/zlib/win32/Makefile.gcc +177 -0
- package/vendor/zlib/win32/Makefile.msc +159 -0
- package/vendor/zlib/win32/README-WIN32.txt +103 -0
- package/vendor/zlib/win32/VisualC.txt +3 -0
- package/vendor/zlib/win32/zlib.def +98 -0
- package/vendor/zlib/win32/zlib1.rc +37 -0
- package/vendor/zlib/zconf.h.in +544 -0
- package/vendor/zlib/zlib.3 +149 -0
- package/vendor/zlib/zlib.3.pdf +0 -0
- package/vendor/zlib/zlib.h +1957 -0
- package/vendor/zlib/zlib.map +104 -0
- package/vendor/zlib/zlib.pc.cmakein +13 -0
- package/vendor/zlib/zlib.pc.in +13 -0
- package/vendor/zlib/zlibConfig.cmake.in +26 -0
- package/vendor/zlib/zutil.c +299 -0
- package/vendor/zlib/zutil.h +257 -0
- package/vendor/zsign/.gitattributes +4 -0
- package/vendor/zsign/LICENSE +21 -0
- package/vendor/zsign/README.md +142 -0
- package/vendor/zsign/build/linux/Makefile +43 -0
- package/vendor/zsign/build/macos/Makefile +43 -0
- package/vendor/zsign/build/windows/vs2022/include/minizip/crypt.h +128 -0
- package/vendor/zsign/build/windows/vs2022/include/minizip/ioapi.h +216 -0
- package/vendor/zsign/build/windows/vs2022/include/minizip/iowin32.h +28 -0
- package/vendor/zsign/build/windows/vs2022/include/minizip/mztools.h +37 -0
- package/vendor/zsign/build/windows/vs2022/include/minizip/unzip.h +437 -0
- package/vendor/zsign/build/windows/vs2022/include/minizip/zip.h +364 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/__DECC_INCLUDE_EPILOGUE.H +22 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/__DECC_INCLUDE_PROLOGUE.H +26 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/aes.h +111 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/applink.c +153 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/asn1.h +1133 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/asn1_mac.h +10 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/asn1err.h +142 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/asn1t.h +946 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/async.h +104 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/asyncerr.h +29 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/bio.h +1015 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/bioerr.h +72 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/blowfish.h +78 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/bn.h +590 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/bnerr.h +47 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/buffer.h +62 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/buffererr.h +25 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/camellia.h +117 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/cast.h +71 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/cmac.h +52 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/cmp.h +727 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/cmp_util.h +56 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/cmperr.h +131 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/cms.h +508 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/cmserr.h +125 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/comp.h +98 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/comperr.h +38 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/conf.h +214 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/conf_api.h +46 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/conferr.h +52 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/configuration.h +188 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/conftypes.h +44 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/core.h +236 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/core_dispatch.h +1022 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/core_names.h +545 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/core_object.h +41 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/crmf.h +260 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/crmferr.h +50 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/crypto.h +580 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/cryptoerr.h +56 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/cryptoerr_legacy.h +1466 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ct.h +573 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/cterr.h +45 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/decoder.h +133 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/decodererr.h +28 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/des.h +211 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/dh.h +339 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/dherr.h +59 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/dsa.h +280 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/dsaerr.h +44 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/dtls1.h +57 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/e_os2.h +310 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/e_ostime.h +38 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ebcdic.h +39 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ec.h +1588 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ecdh.h +10 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ecdsa.h +10 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ecerr.h +104 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/encoder.h +124 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/encodererr.h +28 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/engine.h +833 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/engineerr.h +63 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/err.h +512 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ess.h +128 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/esserr.h +32 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/evp.h +2231 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/evperr.h +140 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/fips_names.h +50 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/fipskey.h +41 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/hmac.h +62 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/hpke.h +169 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/http.h +118 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/httperr.h +56 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/idea.h +82 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/indicator.h +31 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/kdf.h +138 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/kdferr.h +16 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/lhash.h +398 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/macros.h +338 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/md2.h +56 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/md4.h +63 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/md5.h +62 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/mdc2.h +55 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/modes.h +219 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/obj_mac.h +5820 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/objects.h +184 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/objectserr.h +28 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ocsp.h +483 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ocsperr.h +53 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/opensslconf.h +17 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/opensslv.h +114 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ossl_typ.h +16 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/param_build.h +63 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/params.h +160 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/pem.h +543 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/pem2.h +19 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/pemerr.h +58 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/pkcs12.h +366 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/pkcs12err.h +46 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/pkcs7.h +430 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/pkcs7err.h +63 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/prov_ssl.h +38 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/proverr.h +162 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/provider.h +66 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/quic.h +70 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/rand.h +125 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/randerr.h +69 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/rc2.h +68 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/rc4.h +47 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/rc5.h +79 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ripemd.h +59 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/rsa.h +615 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/rsaerr.h +107 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/safestack.h +297 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/seed.h +113 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/self_test.h +98 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/sha.h +139 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/srp.h +285 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/srtp.h +68 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ssl.h +2878 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ssl2.h +30 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ssl3.h +357 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/sslerr.h +379 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/sslerr_legacy.h +467 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/stack.h +90 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/store.h +377 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/storeerr.h +49 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/symhacks.h +39 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/thread.h +31 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/tls1.h +1220 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/trace.h +320 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ts.h +522 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/tserr.h +67 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/txt_db.h +63 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/types.h +245 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/ui.h +407 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/uierr.h +38 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/whrlpool.h +62 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/x509.h +1304 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/x509_acert.h +263 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/x509_vfy.h +902 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/x509err.h +70 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/x509v3.h +1500 -0
- package/vendor/zsign/build/windows/vs2022/include/openssl/x509v3err.h +96 -0
- package/vendor/zsign/build/windows/vs2022/include/zlib/zconf.h +553 -0
- package/vendor/zsign/build/windows/vs2022/include/zlib/zlib.h +1938 -0
- package/vendor/zsign/build/windows/vs2022/lib/minizip/x64/mt/minizip.lib +0 -0
- package/vendor/zsign/build/windows/vs2022/lib/openssl/x64/mt/libcrypto.lib +0 -0
- package/vendor/zsign/build/windows/vs2022/lib/openssl/x64/mt/libssl.lib +0 -0
- package/vendor/zsign/build/windows/vs2022/lib/zlib/x64/mt/zlib.lib +0 -0
- package/vendor/zsign/build/windows/vs2022/zsign/src/common_win32.h +44 -0
- package/vendor/zsign/build/windows/vs2022/zsign/src/getopt.cpp +69 -0
- package/vendor/zsign/build/windows/vs2022/zsign/src/getopt.h +20 -0
- package/vendor/zsign/build/windows/vs2022/zsign/src/iconv.cpp +138 -0
- package/vendor/zsign/build/windows/vs2022/zsign/src/iconv.h +38 -0
- package/vendor/zsign/build/windows/vs2022/zsign/zsign.vcxproj +177 -0
- package/vendor/zsign/build/windows/vs2022/zsign/zsign.vcxproj.filters +120 -0
- package/vendor/zsign/build/windows/vs2022/zsign.sln +28 -0
- package/vendor/zsign/src/archo.cpp +742 -0
- package/vendor/zsign/src/archo.h +61 -0
- package/vendor/zsign/src/bundle.cpp +589 -0
- package/vendor/zsign/src/bundle.h +46 -0
- package/vendor/zsign/src/common/archive.cpp +246 -0
- package/vendor/zsign/src/common/archive.h +22 -0
- package/vendor/zsign/src/common/base64.cpp +166 -0
- package/vendor/zsign/src/common/base64.h +30 -0
- package/vendor/zsign/src/common/common.h +56 -0
- package/vendor/zsign/src/common/fs.cpp +573 -0
- package/vendor/zsign/src/common/fs.h +50 -0
- package/vendor/zsign/src/common/json.cpp +3380 -0
- package/vendor/zsign/src/common/json.h +530 -0
- package/vendor/zsign/src/common/log.cpp +145 -0
- package/vendor/zsign/src/common/log.h +37 -0
- package/vendor/zsign/src/common/mach-o.h +585 -0
- package/vendor/zsign/src/common/sha.cpp +133 -0
- package/vendor/zsign/src/common/sha.h +24 -0
- package/vendor/zsign/src/common/timer.cpp +28 -0
- package/vendor/zsign/src/common/timer.h +17 -0
- package/vendor/zsign/src/common/util.cpp +185 -0
- package/vendor/zsign/src/common/util.h +25 -0
- package/vendor/zsign/src/macho.cpp +273 -0
- package/vendor/zsign/src/macho.h +38 -0
- package/vendor/zsign/src/openssl.cpp +698 -0
- package/vendor/zsign/src/openssl.h +71 -0
- package/vendor/zsign/src/signing.cpp +745 -0
- package/vendor/zsign/src/signing.h +59 -0
- package/vendor/zsign/src/zsign.cpp +317 -0
- package/vendor/zsign/test/dylib/bin/demo1.dylib +0 -0
- package/vendor/zsign/test/dylib/bin/demo2.dylib +0 -0
- package/vendor/zsign/test/dylib/demo/Makefile +12 -0
- package/vendor/zsign/test/dylib/demo/control +9 -0
- package/vendor/zsign/test/dylib/demo/demo.m +21 -0
- package/vendor/zsign/test/linux/test.sh +19 -0
- package/vendor/zsign/test/macos/test.sh +19 -0
- 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 += "<";
|
|
2041
|
+
break;
|
|
2042
|
+
case '>':
|
|
2043
|
+
ret += ">";
|
|
2044
|
+
break;
|
|
2045
|
+
case '\"':
|
|
2046
|
+
ret += """;
|
|
2047
|
+
break;
|
|
2048
|
+
// case '&': ret += "&"; 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, "&", "&");
|
|
3365
|
+
_string_replace(str, "<", "<");
|
|
3366
|
+
//_string_replace(str, ">", ">"); //optional
|
|
3367
|
+
//_string_replace(str, "'", "'"); //optional
|
|
3368
|
+
//_string_replace(str, "\"", """); //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
|
+
}
|