├── .gitattributes ├── .gitignore ├── C++ XenForo Loader.sln ├── C++ XenForo Loader.vcxproj ├── C++ XenForo Loader.vcxproj.filters ├── README.md ├── configmanager ├── configmanager.cpp └── configmanager.hpp ├── main.cpp ├── rapidjson ├── allocators.h ├── document.h ├── encodedstream.h ├── encodings.h ├── error │ ├── en.h │ └── error.h ├── filereadstream.h ├── filewritestream.h ├── fwd.h ├── internal │ ├── biginteger.h │ ├── diyfp.h │ ├── dtoa.h │ ├── ieee754.h │ ├── itoa.h │ ├── meta.h │ ├── pow10.h │ ├── regex.h │ ├── stack.h │ ├── strfunc.h │ ├── strtod.h │ └── swap.h ├── istreamwrapper.h ├── memorybuffer.h ├── memorystream.h ├── msinttypes │ ├── inttypes.h │ └── stdint.h ├── ostreamwrapper.h ├── pointer.h ├── prettywriter.h ├── rapidjson.h ├── reader.h ├── schema.h ├── stream.h ├── stringbuffer.h └── writer.h ├── request └── request.hpp ├── utils ├── utils.cpp └── utils.hpp └── webfiles └── hwid.php /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | [Aa][Rr][Mm]/ 24 | [Aa][Rr][Mm]64/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | [Ll]og/ 29 | 30 | # Visual Studio 2015/2017 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # Visual Studio 2017 auto generated files 36 | Generated\ Files/ 37 | 38 | # MSTest test Results 39 | [Tt]est[Rr]esult*/ 40 | [Bb]uild[Ll]og.* 41 | 42 | # NUNIT 43 | *.VisualState.xml 44 | TestResult.xml 45 | 46 | # Build Results of an ATL Project 47 | [Dd]ebugPS/ 48 | [Rr]eleasePS/ 49 | dlldata.c 50 | 51 | # Benchmark Results 52 | BenchmarkDotNet.Artifacts/ 53 | 54 | # .NET Core 55 | project.lock.json 56 | project.fragment.lock.json 57 | artifacts/ 58 | 59 | # StyleCop 60 | StyleCopReport.xml 61 | 62 | # Files built by Visual Studio 63 | *_i.c 64 | *_p.c 65 | *_h.h 66 | *.ilk 67 | *.meta 68 | *.obj 69 | *.iobj 70 | *.pch 71 | *.pdb 72 | *.ipdb 73 | *.pgc 74 | *.pgd 75 | *.rsp 76 | *.sbr 77 | *.tlb 78 | *.tli 79 | *.tlh 80 | *.tmp 81 | *.tmp_proj 82 | *_wpftmp.csproj 83 | *.log 84 | *.vspscc 85 | *.vssscc 86 | .builds 87 | *.pidb 88 | *.svclog 89 | *.scc 90 | 91 | # Chutzpah Test files 92 | _Chutzpah* 93 | 94 | # Visual C++ cache files 95 | ipch/ 96 | *.aps 97 | *.ncb 98 | *.opendb 99 | *.opensdf 100 | *.sdf 101 | *.cachefile 102 | *.VC.db 103 | *.VC.VC.opendb 104 | 105 | # Visual Studio profiler 106 | *.psess 107 | *.vsp 108 | *.vspx 109 | *.sap 110 | 111 | # Visual Studio Trace Files 112 | *.e2e 113 | 114 | # TFS 2012 Local Workspace 115 | $tf/ 116 | 117 | # Guidance Automation Toolkit 118 | *.gpState 119 | 120 | # ReSharper is a .NET coding add-in 121 | _ReSharper*/ 122 | *.[Rr]e[Ss]harper 123 | *.DotSettings.user 124 | 125 | # JustCode is a .NET coding add-in 126 | .JustCode 127 | 128 | # TeamCity is a build add-in 129 | _TeamCity* 130 | 131 | # DotCover is a Code Coverage Tool 132 | *.dotCover 133 | 134 | # AxoCover is a Code Coverage Tool 135 | .axoCover/* 136 | !.axoCover/settings.json 137 | 138 | # Visual Studio code coverage results 139 | *.coverage 140 | *.coveragexml 141 | 142 | # NCrunch 143 | _NCrunch_* 144 | .*crunch*.local.xml 145 | nCrunchTemp_* 146 | 147 | # MightyMoose 148 | *.mm.* 149 | AutoTest.Net/ 150 | 151 | # Web workbench (sass) 152 | .sass-cache/ 153 | 154 | # Installshield output folder 155 | [Ee]xpress/ 156 | 157 | # DocProject is a documentation generator add-in 158 | DocProject/buildhelp/ 159 | DocProject/Help/*.HxT 160 | DocProject/Help/*.HxC 161 | DocProject/Help/*.hhc 162 | DocProject/Help/*.hhk 163 | DocProject/Help/*.hhp 164 | DocProject/Help/Html2 165 | DocProject/Help/html 166 | 167 | # Click-Once directory 168 | publish/ 169 | 170 | # Publish Web Output 171 | *.[Pp]ublish.xml 172 | *.azurePubxml 173 | # Note: Comment the next line if you want to checkin your web deploy settings, 174 | # but database connection strings (with potential passwords) will be unencrypted 175 | *.pubxml 176 | *.publishproj 177 | 178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 179 | # checkin your Azure Web App publish settings, but sensitive information contained 180 | # in these scripts will be unencrypted 181 | PublishScripts/ 182 | 183 | # NuGet Packages 184 | *.nupkg 185 | # The packages folder can be ignored because of Package Restore 186 | **/[Pp]ackages/* 187 | # except build/, which is used as an MSBuild target. 188 | !**/[Pp]ackages/build/ 189 | # Uncomment if necessary however generally it will be regenerated when needed 190 | #!**/[Pp]ackages/repositories.config 191 | # NuGet v3's project.json files produces more ignorable files 192 | *.nuget.props 193 | *.nuget.targets 194 | 195 | # Microsoft Azure Build Output 196 | csx/ 197 | *.build.csdef 198 | 199 | # Microsoft Azure Emulator 200 | ecf/ 201 | rcf/ 202 | 203 | # Windows Store app package directories and files 204 | AppPackages/ 205 | BundleArtifacts/ 206 | Package.StoreAssociation.xml 207 | _pkginfo.txt 208 | *.appx 209 | 210 | # Visual Studio cache files 211 | # files ending in .cache can be ignored 212 | *.[Cc]ache 213 | # but keep track of directories ending in .cache 214 | !?*.[Cc]ache/ 215 | 216 | # Others 217 | ClientBin/ 218 | ~$* 219 | *~ 220 | *.dbmdl 221 | *.dbproj.schemaview 222 | *.jfm 223 | *.pfx 224 | *.publishsettings 225 | orleans.codegen.cs 226 | 227 | # Including strong name files can present a security risk 228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 229 | #*.snk 230 | 231 | # Since there are multiple workflows, uncomment next line to ignore bower_components 232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 233 | #bower_components/ 234 | 235 | # RIA/Silverlight projects 236 | Generated_Code/ 237 | 238 | # Backup & report files from converting an old project file 239 | # to a newer Visual Studio version. Backup files are not needed, 240 | # because we have git ;-) 241 | _UpgradeReport_Files/ 242 | Backup*/ 243 | UpgradeLog*.XML 244 | UpgradeLog*.htm 245 | ServiceFabricBackup/ 246 | *.rptproj.bak 247 | 248 | # SQL Server files 249 | *.mdf 250 | *.ldf 251 | *.ndf 252 | 253 | # Business Intelligence projects 254 | *.rdl.data 255 | *.bim.layout 256 | *.bim_*.settings 257 | *.rptproj.rsuser 258 | *- Backup*.rdl 259 | 260 | # Microsoft Fakes 261 | FakesAssemblies/ 262 | 263 | # GhostDoc plugin setting file 264 | *.GhostDoc.xml 265 | 266 | # Node.js Tools for Visual Studio 267 | .ntvs_analysis.dat 268 | node_modules/ 269 | 270 | # Visual Studio 6 build log 271 | *.plg 272 | 273 | # Visual Studio 6 workspace options file 274 | *.opt 275 | 276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 277 | *.vbw 278 | 279 | # Visual Studio LightSwitch build output 280 | **/*.HTMLClient/GeneratedArtifacts 281 | **/*.DesktopClient/GeneratedArtifacts 282 | **/*.DesktopClient/ModelManifest.xml 283 | **/*.Server/GeneratedArtifacts 284 | **/*.Server/ModelManifest.xml 285 | _Pvt_Extensions 286 | 287 | # Paket dependency manager 288 | .paket/paket.exe 289 | paket-files/ 290 | 291 | # FAKE - F# Make 292 | .fake/ 293 | 294 | # JetBrains Rider 295 | .idea/ 296 | *.sln.iml 297 | 298 | # CodeRush personal settings 299 | .cr/personal 300 | 301 | # Python Tools for Visual Studio (PTVS) 302 | __pycache__/ 303 | *.pyc 304 | 305 | # Cake - Uncomment if you are using it 306 | # tools/** 307 | # !tools/packages.config 308 | 309 | # Tabs Studio 310 | *.tss 311 | 312 | # Telerik's JustMock configuration file 313 | *.jmconfig 314 | 315 | # BizTalk build output 316 | *.btp.cs 317 | *.btm.cs 318 | *.odx.cs 319 | *.xsd.cs 320 | 321 | # OpenCover UI analysis results 322 | OpenCover/ 323 | 324 | # Azure Stream Analytics local run output 325 | ASALocalRun/ 326 | 327 | # MSBuild Binary and Structured Log 328 | *.binlog 329 | 330 | # NVidia Nsight GPU debugger configuration file 331 | *.nvuser 332 | 333 | # MFractors (Xamarin productivity tool) working folder 334 | .mfractor/ 335 | 336 | # Local History for Visual Studio 337 | .localhistory/ 338 | 339 | # BeatPulse healthcheck temp database 340 | healthchecksdb -------------------------------------------------------------------------------- /C++ XenForo Loader.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29806.167 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "C++ XenForo Loader", "C++ XenForo Loader.vcxproj", "{64A9A18D-04B3-452E-8B6D-2E672340CB94}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Debug|x64 = Debug|x64 12 | Release|Win32 = Release|Win32 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {64A9A18D-04B3-452E-8B6D-2E672340CB94}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {64A9A18D-04B3-452E-8B6D-2E672340CB94}.Debug|Win32.Build.0 = Debug|Win32 18 | {64A9A18D-04B3-452E-8B6D-2E672340CB94}.Debug|x64.ActiveCfg = Debug|x64 19 | {64A9A18D-04B3-452E-8B6D-2E672340CB94}.Debug|x64.Build.0 = Debug|x64 20 | {64A9A18D-04B3-452E-8B6D-2E672340CB94}.Release|Win32.ActiveCfg = Release|Win32 21 | {64A9A18D-04B3-452E-8B6D-2E672340CB94}.Release|Win32.Build.0 = Release|Win32 22 | {64A9A18D-04B3-452E-8B6D-2E672340CB94}.Release|x64.ActiveCfg = Release|x64 23 | {64A9A18D-04B3-452E-8B6D-2E672340CB94}.Release|x64.Build.0 = Release|x64 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {6D044158-618D-46A1-A83E-AD851AD02821} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /C++ XenForo Loader.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {64A9A18D-04B3-452E-8B6D-2E672340CB94} 24 | Win32Proj 25 | C++ XenForo Loader 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | MultiByte 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | MultiByte 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | $(IncludePath) 82 | 83 | 84 | false 85 | 86 | 87 | 88 | 89 | 90 | Level3 91 | true 92 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 93 | true 94 | 95 | 96 | Console 97 | true 98 | 99 | 100 | 101 | 102 | 103 | 104 | Level3 105 | true 106 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 107 | true 108 | 109 | 110 | Console 111 | true 112 | 113 | 114 | 115 | 116 | Level3 117 | MaxSpeed 118 | true 119 | true 120 | _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 121 | true 122 | 123 | 124 | Console 125 | true 126 | true 127 | true 128 | ws2_32.lib;%(AdditionalDependencies) 129 | 130 | 131 | 132 | 133 | 134 | 135 | Level3 136 | true 137 | true 138 | true 139 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 140 | true 141 | 142 | 143 | Console 144 | true 145 | true 146 | true 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /C++ XenForo Loader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | configmanager 7 | 8 | 9 | utils 10 | 11 | 12 | 13 | 14 | {c1f500b1-6010-4a1f-bf64-b839deffb04b} 15 | 16 | 17 | {8c7cb401-9c93-434c-acca-d922ff8bb2b3} 18 | 19 | 20 | {0f2108a5-3fac-4c77-8199-3e10157896f4} 21 | 22 | 23 | {5efc35dd-bd16-4c84-bbb3-91b137dec4eb} 24 | 25 | 26 | {038d4898-94fc-471a-9ea1-8c3a4b1df4d0} 27 | 28 | 29 | {50f53050-300b-4a21-8774-1b2260714df6} 30 | 31 | 32 | {ad52dae1-daa0-48a6-8772-52f19b6b1890} 33 | 34 | 35 | 36 | 37 | request 38 | 39 | 40 | rapidjson 41 | 42 | 43 | rapidjson 44 | 45 | 46 | rapidjson 47 | 48 | 49 | rapidjson 50 | 51 | 52 | rapidjson 53 | 54 | 55 | rapidjson 56 | 57 | 58 | rapidjson 59 | 60 | 61 | rapidjson 62 | 63 | 64 | rapidjson 65 | 66 | 67 | rapidjson 68 | 69 | 70 | rapidjson 71 | 72 | 73 | rapidjson 74 | 75 | 76 | rapidjson 77 | 78 | 79 | rapidjson 80 | 81 | 82 | rapidjson 83 | 84 | 85 | rapidjson 86 | 87 | 88 | rapidjson 89 | 90 | 91 | rapidjson 92 | 93 | 94 | rapidjson 95 | 96 | 97 | rapidjson\msinttypes 98 | 99 | 100 | rapidjson\msinttypes 101 | 102 | 103 | rapidjson\internal 104 | 105 | 106 | rapidjson\internal 107 | 108 | 109 | rapidjson\internal 110 | 111 | 112 | rapidjson\internal 113 | 114 | 115 | rapidjson\internal 116 | 117 | 118 | rapidjson\internal 119 | 120 | 121 | rapidjson\internal 122 | 123 | 124 | rapidjson\internal 125 | 126 | 127 | rapidjson\internal 128 | 129 | 130 | rapidjson\internal 131 | 132 | 133 | rapidjson\internal 134 | 135 | 136 | rapidjson\internal 137 | 138 | 139 | rapidjson\error 140 | 141 | 142 | rapidjson\error 143 | 144 | 145 | configmanager 146 | 147 | 148 | utils 149 | 150 | 151 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CPP-XenForo-Loader 2 | WIP Cheat Loader which authenticates with a XenForo 2.1 forum. 3 | 4 | Open-Source made for Void.to using rapidjson and httprequests. 5 | 6 | Please stop contacting, i will publish a reworked version of this sooner or later. 7 | -------------------------------------------------------------------------------- /configmanager/configmanager.cpp: -------------------------------------------------------------------------------- 1 | #include "configmanager.hpp" 2 | 3 | void CConfigManager::GetValue(string szSection, string szKey, string* Value, string szPath) { 4 | TCHAR KeyValue[32]; 5 | GetPrivateProfileString(szSection.c_str(), szKey.c_str(), "", KeyValue, 32, szPath.c_str()); 6 | 7 | string szKeyValue = KeyValue; 8 | 9 | *Value = szKeyValue; 10 | } 11 | 12 | void CConfigManager::GetValue(string szSection, string szKey, double* Value, string szPath) { 13 | TCHAR KeyValue[32]; 14 | GetPrivateProfileString(szSection.c_str(), szKey.c_str(), "", KeyValue, 32, szPath.c_str()); 15 | 16 | string szKeyValue = KeyValue; 17 | 18 | double nKeyValue = atof(szKeyValue.c_str()); 19 | 20 | *Value = nKeyValue; 21 | } 22 | 23 | void CConfigManager::GetValue(string szSection, string szKey, int* Value, string szPath) { 24 | TCHAR KeyValue[32]; 25 | GetPrivateProfileString(szSection.c_str(), szKey.c_str(), "", KeyValue, 32, szPath.c_str()); 26 | 27 | string szKeyValue = KeyValue; 28 | 29 | int nKeyValue = atoi(szKeyValue.c_str()); 30 | 31 | *Value = nKeyValue; 32 | } 33 | 34 | void CConfigManager::GetValue(string szSection, string szKey, float* Value, string szPath) { 35 | TCHAR KeyValue[32]; 36 | GetPrivateProfileString(szSection.c_str(), szKey.c_str(), "", KeyValue, 32, szPath.c_str()); 37 | 38 | string szKeyValue = KeyValue; 39 | 40 | float nKeyValue = (float)atof(szKeyValue.c_str()); 41 | 42 | *Value = nKeyValue; 43 | } 44 | 45 | void CConfigManager::GetValue(string szSection, string szKey, bool* Value, string szPath) { 46 | TCHAR KeyValue[32]; 47 | GetPrivateProfileString(szSection.c_str(), szKey.c_str(), "", KeyValue, 32, szPath.c_str()); 48 | 49 | string szKeyValue = KeyValue; 50 | 51 | bool bKeyValue = StringToBool(szKeyValue); 52 | 53 | *Value = bKeyValue; 54 | } 55 | 56 | void CConfigManager::PushValue(string szSection, string szKey, string Value, string szPath) { 57 | WritePrivateProfileString(szSection.c_str(), szKey.c_str(), Value.c_str(), szPath.c_str()); 58 | } 59 | 60 | void CConfigManager::PushValue(string szSection, string szKey, double* Value, string szPath) { 61 | string szKeyValue = to_string(*Value); 62 | 63 | WritePrivateProfileString(szSection.c_str(), szKey.c_str(), szKeyValue.c_str(), szPath.c_str()); 64 | } 65 | 66 | void CConfigManager::PushValue(string szSection, string szKey, int* Value, string szPath) { 67 | string szKeyValue = to_string(*Value); 68 | 69 | WritePrivateProfileString(szSection.c_str(), szKey.c_str(), szKeyValue.c_str(), szPath.c_str()); 70 | } 71 | 72 | void CConfigManager::PushValue(string szSection, string szKey, float* Value, string szPath) { 73 | string szKeyValue = to_string(*Value); 74 | 75 | WritePrivateProfileString(szSection.c_str(), szKey.c_str(), szKeyValue.c_str(), szPath.c_str()); 76 | } 77 | 78 | void CConfigManager::PushValue(string szSection, string szKey, bool* Value, string szPath) { 79 | string szKeyValue = BoolToString(*Value); 80 | 81 | WritePrivateProfileString(szSection.c_str(), szKey.c_str(), szKeyValue.c_str(), szPath.c_str()); 82 | } 83 | 84 | void CConfigManager::MakeValue(string szSection, string szKey, string Value, string szPath, bool bIsSave) { 85 | if (!bIsSave) 86 | GetValue(szSection, szKey, &Value, szPath); 87 | else 88 | PushValue(szSection, szKey, Value, szPath); 89 | } 90 | 91 | void CConfigManager::MakeValue(string szSection, string szKey, double* Value, string szPath, bool bIsSave) { 92 | if (!bIsSave) 93 | GetValue(szSection, szKey, Value, szPath); 94 | else 95 | PushValue(szSection, szKey, Value, szPath); 96 | } 97 | 98 | void CConfigManager::MakeValue(string szSection, string szKey, int* Value, string szPath, bool bIsSave) { 99 | if (!bIsSave) 100 | GetValue(szSection, szKey, Value, szPath); 101 | else 102 | PushValue(szSection, szKey, Value, szPath); 103 | } 104 | 105 | void CConfigManager::MakeValue(string szSection, string szKey, float* Value, string szPath, bool bIsSave) { 106 | if (!bIsSave) 107 | GetValue(szSection, szKey, Value, szPath); 108 | else 109 | PushValue(szSection, szKey, Value, szPath); 110 | } 111 | 112 | void CConfigManager::MakeValue(string szSection, string szKey, bool* Value, string szPath, bool bIsSave) { 113 | if (!bIsSave) 114 | GetValue(szSection, szKey, Value, szPath); 115 | else 116 | PushValue(szSection, szKey, Value, szPath); 117 | } 118 | 119 | string CConfigManager::BoolToString(bool value) 120 | { 121 | return value ? "true" : "false"; 122 | } 123 | 124 | bool CConfigManager::StringToBool(string value) 125 | { 126 | return (value == "true") ? true : false; 127 | } 128 | 129 | CConfigManager* configmanager; -------------------------------------------------------------------------------- /configmanager/configmanager.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class CConfigManager 7 | { 8 | public: 9 | void GetValue(string szSection, string szKey, string* Value, string szPath); 10 | void GetValue(string szSection, string szKey, double* Value, string szPath); 11 | void GetValue(string szSection, string szKey, int* Value, string szPath); 12 | void GetValue(string szSection, string szKey, float* Value, string szPath); 13 | void GetValue(string szSection, string szKey, bool* Value, string szPath); 14 | 15 | void PushValue(string szSection, string szKey, string Value, string szPath); 16 | void PushValue(string szSection, string szKey, double* Value, string szPath); 17 | void PushValue(string szSection, string szKey, int* Value, string szPath); 18 | void PushValue(string szSection, string szKey, float* Value, string szPath); 19 | void PushValue(string szSection, string szKey, bool* Value, string szPath); 20 | 21 | void MakeValue(string szSection, string szKey, string Value, string szPath, bool bIsSave); 22 | void MakeValue(string szSection, string szKey, double* Value, string szPath, bool bIsSave); 23 | void MakeValue(string szSection, string szKey, int* Value, string szPath, bool bIsSave); 24 | void MakeValue(string szSection, string szKey, float* Value, string szPath, bool bIsSave); 25 | void MakeValue(string szSection, string szKey, bool* Value, string szPath, bool bIsSave); 26 | private: 27 | string BoolToString(bool value); 28 | bool StringToBool(string value); 29 | }; 30 | 31 | extern CConfigManager* configmanager; -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | // windows related 2 | #include 3 | #include 4 | #include 5 | #include 6 | // request 7 | #include "request/request.hpp" 8 | // rapidjson 9 | #include "rapidjson/document.h" 10 | #include "rapidjson/pointer.h" 11 | #include "rapidjson/stringbuffer.h" 12 | #include "rapidjson/writer.h" 13 | // utils 14 | #include "utils/utils.hpp" 15 | 16 | // using namespaces to make the code cleaner without typing everything with std:: etc 17 | using namespace std; 18 | using namespace http; 19 | using namespace rapidjson; 20 | 21 | int main() 22 | { 23 | /* 24 | some sidenote for the hwid check, there are for sure multiple ways for this, 25 | but imo it was the easiest way to connect to the xenforo database via a php script and 26 | provide it through there. 27 | but to avoid random people fucking up the hwid system (because in the php file we won't check the password) 28 | we will secure the input by a token which is defined in the php file and inside the loader. 29 | */ 30 | 31 | string username, password; // defined authentication strings 32 | string hwid, hwidtoken, respondedhwid; // hwid related strings 33 | string appdata, appdatafolder, appdatafile; // paths/file to store the authentication data locally on the host's pc 34 | bool success; // used later for checking our login data 35 | 36 | // definining the paths/file 37 | appdata = utils->GetAppData(); 38 | appdatafolder = appdata + "\\loader"; 39 | appdatafile = appdatafolder + "\\logindata.ini"; 40 | 41 | if (!utils->dirExists(appdatafolder.c_str())) // check if the folder exists already 42 | _mkdir(appdatafolder.c_str()); // creating a folder inside appdata 43 | 44 | cout << "enter your username:" << endl; // asking for the username 45 | cin >> username; // getting the username as input 46 | cout << "enter your password:" << endl; // asking for the password 47 | cin >> password; // getting the password as inpout 48 | 49 | try // try to make a request 50 | { 51 | Request request("http://xenforo.gandaa.lv/index.php/api/auth"); // xenforo api url / request url 52 | 53 | // making the post request 54 | const Response postResponse = request.send("POST", "login=" + username + "&password=" + password, { 55 | "Content-Type: application/x-www-form-urlencoded", "XF-Api-Key: TqfDwgHw3dpuXGXC9MqVdWRmhJUic9BO" // your xenforo api key 56 | }); 57 | 58 | // setting up the json document and parsing the output 59 | Document document; 60 | document.Parse(string(postResponse.body.begin(), postResponse.body.end()).c_str()); 61 | 62 | assert(document["success"].IsBool()); // checking if the resonded function "success" is a bool 63 | success = document["success"].GetBool(); // defining our local variable "success" to be the responded bool 64 | 65 | if (success == true) 66 | { 67 | cout << "login was successful :)" << endl; 68 | 69 | // now we do a staff check first, if the logged in user is a staff member, we will skip the hwid check 70 | 71 | if (Value* user = GetValueByPointer(document, "/user")) // since "success" and "user" are 2 different pointers, we need to resolve the second one 72 | { 73 | if ((*user)["is_staff"].GetBool() || (*user)["is_admin"].GetBool() || (*user)["is_moderator"].GetBool() || (*user)["is_super_admin"].GetBool() == true) { // we check if either one of those staff variables are true 74 | cout << "staff member detected, no hwid check needed!" << endl; 75 | 76 | // from here the main authentication is basically done, next step would be the cheat part. 77 | } 78 | else // if the logged in user is not a staff member, continue with the hwid check 79 | { 80 | if (Value* v = GetValueByPointer(document, "/user")) { 81 | const Value& secondary_group = (*v)["secondary_group_ids"]; 82 | assert(secondary_group.IsArray()); 83 | 84 | if (secondary_group[0].GetInt() == 2 || secondary_group[0].GetInt() == 3 || secondary_group[0].GetInt() == 4 || secondary_group[0].GetInt() == 5) // kinda ghetto like, but it checks for the secondary group ids. why? because the xenforo userupgrade function only edits the secondary group id, not the primary. 85 | { // the 0 defines ^^^ the position of inside the array, the other numbers define the usergroup id 86 | try // try to make a second request 87 | { 88 | cout << "checking hwid..." << endl; 89 | 90 | hwid = to_string(utils->GetHWID()); 91 | hwidtoken = "1337"; 92 | 93 | Request requesthwid("http://xenforo.gandaa.lv/hwid.php?username=" + username + "&token=" + hwidtoken + "&hwid=" + hwid); // we will use now the hwid.php for the new request 94 | 95 | const http::Response getResponseHWID = requesthwid.send("GET"); // for the hwid request we only need a simple 'GET' request 96 | respondedhwid = string(getResponseHWID.body.begin(), getResponseHWID.body.end()); 97 | 98 | if (respondedhwid == "new") // if there is no hwid set 99 | { 100 | cout << "no stored hwid found! setting new one." << endl; 101 | utils->StoreLogin(username, password, hwid, appdatafile); // storing the logindata for later 102 | // do cheat stuff 103 | } 104 | else if (respondedhwid == "accepted") // if hwid check was successful 105 | { 106 | cout << "hwid check was successful, welcome back " + username + " :)" << endl; 107 | utils->StoreLogin(username, password, hwid, appdatafile); // storing the logindata for later 108 | // do cheat stuff 109 | } 110 | else if (respondedhwid == "declined") 111 | { 112 | cout << "unknown hwid detected! please request a reset" << endl; 113 | // don't allow to continue / exit the programm 114 | } 115 | else 116 | { 117 | cout << "some unknown error occured, please check back later :(" << endl; 118 | // some other error within the system 119 | } 120 | } 121 | catch (const exception & e) // catch any errors 122 | { 123 | cerr << "hwid request failed, error: " << e.what() << endl; // print the errors 124 | 125 | system("pause"); // wait for user input 126 | 127 | return EXIT_FAILURE; //exit programm with status code 1 128 | } 129 | } 130 | else // no subscription - wrong usergroup 131 | { 132 | cout << "no active sub found" << endl; 133 | system("pause"); 134 | return EXIT_FAILURE; 135 | } 136 | } 137 | } 138 | } 139 | } 140 | else 141 | { 142 | cout << "login was not successful :(" << endl; // invalid username+password combination 143 | } 144 | 145 | system("pause"); // wait for user input 146 | } 147 | catch (const exception & e) // catch any errors 148 | { 149 | cerr << "Request failed, error: " << e.what() << endl; // print the errors 150 | 151 | system("pause"); // wait for user input 152 | 153 | return EXIT_FAILURE; //exit programm with status code 1 154 | } 155 | 156 | return EXIT_SUCCESS; //exit programm with status code 0 157 | } -------------------------------------------------------------------------------- /rapidjson/allocators.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ALLOCATORS_H_ 16 | #define RAPIDJSON_ALLOCATORS_H_ 17 | 18 | #include "rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | 22 | /////////////////////////////////////////////////////////////////////////////// 23 | // Allocator 24 | 25 | /*! \class rapidjson::Allocator 26 | \brief Concept for allocating, resizing and freeing memory block. 27 | 28 | Note that Malloc() and Realloc() are non-static but Free() is static. 29 | 30 | So if an allocator need to support Free(), it needs to put its pointer in 31 | the header of memory block. 32 | 33 | \code 34 | concept Allocator { 35 | static const bool kNeedFree; //!< Whether this allocator needs to call Free(). 36 | 37 | // Allocate a memory block. 38 | // \param size of the memory block in bytes. 39 | // \returns pointer to the memory block. 40 | void* Malloc(size_t size); 41 | 42 | // Resize a memory block. 43 | // \param originalPtr The pointer to current memory block. Null pointer is permitted. 44 | // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) 45 | // \param newSize the new size in bytes. 46 | void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); 47 | 48 | // Free a memory block. 49 | // \param pointer to the memory block. Null pointer is permitted. 50 | static void Free(void *ptr); 51 | }; 52 | \endcode 53 | */ 54 | 55 | /////////////////////////////////////////////////////////////////////////////// 56 | // CrtAllocator 57 | 58 | //! C-runtime library allocator. 59 | /*! This class is just wrapper for standard C library memory routines. 60 | \note implements Allocator concept 61 | */ 62 | class CrtAllocator { 63 | public: 64 | static const bool kNeedFree = true; 65 | void* Malloc(size_t size) { 66 | if (size) // behavior of malloc(0) is implementation defined. 67 | return std::malloc(size); 68 | else 69 | return NULL; // standardize to returning NULL. 70 | } 71 | void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { 72 | (void)originalSize; 73 | if (newSize == 0) { 74 | std::free(originalPtr); 75 | return NULL; 76 | } 77 | return std::realloc(originalPtr, newSize); 78 | } 79 | static void Free(void *ptr) { std::free(ptr); } 80 | }; 81 | 82 | /////////////////////////////////////////////////////////////////////////////// 83 | // MemoryPoolAllocator 84 | 85 | //! Default memory allocator used by the parser and DOM. 86 | /*! This allocator allocate memory blocks from pre-allocated memory chunks. 87 | 88 | It does not free memory blocks. And Realloc() only allocate new memory. 89 | 90 | The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. 91 | 92 | User may also supply a buffer as the first chunk. 93 | 94 | If the user-buffer is full then additional chunks are allocated by BaseAllocator. 95 | 96 | The user-buffer is not deallocated by this allocator. 97 | 98 | \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. 99 | \note implements Allocator concept 100 | */ 101 | template 102 | class MemoryPoolAllocator { 103 | public: 104 | static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) 105 | 106 | //! Constructor with chunkSize. 107 | /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. 108 | \param baseAllocator The allocator for allocating memory chunks. 109 | */ 110 | MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : 111 | chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) 112 | { 113 | } 114 | 115 | //! Constructor with user-supplied buffer. 116 | /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. 117 | 118 | The user buffer will not be deallocated when this allocator is destructed. 119 | 120 | \param buffer User supplied buffer. 121 | \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). 122 | \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. 123 | \param baseAllocator The allocator for allocating memory chunks. 124 | */ 125 | MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : 126 | chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) 127 | { 128 | RAPIDJSON_ASSERT(buffer != 0); 129 | RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); 130 | chunkHead_ = reinterpret_cast(buffer); 131 | chunkHead_->capacity = size - sizeof(ChunkHeader); 132 | chunkHead_->size = 0; 133 | chunkHead_->next = 0; 134 | } 135 | 136 | //! Destructor. 137 | /*! This deallocates all memory chunks, excluding the user-supplied buffer. 138 | */ 139 | ~MemoryPoolAllocator() { 140 | Clear(); 141 | RAPIDJSON_DELETE(ownBaseAllocator_); 142 | } 143 | 144 | //! Deallocates all memory chunks, excluding the user-supplied buffer. 145 | void Clear() { 146 | while (chunkHead_ && chunkHead_ != userBuffer_) { 147 | ChunkHeader* next = chunkHead_->next; 148 | baseAllocator_->Free(chunkHead_); 149 | chunkHead_ = next; 150 | } 151 | if (chunkHead_ && chunkHead_ == userBuffer_) 152 | chunkHead_->size = 0; // Clear user buffer 153 | } 154 | 155 | //! Computes the total capacity of allocated memory chunks. 156 | /*! \return total capacity in bytes. 157 | */ 158 | size_t Capacity() const { 159 | size_t capacity = 0; 160 | for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) 161 | capacity += c->capacity; 162 | return capacity; 163 | } 164 | 165 | //! Computes the memory blocks allocated. 166 | /*! \return total used bytes. 167 | */ 168 | size_t Size() const { 169 | size_t size = 0; 170 | for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) 171 | size += c->size; 172 | return size; 173 | } 174 | 175 | //! Allocates a memory block. (concept Allocator) 176 | void* Malloc(size_t size) { 177 | if (!size) 178 | return NULL; 179 | 180 | size = RAPIDJSON_ALIGN(size); 181 | if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity) 182 | if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size)) 183 | return NULL; 184 | 185 | void *buffer = reinterpret_cast(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size; 186 | chunkHead_->size += size; 187 | return buffer; 188 | } 189 | 190 | //! Resizes a memory block (concept Allocator) 191 | void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { 192 | if (originalPtr == 0) 193 | return Malloc(newSize); 194 | 195 | if (newSize == 0) 196 | return NULL; 197 | 198 | originalSize = RAPIDJSON_ALIGN(originalSize); 199 | newSize = RAPIDJSON_ALIGN(newSize); 200 | 201 | // Do not shrink if new size is smaller than original 202 | if (originalSize >= newSize) 203 | return originalPtr; 204 | 205 | // Simply expand it if it is the last allocation and there is sufficient space 206 | if (originalPtr == reinterpret_cast(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) { 207 | size_t increment = static_cast(newSize - originalSize); 208 | if (chunkHead_->size + increment <= chunkHead_->capacity) { 209 | chunkHead_->size += increment; 210 | return originalPtr; 211 | } 212 | } 213 | 214 | // Realloc process: allocate and copy memory, do not free original buffer. 215 | if (void* newBuffer = Malloc(newSize)) { 216 | if (originalSize) 217 | std::memcpy(newBuffer, originalPtr, originalSize); 218 | return newBuffer; 219 | } 220 | else 221 | return NULL; 222 | } 223 | 224 | //! Frees a memory block (concept Allocator) 225 | static void Free(void *ptr) { (void)ptr; } // Do nothing 226 | 227 | private: 228 | //! Copy constructor is not permitted. 229 | MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */; 230 | //! Copy assignment operator is not permitted. 231 | MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */; 232 | 233 | //! Creates a new chunk. 234 | /*! \param capacity Capacity of the chunk in bytes. 235 | \return true if success. 236 | */ 237 | bool AddChunk(size_t capacity) { 238 | if (!baseAllocator_) 239 | ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)(); 240 | if (ChunkHeader* chunk = reinterpret_cast(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) { 241 | chunk->capacity = capacity; 242 | chunk->size = 0; 243 | chunk->next = chunkHead_; 244 | chunkHead_ = chunk; 245 | return true; 246 | } 247 | else 248 | return false; 249 | } 250 | 251 | static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity. 252 | 253 | //! Chunk header for perpending to each chunk. 254 | /*! Chunks are stored as a singly linked list. 255 | */ 256 | struct ChunkHeader { 257 | size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). 258 | size_t size; //!< Current size of allocated memory in bytes. 259 | ChunkHeader *next; //!< Next chunk in the linked list. 260 | }; 261 | 262 | ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation. 263 | size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. 264 | void *userBuffer_; //!< User supplied buffer. 265 | BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. 266 | BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object. 267 | }; 268 | 269 | RAPIDJSON_NAMESPACE_END 270 | 271 | #endif // RAPIDJSON_ENCODINGS_H_ 272 | -------------------------------------------------------------------------------- /rapidjson/encodedstream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ENCODEDSTREAM_H_ 16 | #define RAPIDJSON_ENCODEDSTREAM_H_ 17 | 18 | #include "stream.h" 19 | #include "memorystream.h" 20 | 21 | #ifdef __GNUC__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(effc++) 24 | #endif 25 | 26 | #ifdef __clang__ 27 | RAPIDJSON_DIAG_PUSH 28 | RAPIDJSON_DIAG_OFF(padded) 29 | #endif 30 | 31 | RAPIDJSON_NAMESPACE_BEGIN 32 | 33 | //! Input byte stream wrapper with a statically bound encoding. 34 | /*! 35 | \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. 36 | \tparam InputByteStream Type of input byte stream. For example, FileReadStream. 37 | */ 38 | template 39 | class EncodedInputStream { 40 | RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); 41 | public: 42 | typedef typename Encoding::Ch Ch; 43 | 44 | EncodedInputStream(InputByteStream& is) : is_(is) { 45 | current_ = Encoding::TakeBOM(is_); 46 | } 47 | 48 | Ch Peek() const { return current_; } 49 | Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; } 50 | size_t Tell() const { return is_.Tell(); } 51 | 52 | // Not implemented 53 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 54 | void Flush() { RAPIDJSON_ASSERT(false); } 55 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 56 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 57 | 58 | private: 59 | EncodedInputStream(const EncodedInputStream&); 60 | EncodedInputStream& operator=(const EncodedInputStream&); 61 | 62 | InputByteStream& is_; 63 | Ch current_; 64 | }; 65 | 66 | //! Specialized for UTF8 MemoryStream. 67 | template <> 68 | class EncodedInputStream, MemoryStream> { 69 | public: 70 | typedef UTF8<>::Ch Ch; 71 | 72 | EncodedInputStream(MemoryStream& is) : is_(is) { 73 | if (static_cast(is_.Peek()) == 0xEFu) is_.Take(); 74 | if (static_cast(is_.Peek()) == 0xBBu) is_.Take(); 75 | if (static_cast(is_.Peek()) == 0xBFu) is_.Take(); 76 | } 77 | Ch Peek() const { return is_.Peek(); } 78 | Ch Take() { return is_.Take(); } 79 | size_t Tell() const { return is_.Tell(); } 80 | 81 | // Not implemented 82 | void Put(Ch) {} 83 | void Flush() {} 84 | Ch* PutBegin() { return 0; } 85 | size_t PutEnd(Ch*) { return 0; } 86 | 87 | MemoryStream& is_; 88 | 89 | private: 90 | EncodedInputStream(const EncodedInputStream&); 91 | EncodedInputStream& operator=(const EncodedInputStream&); 92 | }; 93 | 94 | //! Output byte stream wrapper with statically bound encoding. 95 | /*! 96 | \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. 97 | \tparam OutputByteStream Type of input byte stream. For example, FileWriteStream. 98 | */ 99 | template 100 | class EncodedOutputStream { 101 | RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); 102 | public: 103 | typedef typename Encoding::Ch Ch; 104 | 105 | EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { 106 | if (putBOM) 107 | Encoding::PutBOM(os_); 108 | } 109 | 110 | void Put(Ch c) { Encoding::Put(os_, c); } 111 | void Flush() { os_.Flush(); } 112 | 113 | // Not implemented 114 | Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} 115 | Ch Take() { RAPIDJSON_ASSERT(false); return 0;} 116 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 117 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 118 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 119 | 120 | private: 121 | EncodedOutputStream(const EncodedOutputStream&); 122 | EncodedOutputStream& operator=(const EncodedOutputStream&); 123 | 124 | OutputByteStream& os_; 125 | }; 126 | 127 | #define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x 128 | 129 | //! Input stream wrapper with dynamically bound encoding and automatic encoding detection. 130 | /*! 131 | \tparam CharType Type of character for reading. 132 | \tparam InputByteStream type of input byte stream to be wrapped. 133 | */ 134 | template 135 | class AutoUTFInputStream { 136 | RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); 137 | public: 138 | typedef CharType Ch; 139 | 140 | //! Constructor. 141 | /*! 142 | \param is input stream to be wrapped. 143 | \param type UTF encoding type if it is not detected from the stream. 144 | */ 145 | AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) { 146 | RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); 147 | DetectType(); 148 | static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) }; 149 | takeFunc_ = f[type_]; 150 | current_ = takeFunc_(*is_); 151 | } 152 | 153 | UTFType GetType() const { return type_; } 154 | bool HasBOM() const { return hasBOM_; } 155 | 156 | Ch Peek() const { return current_; } 157 | Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; } 158 | size_t Tell() const { return is_->Tell(); } 159 | 160 | // Not implemented 161 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 162 | void Flush() { RAPIDJSON_ASSERT(false); } 163 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 164 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 165 | 166 | private: 167 | AutoUTFInputStream(const AutoUTFInputStream&); 168 | AutoUTFInputStream& operator=(const AutoUTFInputStream&); 169 | 170 | // Detect encoding type with BOM or RFC 4627 171 | void DetectType() { 172 | // BOM (Byte Order Mark): 173 | // 00 00 FE FF UTF-32BE 174 | // FF FE 00 00 UTF-32LE 175 | // FE FF UTF-16BE 176 | // FF FE UTF-16LE 177 | // EF BB BF UTF-8 178 | 179 | const unsigned char* c = reinterpret_cast(is_->Peek4()); 180 | if (!c) 181 | return; 182 | 183 | unsigned bom = static_cast(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24)); 184 | hasBOM_ = false; 185 | if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } 186 | else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } 187 | else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); } 188 | else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); } 189 | else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); } 190 | 191 | // RFC 4627: Section 3 192 | // "Since the first two characters of a JSON text will always be ASCII 193 | // characters [RFC0020], it is possible to determine whether an octet 194 | // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking 195 | // at the pattern of nulls in the first four octets." 196 | // 00 00 00 xx UTF-32BE 197 | // 00 xx 00 xx UTF-16BE 198 | // xx 00 00 00 UTF-32LE 199 | // xx 00 xx 00 UTF-16LE 200 | // xx xx xx xx UTF-8 201 | 202 | if (!hasBOM_) { 203 | int pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); 204 | switch (pattern) { 205 | case 0x08: type_ = kUTF32BE; break; 206 | case 0x0A: type_ = kUTF16BE; break; 207 | case 0x01: type_ = kUTF32LE; break; 208 | case 0x05: type_ = kUTF16LE; break; 209 | case 0x0F: type_ = kUTF8; break; 210 | default: break; // Use type defined by user. 211 | } 212 | } 213 | 214 | // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. 215 | if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); 216 | if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); 217 | } 218 | 219 | typedef Ch (*TakeFunc)(InputByteStream& is); 220 | InputByteStream* is_; 221 | UTFType type_; 222 | Ch current_; 223 | TakeFunc takeFunc_; 224 | bool hasBOM_; 225 | }; 226 | 227 | //! Output stream wrapper with dynamically bound encoding and automatic encoding detection. 228 | /*! 229 | \tparam CharType Type of character for writing. 230 | \tparam OutputByteStream type of output byte stream to be wrapped. 231 | */ 232 | template 233 | class AutoUTFOutputStream { 234 | RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); 235 | public: 236 | typedef CharType Ch; 237 | 238 | //! Constructor. 239 | /*! 240 | \param os output stream to be wrapped. 241 | \param type UTF encoding type. 242 | \param putBOM Whether to write BOM at the beginning of the stream. 243 | */ 244 | AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) { 245 | RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); 246 | 247 | // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. 248 | if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); 249 | if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); 250 | 251 | static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) }; 252 | putFunc_ = f[type_]; 253 | 254 | if (putBOM) 255 | PutBOM(); 256 | } 257 | 258 | UTFType GetType() const { return type_; } 259 | 260 | void Put(Ch c) { putFunc_(*os_, c); } 261 | void Flush() { os_->Flush(); } 262 | 263 | // Not implemented 264 | Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} 265 | Ch Take() { RAPIDJSON_ASSERT(false); return 0;} 266 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 267 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 268 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 269 | 270 | private: 271 | AutoUTFOutputStream(const AutoUTFOutputStream&); 272 | AutoUTFOutputStream& operator=(const AutoUTFOutputStream&); 273 | 274 | void PutBOM() { 275 | typedef void (*PutBOMFunc)(OutputByteStream&); 276 | static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) }; 277 | f[type_](*os_); 278 | } 279 | 280 | typedef void (*PutFunc)(OutputByteStream&, Ch); 281 | 282 | OutputByteStream* os_; 283 | UTFType type_; 284 | PutFunc putFunc_; 285 | }; 286 | 287 | #undef RAPIDJSON_ENCODINGS_FUNC 288 | 289 | RAPIDJSON_NAMESPACE_END 290 | 291 | #ifdef __clang__ 292 | RAPIDJSON_DIAG_POP 293 | #endif 294 | 295 | #ifdef __GNUC__ 296 | RAPIDJSON_DIAG_POP 297 | #endif 298 | 299 | #endif // RAPIDJSON_FILESTREAM_H_ 300 | -------------------------------------------------------------------------------- /rapidjson/error/en.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ERROR_EN_H_ 16 | #define RAPIDJSON_ERROR_EN_H_ 17 | 18 | #include "error.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(switch-enum) 23 | RAPIDJSON_DIAG_OFF(covered-switch-default) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Maps error code of parsing into error message. 29 | /*! 30 | \ingroup RAPIDJSON_ERRORS 31 | \param parseErrorCode Error code obtained in parsing. 32 | \return the error message. 33 | \note User can make a copy of this function for localization. 34 | Using switch-case is safer for future modification of error codes. 35 | */ 36 | inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { 37 | switch (parseErrorCode) { 38 | case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); 39 | 40 | case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); 41 | case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values."); 42 | 43 | case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); 44 | 45 | case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); 46 | case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); 47 | case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); 48 | 49 | case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); 50 | 51 | case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); 52 | case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); 53 | case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); 54 | case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); 55 | case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); 56 | 57 | case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); 58 | case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); 59 | case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); 60 | 61 | case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); 62 | case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); 63 | 64 | default: return RAPIDJSON_ERROR_STRING("Unknown error."); 65 | } 66 | } 67 | 68 | RAPIDJSON_NAMESPACE_END 69 | 70 | #ifdef __clang__ 71 | RAPIDJSON_DIAG_POP 72 | #endif 73 | 74 | #endif // RAPIDJSON_ERROR_EN_H_ 75 | -------------------------------------------------------------------------------- /rapidjson/error/error.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ERROR_ERROR_H_ 16 | #define RAPIDJSON_ERROR_ERROR_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(padded) 23 | #endif 24 | 25 | /*! \file error.h */ 26 | 27 | /*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ 28 | 29 | /////////////////////////////////////////////////////////////////////////////// 30 | // RAPIDJSON_ERROR_CHARTYPE 31 | 32 | //! Character type of error messages. 33 | /*! \ingroup RAPIDJSON_ERRORS 34 | The default character type is \c char. 35 | On Windows, user can define this macro as \c TCHAR for supporting both 36 | unicode/non-unicode settings. 37 | */ 38 | #ifndef RAPIDJSON_ERROR_CHARTYPE 39 | #define RAPIDJSON_ERROR_CHARTYPE char 40 | #endif 41 | 42 | /////////////////////////////////////////////////////////////////////////////// 43 | // RAPIDJSON_ERROR_STRING 44 | 45 | //! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[]. 46 | /*! \ingroup RAPIDJSON_ERRORS 47 | By default this conversion macro does nothing. 48 | On Windows, user can define this macro as \c _T(x) for supporting both 49 | unicode/non-unicode settings. 50 | */ 51 | #ifndef RAPIDJSON_ERROR_STRING 52 | #define RAPIDJSON_ERROR_STRING(x) x 53 | #endif 54 | 55 | RAPIDJSON_NAMESPACE_BEGIN 56 | 57 | /////////////////////////////////////////////////////////////////////////////// 58 | // ParseErrorCode 59 | 60 | //! Error code of parsing. 61 | /*! \ingroup RAPIDJSON_ERRORS 62 | \see GenericReader::Parse, GenericReader::GetParseErrorCode 63 | */ 64 | enum ParseErrorCode { 65 | kParseErrorNone = 0, //!< No error. 66 | 67 | kParseErrorDocumentEmpty, //!< The document is empty. 68 | kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. 69 | 70 | kParseErrorValueInvalid, //!< Invalid value. 71 | 72 | kParseErrorObjectMissName, //!< Missing a name for object member. 73 | kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. 74 | kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. 75 | 76 | kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. 77 | 78 | kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. 79 | kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. 80 | kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. 81 | kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. 82 | kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. 83 | 84 | kParseErrorNumberTooBig, //!< Number too big to be stored in double. 85 | kParseErrorNumberMissFraction, //!< Miss fraction part in number. 86 | kParseErrorNumberMissExponent, //!< Miss exponent in number. 87 | 88 | kParseErrorTermination, //!< Parsing was terminated. 89 | kParseErrorUnspecificSyntaxError //!< Unspecific syntax error. 90 | }; 91 | 92 | //! Result of parsing (wraps ParseErrorCode) 93 | /*! 94 | \ingroup RAPIDJSON_ERRORS 95 | \code 96 | Document doc; 97 | ParseResult ok = doc.Parse("[42]"); 98 | if (!ok) { 99 | fprintf(stderr, "JSON parse error: %s (%u)", 100 | GetParseError_En(ok.Code()), ok.Offset()); 101 | exit(EXIT_FAILURE); 102 | } 103 | \endcode 104 | \see GenericReader::Parse, GenericDocument::Parse 105 | */ 106 | struct ParseResult { 107 | public: 108 | //! Default constructor, no error. 109 | ParseResult() : code_(kParseErrorNone), offset_(0) {} 110 | //! Constructor to set an error. 111 | ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} 112 | 113 | //! Get the error code. 114 | ParseErrorCode Code() const { return code_; } 115 | //! Get the error offset, if \ref IsError(), 0 otherwise. 116 | size_t Offset() const { return offset_; } 117 | 118 | //! Conversion to \c bool, returns \c true, iff !\ref IsError(). 119 | operator bool() const { return !IsError(); } 120 | //! Whether the result is an error. 121 | bool IsError() const { return code_ != kParseErrorNone; } 122 | 123 | bool operator==(const ParseResult& that) const { return code_ == that.code_; } 124 | bool operator==(ParseErrorCode code) const { return code_ == code; } 125 | friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } 126 | 127 | //! Reset error code. 128 | void Clear() { Set(kParseErrorNone); } 129 | //! Update error code and offset. 130 | void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } 131 | 132 | private: 133 | ParseErrorCode code_; 134 | size_t offset_; 135 | }; 136 | 137 | //! Function pointer type of GetParseError(). 138 | /*! \ingroup RAPIDJSON_ERRORS 139 | 140 | This is the prototype for \c GetParseError_X(), where \c X is a locale. 141 | User can dynamically change locale in runtime, e.g.: 142 | \code 143 | GetParseErrorFunc GetParseError = GetParseError_En; // or whatever 144 | const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); 145 | \endcode 146 | */ 147 | typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); 148 | 149 | RAPIDJSON_NAMESPACE_END 150 | 151 | #ifdef __clang__ 152 | RAPIDJSON_DIAG_POP 153 | #endif 154 | 155 | #endif // RAPIDJSON_ERROR_ERROR_H_ 156 | -------------------------------------------------------------------------------- /rapidjson/filereadstream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FILEREADSTREAM_H_ 16 | #define RAPIDJSON_FILEREADSTREAM_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | RAPIDJSON_DIAG_OFF(unreachable-code) 25 | RAPIDJSON_DIAG_OFF(missing-noreturn) 26 | #endif 27 | 28 | RAPIDJSON_NAMESPACE_BEGIN 29 | 30 | //! File byte stream for input using fread(). 31 | /*! 32 | \note implements Stream concept 33 | */ 34 | class FileReadStream { 35 | public: 36 | typedef char Ch; //!< Character type (byte). 37 | 38 | //! Constructor. 39 | /*! 40 | \param fp File pointer opened for read. 41 | \param buffer user-supplied buffer. 42 | \param bufferSize size of buffer in bytes. Must >=4 bytes. 43 | */ 44 | FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { 45 | RAPIDJSON_ASSERT(fp_ != 0); 46 | RAPIDJSON_ASSERT(bufferSize >= 4); 47 | Read(); 48 | } 49 | 50 | Ch Peek() const { return *current_; } 51 | Ch Take() { Ch c = *current_; Read(); return c; } 52 | size_t Tell() const { return count_ + static_cast(current_ - buffer_); } 53 | 54 | // Not implemented 55 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 56 | void Flush() { RAPIDJSON_ASSERT(false); } 57 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 58 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 59 | 60 | // For encoding detection only. 61 | const Ch* Peek4() const { 62 | return (current_ + 4 <= bufferLast_) ? current_ : 0; 63 | } 64 | 65 | private: 66 | void Read() { 67 | if (current_ < bufferLast_) 68 | ++current_; 69 | else if (!eof_) { 70 | count_ += readCount_; 71 | readCount_ = fread(buffer_, 1, bufferSize_, fp_); 72 | bufferLast_ = buffer_ + readCount_ - 1; 73 | current_ = buffer_; 74 | 75 | if (readCount_ < bufferSize_) { 76 | buffer_[readCount_] = '\0'; 77 | ++bufferLast_; 78 | eof_ = true; 79 | } 80 | } 81 | } 82 | 83 | std::FILE* fp_; 84 | Ch *buffer_; 85 | size_t bufferSize_; 86 | Ch *bufferLast_; 87 | Ch *current_; 88 | size_t readCount_; 89 | size_t count_; //!< Number of characters read 90 | bool eof_; 91 | }; 92 | 93 | RAPIDJSON_NAMESPACE_END 94 | 95 | #ifdef __clang__ 96 | RAPIDJSON_DIAG_POP 97 | #endif 98 | 99 | #endif // RAPIDJSON_FILESTREAM_H_ 100 | -------------------------------------------------------------------------------- /rapidjson/filewritestream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FILEWRITESTREAM_H_ 16 | #define RAPIDJSON_FILEWRITESTREAM_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(unreachable-code) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Wrapper of C file stream for input using fread(). 29 | /*! 30 | \note implements Stream concept 31 | */ 32 | class FileWriteStream { 33 | public: 34 | typedef char Ch; //!< Character type. Only support char. 35 | 36 | FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { 37 | RAPIDJSON_ASSERT(fp_ != 0); 38 | } 39 | 40 | void Put(char c) { 41 | if (current_ >= bufferEnd_) 42 | Flush(); 43 | 44 | *current_++ = c; 45 | } 46 | 47 | void PutN(char c, size_t n) { 48 | size_t avail = static_cast(bufferEnd_ - current_); 49 | while (n > avail) { 50 | std::memset(current_, c, avail); 51 | current_ += avail; 52 | Flush(); 53 | n -= avail; 54 | avail = static_cast(bufferEnd_ - current_); 55 | } 56 | 57 | if (n > 0) { 58 | std::memset(current_, c, n); 59 | current_ += n; 60 | } 61 | } 62 | 63 | void Flush() { 64 | if (current_ != buffer_) { 65 | size_t result = fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_); 66 | if (result < static_cast(current_ - buffer_)) { 67 | // failure deliberately ignored at this time 68 | // added to avoid warn_unused_result build errors 69 | } 70 | current_ = buffer_; 71 | } 72 | } 73 | 74 | // Not implemented 75 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; } 76 | char Take() { RAPIDJSON_ASSERT(false); return 0; } 77 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 78 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 79 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 80 | 81 | private: 82 | // Prohibit copy constructor & assignment operator. 83 | FileWriteStream(const FileWriteStream&); 84 | FileWriteStream& operator=(const FileWriteStream&); 85 | 86 | std::FILE* fp_; 87 | char *buffer_; 88 | char *bufferEnd_; 89 | char *current_; 90 | }; 91 | 92 | //! Implement specialized version of PutN() with memset() for better performance. 93 | template<> 94 | inline void PutN(FileWriteStream& stream, char c, size_t n) { 95 | stream.PutN(c, n); 96 | } 97 | 98 | RAPIDJSON_NAMESPACE_END 99 | 100 | #ifdef __clang__ 101 | RAPIDJSON_DIAG_POP 102 | #endif 103 | 104 | #endif // RAPIDJSON_FILESTREAM_H_ 105 | -------------------------------------------------------------------------------- /rapidjson/fwd.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FWD_H_ 16 | #define RAPIDJSON_FWD_H_ 17 | 18 | #include "rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | 22 | // encodings.h 23 | 24 | template struct UTF8; 25 | template struct UTF16; 26 | template struct UTF16BE; 27 | template struct UTF16LE; 28 | template struct UTF32; 29 | template struct UTF32BE; 30 | template struct UTF32LE; 31 | template struct ASCII; 32 | template struct AutoUTF; 33 | 34 | template 35 | struct Transcoder; 36 | 37 | // allocators.h 38 | 39 | class CrtAllocator; 40 | 41 | template 42 | class MemoryPoolAllocator; 43 | 44 | // stream.h 45 | 46 | template 47 | struct GenericStringStream; 48 | 49 | typedef GenericStringStream > StringStream; 50 | 51 | template 52 | struct GenericInsituStringStream; 53 | 54 | typedef GenericInsituStringStream > InsituStringStream; 55 | 56 | // stringbuffer.h 57 | 58 | template 59 | class GenericStringBuffer; 60 | 61 | typedef GenericStringBuffer, CrtAllocator> StringBuffer; 62 | 63 | // filereadstream.h 64 | 65 | class FileReadStream; 66 | 67 | // filewritestream.h 68 | 69 | class FileWriteStream; 70 | 71 | // memorybuffer.h 72 | 73 | template 74 | struct GenericMemoryBuffer; 75 | 76 | typedef GenericMemoryBuffer MemoryBuffer; 77 | 78 | // memorystream.h 79 | 80 | struct MemoryStream; 81 | 82 | // reader.h 83 | 84 | template 85 | struct BaseReaderHandler; 86 | 87 | template 88 | class GenericReader; 89 | 90 | typedef GenericReader, UTF8, CrtAllocator> Reader; 91 | 92 | // writer.h 93 | 94 | template 95 | class Writer; 96 | 97 | // prettywriter.h 98 | 99 | template 100 | class PrettyWriter; 101 | 102 | // document.h 103 | 104 | template 105 | struct GenericMember; 106 | 107 | template 108 | class GenericMemberIterator; 109 | 110 | template 111 | struct GenericStringRef; 112 | 113 | template 114 | class GenericValue; 115 | 116 | typedef GenericValue, MemoryPoolAllocator > Value; 117 | 118 | template 119 | class GenericDocument; 120 | 121 | typedef GenericDocument, MemoryPoolAllocator, CrtAllocator> Document; 122 | 123 | // pointer.h 124 | 125 | template 126 | class GenericPointer; 127 | 128 | typedef GenericPointer Pointer; 129 | 130 | // schema.h 131 | 132 | template 133 | class IGenericRemoteSchemaDocumentProvider; 134 | 135 | template 136 | class GenericSchemaDocument; 137 | 138 | typedef GenericSchemaDocument SchemaDocument; 139 | typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; 140 | 141 | template < 142 | typename SchemaDocumentType, 143 | typename OutputHandler, 144 | typename StateAllocator> 145 | class GenericSchemaValidator; 146 | 147 | typedef GenericSchemaValidator, void>, CrtAllocator> SchemaValidator; 148 | 149 | RAPIDJSON_NAMESPACE_END 150 | 151 | #endif // RAPIDJSON_RAPIDJSONFWD_H_ 152 | -------------------------------------------------------------------------------- /rapidjson/internal/biginteger.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_BIGINTEGER_H_ 16 | #define RAPIDJSON_BIGINTEGER_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #if defined(_MSC_VER) && defined(_M_AMD64) 21 | #include // for _umul128 22 | #pragma intrinsic(_umul128) 23 | #endif 24 | 25 | RAPIDJSON_NAMESPACE_BEGIN 26 | namespace internal { 27 | 28 | class BigInteger { 29 | public: 30 | typedef uint64_t Type; 31 | 32 | BigInteger(const BigInteger& rhs) : count_(rhs.count_) { 33 | std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); 34 | } 35 | 36 | explicit BigInteger(uint64_t u) : count_(1) { 37 | digits_[0] = u; 38 | } 39 | 40 | BigInteger(const char* decimals, size_t length) : count_(1) { 41 | RAPIDJSON_ASSERT(length > 0); 42 | digits_[0] = 0; 43 | size_t i = 0; 44 | const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19 45 | while (length >= kMaxDigitPerIteration) { 46 | AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration); 47 | length -= kMaxDigitPerIteration; 48 | i += kMaxDigitPerIteration; 49 | } 50 | 51 | if (length > 0) 52 | AppendDecimal64(decimals + i, decimals + i + length); 53 | } 54 | 55 | BigInteger& operator=(const BigInteger &rhs) 56 | { 57 | if (this != &rhs) { 58 | count_ = rhs.count_; 59 | std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); 60 | } 61 | return *this; 62 | } 63 | 64 | BigInteger& operator=(uint64_t u) { 65 | digits_[0] = u; 66 | count_ = 1; 67 | return *this; 68 | } 69 | 70 | BigInteger& operator+=(uint64_t u) { 71 | Type backup = digits_[0]; 72 | digits_[0] += u; 73 | for (size_t i = 0; i < count_ - 1; i++) { 74 | if (digits_[i] >= backup) 75 | return *this; // no carry 76 | backup = digits_[i + 1]; 77 | digits_[i + 1] += 1; 78 | } 79 | 80 | // Last carry 81 | if (digits_[count_ - 1] < backup) 82 | PushBack(1); 83 | 84 | return *this; 85 | } 86 | 87 | BigInteger& operator*=(uint64_t u) { 88 | if (u == 0) return *this = 0; 89 | if (u == 1) return *this; 90 | if (*this == 1) return *this = u; 91 | 92 | uint64_t k = 0; 93 | for (size_t i = 0; i < count_; i++) { 94 | uint64_t hi; 95 | digits_[i] = MulAdd64(digits_[i], u, k, &hi); 96 | k = hi; 97 | } 98 | 99 | if (k > 0) 100 | PushBack(k); 101 | 102 | return *this; 103 | } 104 | 105 | BigInteger& operator*=(uint32_t u) { 106 | if (u == 0) return *this = 0; 107 | if (u == 1) return *this; 108 | if (*this == 1) return *this = u; 109 | 110 | uint64_t k = 0; 111 | for (size_t i = 0; i < count_; i++) { 112 | const uint64_t c = digits_[i] >> 32; 113 | const uint64_t d = digits_[i] & 0xFFFFFFFF; 114 | const uint64_t uc = u * c; 115 | const uint64_t ud = u * d; 116 | const uint64_t p0 = ud + k; 117 | const uint64_t p1 = uc + (p0 >> 32); 118 | digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32); 119 | k = p1 >> 32; 120 | } 121 | 122 | if (k > 0) 123 | PushBack(k); 124 | 125 | return *this; 126 | } 127 | 128 | BigInteger& operator<<=(size_t shift) { 129 | if (IsZero() || shift == 0) return *this; 130 | 131 | size_t offset = shift / kTypeBit; 132 | size_t interShift = shift % kTypeBit; 133 | RAPIDJSON_ASSERT(count_ + offset <= kCapacity); 134 | 135 | if (interShift == 0) { 136 | std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type)); 137 | count_ += offset; 138 | } 139 | else { 140 | digits_[count_] = 0; 141 | for (size_t i = count_; i > 0; i--) 142 | digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift)); 143 | digits_[offset] = digits_[0] << interShift; 144 | count_ += offset; 145 | if (digits_[count_]) 146 | count_++; 147 | } 148 | 149 | std::memset(digits_, 0, offset * sizeof(Type)); 150 | 151 | return *this; 152 | } 153 | 154 | bool operator==(const BigInteger& rhs) const { 155 | return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0; 156 | } 157 | 158 | bool operator==(const Type rhs) const { 159 | return count_ == 1 && digits_[0] == rhs; 160 | } 161 | 162 | BigInteger& MultiplyPow5(unsigned exp) { 163 | static const uint32_t kPow5[12] = { 164 | 5, 165 | 5 * 5, 166 | 5 * 5 * 5, 167 | 5 * 5 * 5 * 5, 168 | 5 * 5 * 5 * 5 * 5, 169 | 5 * 5 * 5 * 5 * 5 * 5, 170 | 5 * 5 * 5 * 5 * 5 * 5 * 5, 171 | 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, 172 | 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, 173 | 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, 174 | 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, 175 | 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 176 | }; 177 | if (exp == 0) return *this; 178 | for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27 179 | for (; exp >= 13; exp -= 13) *this *= static_cast(1220703125u); // 5^13 180 | if (exp > 0) *this *= kPow5[exp - 1]; 181 | return *this; 182 | } 183 | 184 | // Compute absolute difference of this and rhs. 185 | // Assume this != rhs 186 | bool Difference(const BigInteger& rhs, BigInteger* out) const { 187 | int cmp = Compare(rhs); 188 | RAPIDJSON_ASSERT(cmp != 0); 189 | const BigInteger *a, *b; // Makes a > b 190 | bool ret; 191 | if (cmp < 0) { a = &rhs; b = this; ret = true; } 192 | else { a = this; b = &rhs; ret = false; } 193 | 194 | Type borrow = 0; 195 | for (size_t i = 0; i < a->count_; i++) { 196 | Type d = a->digits_[i] - borrow; 197 | if (i < b->count_) 198 | d -= b->digits_[i]; 199 | borrow = (d > a->digits_[i]) ? 1 : 0; 200 | out->digits_[i] = d; 201 | if (d != 0) 202 | out->count_ = i + 1; 203 | } 204 | 205 | return ret; 206 | } 207 | 208 | int Compare(const BigInteger& rhs) const { 209 | if (count_ != rhs.count_) 210 | return count_ < rhs.count_ ? -1 : 1; 211 | 212 | for (size_t i = count_; i-- > 0;) 213 | if (digits_[i] != rhs.digits_[i]) 214 | return digits_[i] < rhs.digits_[i] ? -1 : 1; 215 | 216 | return 0; 217 | } 218 | 219 | size_t GetCount() const { return count_; } 220 | Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; } 221 | bool IsZero() const { return count_ == 1 && digits_[0] == 0; } 222 | 223 | private: 224 | void AppendDecimal64(const char* begin, const char* end) { 225 | uint64_t u = ParseUint64(begin, end); 226 | if (IsZero()) 227 | *this = u; 228 | else { 229 | unsigned exp = static_cast(end - begin); 230 | (MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u 231 | } 232 | } 233 | 234 | void PushBack(Type digit) { 235 | RAPIDJSON_ASSERT(count_ < kCapacity); 236 | digits_[count_++] = digit; 237 | } 238 | 239 | static uint64_t ParseUint64(const char* begin, const char* end) { 240 | uint64_t r = 0; 241 | for (const char* p = begin; p != end; ++p) { 242 | RAPIDJSON_ASSERT(*p >= '0' && *p <= '9'); 243 | r = r * 10u + static_cast(*p - '0'); 244 | } 245 | return r; 246 | } 247 | 248 | // Assume a * b + k < 2^128 249 | static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) { 250 | #if defined(_MSC_VER) && defined(_M_AMD64) 251 | uint64_t low = _umul128(a, b, outHigh) + k; 252 | if (low < k) 253 | (*outHigh)++; 254 | return low; 255 | #elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) 256 | __extension__ typedef unsigned __int128 uint128; 257 | uint128 p = static_cast(a) * static_cast(b); 258 | p += k; 259 | *outHigh = static_cast(p >> 64); 260 | return static_cast(p); 261 | #else 262 | const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32; 263 | uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1; 264 | x1 += (x0 >> 32); // can't give carry 265 | x1 += x2; 266 | if (x1 < x2) 267 | x3 += (static_cast(1) << 32); 268 | uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF); 269 | uint64_t hi = x3 + (x1 >> 32); 270 | 271 | lo += k; 272 | if (lo < k) 273 | hi++; 274 | *outHigh = hi; 275 | return lo; 276 | #endif 277 | } 278 | 279 | static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000 280 | static const size_t kCapacity = kBitCount / sizeof(Type); 281 | static const size_t kTypeBit = sizeof(Type) * 8; 282 | 283 | Type digits_[kCapacity]; 284 | size_t count_; 285 | }; 286 | 287 | } // namespace internal 288 | RAPIDJSON_NAMESPACE_END 289 | 290 | #endif // RAPIDJSON_BIGINTEGER_H_ 291 | -------------------------------------------------------------------------------- /rapidjson/internal/diyfp.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | // This is a C++ header-only implementation of Grisu2 algorithm from the publication: 16 | // Loitsch, Florian. "Printing floating-point numbers quickly and accurately with 17 | // integers." ACM Sigplan Notices 45.6 (2010): 233-243. 18 | 19 | #ifndef RAPIDJSON_DIYFP_H_ 20 | #define RAPIDJSON_DIYFP_H_ 21 | 22 | #include "../rapidjson.h" 23 | 24 | #if defined(_MSC_VER) && defined(_M_AMD64) 25 | #include 26 | #pragma intrinsic(_BitScanReverse64) 27 | #pragma intrinsic(_umul128) 28 | #endif 29 | 30 | RAPIDJSON_NAMESPACE_BEGIN 31 | namespace internal { 32 | 33 | #ifdef __GNUC__ 34 | RAPIDJSON_DIAG_PUSH 35 | RAPIDJSON_DIAG_OFF(effc++) 36 | #endif 37 | 38 | #ifdef __clang__ 39 | RAPIDJSON_DIAG_PUSH 40 | RAPIDJSON_DIAG_OFF(padded) 41 | #endif 42 | 43 | struct DiyFp { 44 | DiyFp() : f(), e() {} 45 | 46 | DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {} 47 | 48 | explicit DiyFp(double d) { 49 | union { 50 | double d; 51 | uint64_t u64; 52 | } u = { d }; 53 | 54 | int biased_e = static_cast((u.u64 & kDpExponentMask) >> kDpSignificandSize); 55 | uint64_t significand = (u.u64 & kDpSignificandMask); 56 | if (biased_e != 0) { 57 | f = significand + kDpHiddenBit; 58 | e = biased_e - kDpExponentBias; 59 | } 60 | else { 61 | f = significand; 62 | e = kDpMinExponent + 1; 63 | } 64 | } 65 | 66 | DiyFp operator-(const DiyFp& rhs) const { 67 | return DiyFp(f - rhs.f, e); 68 | } 69 | 70 | DiyFp operator*(const DiyFp& rhs) const { 71 | #if defined(_MSC_VER) && defined(_M_AMD64) 72 | uint64_t h; 73 | uint64_t l = _umul128(f, rhs.f, &h); 74 | if (l & (uint64_t(1) << 63)) // rounding 75 | h++; 76 | return DiyFp(h, e + rhs.e + 64); 77 | #elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) 78 | __extension__ typedef unsigned __int128 uint128; 79 | uint128 p = static_cast(f) * static_cast(rhs.f); 80 | uint64_t h = static_cast(p >> 64); 81 | uint64_t l = static_cast(p); 82 | if (l & (uint64_t(1) << 63)) // rounding 83 | h++; 84 | return DiyFp(h, e + rhs.e + 64); 85 | #else 86 | const uint64_t M32 = 0xFFFFFFFF; 87 | const uint64_t a = f >> 32; 88 | const uint64_t b = f & M32; 89 | const uint64_t c = rhs.f >> 32; 90 | const uint64_t d = rhs.f & M32; 91 | const uint64_t ac = a * c; 92 | const uint64_t bc = b * c; 93 | const uint64_t ad = a * d; 94 | const uint64_t bd = b * d; 95 | uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32); 96 | tmp += 1U << 31; /// mult_round 97 | return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64); 98 | #endif 99 | } 100 | 101 | DiyFp Normalize() const { 102 | #if defined(_MSC_VER) && defined(_M_AMD64) 103 | unsigned long index; 104 | _BitScanReverse64(&index, f); 105 | return DiyFp(f << (63 - index), e - (63 - index)); 106 | #elif defined(__GNUC__) && __GNUC__ >= 4 107 | int s = __builtin_clzll(f); 108 | return DiyFp(f << s, e - s); 109 | #else 110 | DiyFp res = *this; 111 | while (!(res.f & (static_cast(1) << 63))) { 112 | res.f <<= 1; 113 | res.e--; 114 | } 115 | return res; 116 | #endif 117 | } 118 | 119 | DiyFp NormalizeBoundary() const { 120 | DiyFp res = *this; 121 | while (!(res.f & (kDpHiddenBit << 1))) { 122 | res.f <<= 1; 123 | res.e--; 124 | } 125 | res.f <<= (kDiySignificandSize - kDpSignificandSize - 2); 126 | res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2); 127 | return res; 128 | } 129 | 130 | void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const { 131 | DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary(); 132 | DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1); 133 | mi.f <<= mi.e - pl.e; 134 | mi.e = pl.e; 135 | *plus = pl; 136 | *minus = mi; 137 | } 138 | 139 | double ToDouble() const { 140 | union { 141 | double d; 142 | uint64_t u64; 143 | }u; 144 | const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : 145 | static_cast(e + kDpExponentBias); 146 | u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize); 147 | return u.d; 148 | } 149 | 150 | static const int kDiySignificandSize = 64; 151 | static const int kDpSignificandSize = 52; 152 | static const int kDpExponentBias = 0x3FF + kDpSignificandSize; 153 | static const int kDpMaxExponent = 0x7FF - kDpExponentBias; 154 | static const int kDpMinExponent = -kDpExponentBias; 155 | static const int kDpDenormalExponent = -kDpExponentBias + 1; 156 | static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); 157 | static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); 158 | static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); 159 | 160 | uint64_t f; 161 | int e; 162 | }; 163 | 164 | inline DiyFp GetCachedPowerByIndex(size_t index) { 165 | // 10^-348, 10^-340, ..., 10^340 166 | static const uint64_t kCachedPowers_F[] = { 167 | RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76), 168 | RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea), 169 | RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df), 170 | RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f), 171 | RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c), 172 | RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5), 173 | RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d), 174 | RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637), 175 | RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7), 176 | RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5), 177 | RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b), 178 | RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996), 179 | RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6), 180 | RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8), 181 | RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053), 182 | RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd), 183 | RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94), 184 | RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b), 185 | RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac), 186 | RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3), 187 | RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb), 188 | RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c), 189 | RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000), 190 | RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984), 191 | RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70), 192 | RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245), 193 | RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8), 194 | RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a), 195 | RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea), 196 | RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85), 197 | RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2), 198 | RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3), 199 | RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25), 200 | RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece), 201 | RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5), 202 | RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a), 203 | RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c), 204 | RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a), 205 | RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129), 206 | RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429), 207 | RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d), 208 | RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841), 209 | RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9), 210 | RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b) 211 | }; 212 | static const int16_t kCachedPowers_E[] = { 213 | -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, 214 | -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, 215 | -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, 216 | -422, -396, -369, -343, -316, -289, -263, -236, -210, -183, 217 | -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, 218 | 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, 219 | 375, 402, 428, 455, 481, 508, 534, 561, 588, 614, 220 | 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, 221 | 907, 933, 960, 986, 1013, 1039, 1066 222 | }; 223 | return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]); 224 | } 225 | 226 | inline DiyFp GetCachedPower(int e, int* K) { 227 | 228 | //int k = static_cast(ceil((-61 - e) * 0.30102999566398114)) + 374; 229 | double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive 230 | int k = static_cast(dk); 231 | if (dk - k > 0.0) 232 | k++; 233 | 234 | unsigned index = static_cast((k >> 3) + 1); 235 | *K = -(-348 + static_cast(index << 3)); // decimal exponent no need lookup table 236 | 237 | return GetCachedPowerByIndex(index); 238 | } 239 | 240 | inline DiyFp GetCachedPower10(int exp, int *outExp) { 241 | unsigned index = (static_cast(exp) + 348u) / 8u; 242 | *outExp = -348 + static_cast(index) * 8; 243 | return GetCachedPowerByIndex(index); 244 | } 245 | 246 | #ifdef __GNUC__ 247 | RAPIDJSON_DIAG_POP 248 | #endif 249 | 250 | #ifdef __clang__ 251 | RAPIDJSON_DIAG_POP 252 | RAPIDJSON_DIAG_OFF(padded) 253 | #endif 254 | 255 | } // namespace internal 256 | RAPIDJSON_NAMESPACE_END 257 | 258 | #endif // RAPIDJSON_DIYFP_H_ 259 | -------------------------------------------------------------------------------- /rapidjson/internal/dtoa.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | // This is a C++ header-only implementation of Grisu2 algorithm from the publication: 16 | // Loitsch, Florian. "Printing floating-point numbers quickly and accurately with 17 | // integers." ACM Sigplan Notices 45.6 (2010): 233-243. 18 | 19 | #ifndef RAPIDJSON_DTOA_ 20 | #define RAPIDJSON_DTOA_ 21 | 22 | #include "itoa.h" // GetDigitsLut() 23 | #include "diyfp.h" 24 | #include "ieee754.h" 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | namespace internal { 28 | 29 | #ifdef __GNUC__ 30 | RAPIDJSON_DIAG_PUSH 31 | RAPIDJSON_DIAG_OFF(effc++) 32 | RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124 33 | #endif 34 | 35 | inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) { 36 | while (rest < wp_w && delta - rest >= ten_kappa && 37 | (rest + ten_kappa < wp_w || /// closer 38 | wp_w - rest > rest + ten_kappa - wp_w)) { 39 | buffer[len - 1]--; 40 | rest += ten_kappa; 41 | } 42 | } 43 | 44 | inline int CountDecimalDigit32(uint32_t n) { 45 | // Simple pure C++ implementation was faster than __builtin_clz version in this situation. 46 | if (n < 10) return 1; 47 | if (n < 100) return 2; 48 | if (n < 1000) return 3; 49 | if (n < 10000) return 4; 50 | if (n < 100000) return 5; 51 | if (n < 1000000) return 6; 52 | if (n < 10000000) return 7; 53 | if (n < 100000000) return 8; 54 | // Will not reach 10 digits in DigitGen() 55 | //if (n < 1000000000) return 9; 56 | //return 10; 57 | return 9; 58 | } 59 | 60 | inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) { 61 | static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; 62 | const DiyFp one(uint64_t(1) << -Mp.e, Mp.e); 63 | const DiyFp wp_w = Mp - W; 64 | uint32_t p1 = static_cast(Mp.f >> -one.e); 65 | uint64_t p2 = Mp.f & (one.f - 1); 66 | int kappa = CountDecimalDigit32(p1); // kappa in [0, 9] 67 | *len = 0; 68 | 69 | while (kappa > 0) { 70 | uint32_t d = 0; 71 | switch (kappa) { 72 | case 9: d = p1 / 100000000; p1 %= 100000000; break; 73 | case 8: d = p1 / 10000000; p1 %= 10000000; break; 74 | case 7: d = p1 / 1000000; p1 %= 1000000; break; 75 | case 6: d = p1 / 100000; p1 %= 100000; break; 76 | case 5: d = p1 / 10000; p1 %= 10000; break; 77 | case 4: d = p1 / 1000; p1 %= 1000; break; 78 | case 3: d = p1 / 100; p1 %= 100; break; 79 | case 2: d = p1 / 10; p1 %= 10; break; 80 | case 1: d = p1; p1 = 0; break; 81 | default:; 82 | } 83 | if (d || *len) 84 | buffer[(*len)++] = static_cast('0' + static_cast(d)); 85 | kappa--; 86 | uint64_t tmp = (static_cast(p1) << -one.e) + p2; 87 | if (tmp <= delta) { 88 | *K += kappa; 89 | GrisuRound(buffer, *len, delta, tmp, static_cast(kPow10[kappa]) << -one.e, wp_w.f); 90 | return; 91 | } 92 | } 93 | 94 | // kappa = 0 95 | for (;;) { 96 | p2 *= 10; 97 | delta *= 10; 98 | char d = static_cast(p2 >> -one.e); 99 | if (d || *len) 100 | buffer[(*len)++] = static_cast('0' + d); 101 | p2 &= one.f - 1; 102 | kappa--; 103 | if (p2 < delta) { 104 | *K += kappa; 105 | int index = -kappa; 106 | GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[index] : 0)); 107 | return; 108 | } 109 | } 110 | } 111 | 112 | inline void Grisu2(double value, char* buffer, int* length, int* K) { 113 | const DiyFp v(value); 114 | DiyFp w_m, w_p; 115 | v.NormalizedBoundaries(&w_m, &w_p); 116 | 117 | const DiyFp c_mk = GetCachedPower(w_p.e, K); 118 | const DiyFp W = v.Normalize() * c_mk; 119 | DiyFp Wp = w_p * c_mk; 120 | DiyFp Wm = w_m * c_mk; 121 | Wm.f++; 122 | Wp.f--; 123 | DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K); 124 | } 125 | 126 | inline char* WriteExponent(int K, char* buffer) { 127 | if (K < 0) { 128 | *buffer++ = '-'; 129 | K = -K; 130 | } 131 | 132 | if (K >= 100) { 133 | *buffer++ = static_cast('0' + static_cast(K / 100)); 134 | K %= 100; 135 | const char* d = GetDigitsLut() + K * 2; 136 | *buffer++ = d[0]; 137 | *buffer++ = d[1]; 138 | } 139 | else if (K >= 10) { 140 | const char* d = GetDigitsLut() + K * 2; 141 | *buffer++ = d[0]; 142 | *buffer++ = d[1]; 143 | } 144 | else 145 | *buffer++ = static_cast('0' + static_cast(K)); 146 | 147 | return buffer; 148 | } 149 | 150 | inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) { 151 | const int kk = length + k; // 10^(kk-1) <= v < 10^kk 152 | 153 | if (0 <= k && kk <= 21) { 154 | // 1234e7 -> 12340000000 155 | for (int i = length; i < kk; i++) 156 | buffer[i] = '0'; 157 | buffer[kk] = '.'; 158 | buffer[kk + 1] = '0'; 159 | return &buffer[kk + 2]; 160 | } 161 | else if (0 < kk && kk <= 21) { 162 | // 1234e-2 -> 12.34 163 | std::memmove(&buffer[kk + 1], &buffer[kk], static_cast(length - kk)); 164 | buffer[kk] = '.'; 165 | if (0 > k + maxDecimalPlaces) { 166 | // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1 167 | // Remove extra trailing zeros (at least one) after truncation. 168 | for (int i = kk + maxDecimalPlaces; i > kk + 1; i--) 169 | if (buffer[i] != '0') 170 | return &buffer[i + 1]; 171 | return &buffer[kk + 2]; // Reserve one zero 172 | } 173 | else 174 | return &buffer[length + 1]; 175 | } 176 | else if (-6 < kk && kk <= 0) { 177 | // 1234e-6 -> 0.001234 178 | const int offset = 2 - kk; 179 | std::memmove(&buffer[offset], &buffer[0], static_cast(length)); 180 | buffer[0] = '0'; 181 | buffer[1] = '.'; 182 | for (int i = 2; i < offset; i++) 183 | buffer[i] = '0'; 184 | if (length - kk > maxDecimalPlaces) { 185 | // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1 186 | // Remove extra trailing zeros (at least one) after truncation. 187 | for (int i = maxDecimalPlaces + 1; i > 2; i--) 188 | if (buffer[i] != '0') 189 | return &buffer[i + 1]; 190 | return &buffer[3]; // Reserve one zero 191 | } 192 | else 193 | return &buffer[length + offset]; 194 | } 195 | else if (kk < -maxDecimalPlaces) { 196 | // Truncate to zero 197 | buffer[0] = '0'; 198 | buffer[1] = '.'; 199 | buffer[2] = '0'; 200 | return &buffer[3]; 201 | } 202 | else if (length == 1) { 203 | // 1e30 204 | buffer[1] = 'e'; 205 | return WriteExponent(kk - 1, &buffer[2]); 206 | } 207 | else { 208 | // 1234e30 -> 1.234e33 209 | std::memmove(&buffer[2], &buffer[1], static_cast(length - 1)); 210 | buffer[1] = '.'; 211 | buffer[length + 1] = 'e'; 212 | return WriteExponent(kk - 1, &buffer[0 + length + 2]); 213 | } 214 | } 215 | 216 | inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) { 217 | RAPIDJSON_ASSERT(maxDecimalPlaces >= 1); 218 | Double d(value); 219 | if (d.IsZero()) { 220 | if (d.Sign()) 221 | *buffer++ = '-'; // -0.0, Issue #289 222 | buffer[0] = '0'; 223 | buffer[1] = '.'; 224 | buffer[2] = '0'; 225 | return &buffer[3]; 226 | } 227 | else { 228 | if (value < 0) { 229 | *buffer++ = '-'; 230 | value = -value; 231 | } 232 | int length, K; 233 | Grisu2(value, buffer, &length, &K); 234 | return Prettify(buffer, length, K, maxDecimalPlaces); 235 | } 236 | } 237 | 238 | #ifdef __GNUC__ 239 | RAPIDJSON_DIAG_POP 240 | #endif 241 | 242 | } // namespace internal 243 | RAPIDJSON_NAMESPACE_END 244 | 245 | #endif // RAPIDJSON_DTOA_ 246 | -------------------------------------------------------------------------------- /rapidjson/internal/ieee754.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_IEEE754_ 16 | #define RAPIDJSON_IEEE754_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | class Double { 24 | public: 25 | Double() {} 26 | Double(double d) : d_(d) {} 27 | Double(uint64_t u) : u_(u) {} 28 | 29 | double Value() const { return d_; } 30 | uint64_t Uint64Value() const { return u_; } 31 | 32 | double NextPositiveDouble() const { 33 | RAPIDJSON_ASSERT(!Sign()); 34 | return Double(u_ + 1).Value(); 35 | } 36 | 37 | bool Sign() const { return (u_ & kSignMask) != 0; } 38 | uint64_t Significand() const { return u_ & kSignificandMask; } 39 | int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } 40 | 41 | bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } 42 | bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } 43 | bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; } 44 | bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } 45 | bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } 46 | 47 | uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } 48 | int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } 49 | uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } 50 | 51 | static int EffectiveSignificandSize(int order) { 52 | if (order >= -1021) 53 | return 53; 54 | else if (order <= -1074) 55 | return 0; 56 | else 57 | return order + 1074; 58 | } 59 | 60 | private: 61 | static const int kSignificandSize = 52; 62 | static const int kExponentBias = 0x3FF; 63 | static const int kDenormalExponent = 1 - kExponentBias; 64 | static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); 65 | static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); 66 | static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); 67 | static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); 68 | 69 | union { 70 | double d_; 71 | uint64_t u_; 72 | }; 73 | }; 74 | 75 | } // namespace internal 76 | RAPIDJSON_NAMESPACE_END 77 | 78 | #endif // RAPIDJSON_IEEE754_ 79 | -------------------------------------------------------------------------------- /rapidjson/internal/itoa.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ITOA_ 16 | #define RAPIDJSON_ITOA_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | inline const char* GetDigitsLut() { 24 | static const char cDigitsLut[200] = { 25 | '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', 26 | '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9', 27 | '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9', 28 | '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9', 29 | '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9', 30 | '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9', 31 | '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9', 32 | '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9', 33 | '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', 34 | '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' 35 | }; 36 | return cDigitsLut; 37 | } 38 | 39 | inline char* u32toa(uint32_t value, char* buffer) { 40 | const char* cDigitsLut = GetDigitsLut(); 41 | 42 | if (value < 10000) { 43 | const uint32_t d1 = (value / 100) << 1; 44 | const uint32_t d2 = (value % 100) << 1; 45 | 46 | if (value >= 1000) 47 | *buffer++ = cDigitsLut[d1]; 48 | if (value >= 100) 49 | *buffer++ = cDigitsLut[d1 + 1]; 50 | if (value >= 10) 51 | *buffer++ = cDigitsLut[d2]; 52 | *buffer++ = cDigitsLut[d2 + 1]; 53 | } 54 | else if (value < 100000000) { 55 | // value = bbbbcccc 56 | const uint32_t b = value / 10000; 57 | const uint32_t c = value % 10000; 58 | 59 | const uint32_t d1 = (b / 100) << 1; 60 | const uint32_t d2 = (b % 100) << 1; 61 | 62 | const uint32_t d3 = (c / 100) << 1; 63 | const uint32_t d4 = (c % 100) << 1; 64 | 65 | if (value >= 10000000) 66 | *buffer++ = cDigitsLut[d1]; 67 | if (value >= 1000000) 68 | *buffer++ = cDigitsLut[d1 + 1]; 69 | if (value >= 100000) 70 | *buffer++ = cDigitsLut[d2]; 71 | *buffer++ = cDigitsLut[d2 + 1]; 72 | 73 | *buffer++ = cDigitsLut[d3]; 74 | *buffer++ = cDigitsLut[d3 + 1]; 75 | *buffer++ = cDigitsLut[d4]; 76 | *buffer++ = cDigitsLut[d4 + 1]; 77 | } 78 | else { 79 | // value = aabbbbcccc in decimal 80 | 81 | const uint32_t a = value / 100000000; // 1 to 42 82 | value %= 100000000; 83 | 84 | if (a >= 10) { 85 | const unsigned i = a << 1; 86 | *buffer++ = cDigitsLut[i]; 87 | *buffer++ = cDigitsLut[i + 1]; 88 | } 89 | else 90 | *buffer++ = static_cast('0' + static_cast(a)); 91 | 92 | const uint32_t b = value / 10000; // 0 to 9999 93 | const uint32_t c = value % 10000; // 0 to 9999 94 | 95 | const uint32_t d1 = (b / 100) << 1; 96 | const uint32_t d2 = (b % 100) << 1; 97 | 98 | const uint32_t d3 = (c / 100) << 1; 99 | const uint32_t d4 = (c % 100) << 1; 100 | 101 | *buffer++ = cDigitsLut[d1]; 102 | *buffer++ = cDigitsLut[d1 + 1]; 103 | *buffer++ = cDigitsLut[d2]; 104 | *buffer++ = cDigitsLut[d2 + 1]; 105 | *buffer++ = cDigitsLut[d3]; 106 | *buffer++ = cDigitsLut[d3 + 1]; 107 | *buffer++ = cDigitsLut[d4]; 108 | *buffer++ = cDigitsLut[d4 + 1]; 109 | } 110 | return buffer; 111 | } 112 | 113 | inline char* i32toa(int32_t value, char* buffer) { 114 | uint32_t u = static_cast(value); 115 | if (value < 0) { 116 | *buffer++ = '-'; 117 | u = ~u + 1; 118 | } 119 | 120 | return u32toa(u, buffer); 121 | } 122 | 123 | inline char* u64toa(uint64_t value, char* buffer) { 124 | const char* cDigitsLut = GetDigitsLut(); 125 | const uint64_t kTen8 = 100000000; 126 | const uint64_t kTen9 = kTen8 * 10; 127 | const uint64_t kTen10 = kTen8 * 100; 128 | const uint64_t kTen11 = kTen8 * 1000; 129 | const uint64_t kTen12 = kTen8 * 10000; 130 | const uint64_t kTen13 = kTen8 * 100000; 131 | const uint64_t kTen14 = kTen8 * 1000000; 132 | const uint64_t kTen15 = kTen8 * 10000000; 133 | const uint64_t kTen16 = kTen8 * kTen8; 134 | 135 | if (value < kTen8) { 136 | uint32_t v = static_cast(value); 137 | if (v < 10000) { 138 | const uint32_t d1 = (v / 100) << 1; 139 | const uint32_t d2 = (v % 100) << 1; 140 | 141 | if (v >= 1000) 142 | *buffer++ = cDigitsLut[d1]; 143 | if (v >= 100) 144 | *buffer++ = cDigitsLut[d1 + 1]; 145 | if (v >= 10) 146 | *buffer++ = cDigitsLut[d2]; 147 | *buffer++ = cDigitsLut[d2 + 1]; 148 | } 149 | else { 150 | // value = bbbbcccc 151 | const uint32_t b = v / 10000; 152 | const uint32_t c = v % 10000; 153 | 154 | const uint32_t d1 = (b / 100) << 1; 155 | const uint32_t d2 = (b % 100) << 1; 156 | 157 | const uint32_t d3 = (c / 100) << 1; 158 | const uint32_t d4 = (c % 100) << 1; 159 | 160 | if (value >= 10000000) 161 | *buffer++ = cDigitsLut[d1]; 162 | if (value >= 1000000) 163 | *buffer++ = cDigitsLut[d1 + 1]; 164 | if (value >= 100000) 165 | *buffer++ = cDigitsLut[d2]; 166 | *buffer++ = cDigitsLut[d2 + 1]; 167 | 168 | *buffer++ = cDigitsLut[d3]; 169 | *buffer++ = cDigitsLut[d3 + 1]; 170 | *buffer++ = cDigitsLut[d4]; 171 | *buffer++ = cDigitsLut[d4 + 1]; 172 | } 173 | } 174 | else if (value < kTen16) { 175 | const uint32_t v0 = static_cast(value / kTen8); 176 | const uint32_t v1 = static_cast(value % kTen8); 177 | 178 | const uint32_t b0 = v0 / 10000; 179 | const uint32_t c0 = v0 % 10000; 180 | 181 | const uint32_t d1 = (b0 / 100) << 1; 182 | const uint32_t d2 = (b0 % 100) << 1; 183 | 184 | const uint32_t d3 = (c0 / 100) << 1; 185 | const uint32_t d4 = (c0 % 100) << 1; 186 | 187 | const uint32_t b1 = v1 / 10000; 188 | const uint32_t c1 = v1 % 10000; 189 | 190 | const uint32_t d5 = (b1 / 100) << 1; 191 | const uint32_t d6 = (b1 % 100) << 1; 192 | 193 | const uint32_t d7 = (c1 / 100) << 1; 194 | const uint32_t d8 = (c1 % 100) << 1; 195 | 196 | if (value >= kTen15) 197 | *buffer++ = cDigitsLut[d1]; 198 | if (value >= kTen14) 199 | *buffer++ = cDigitsLut[d1 + 1]; 200 | if (value >= kTen13) 201 | *buffer++ = cDigitsLut[d2]; 202 | if (value >= kTen12) 203 | *buffer++ = cDigitsLut[d2 + 1]; 204 | if (value >= kTen11) 205 | *buffer++ = cDigitsLut[d3]; 206 | if (value >= kTen10) 207 | *buffer++ = cDigitsLut[d3 + 1]; 208 | if (value >= kTen9) 209 | *buffer++ = cDigitsLut[d4]; 210 | if (value >= kTen8) 211 | *buffer++ = cDigitsLut[d4 + 1]; 212 | 213 | *buffer++ = cDigitsLut[d5]; 214 | *buffer++ = cDigitsLut[d5 + 1]; 215 | *buffer++ = cDigitsLut[d6]; 216 | *buffer++ = cDigitsLut[d6 + 1]; 217 | *buffer++ = cDigitsLut[d7]; 218 | *buffer++ = cDigitsLut[d7 + 1]; 219 | *buffer++ = cDigitsLut[d8]; 220 | *buffer++ = cDigitsLut[d8 + 1]; 221 | } 222 | else { 223 | const uint32_t a = static_cast(value / kTen16); // 1 to 1844 224 | value %= kTen16; 225 | 226 | if (a < 10) 227 | *buffer++ = static_cast('0' + static_cast(a)); 228 | else if (a < 100) { 229 | const uint32_t i = a << 1; 230 | *buffer++ = cDigitsLut[i]; 231 | *buffer++ = cDigitsLut[i + 1]; 232 | } 233 | else if (a < 1000) { 234 | *buffer++ = static_cast('0' + static_cast(a / 100)); 235 | 236 | const uint32_t i = (a % 100) << 1; 237 | *buffer++ = cDigitsLut[i]; 238 | *buffer++ = cDigitsLut[i + 1]; 239 | } 240 | else { 241 | const uint32_t i = (a / 100) << 1; 242 | const uint32_t j = (a % 100) << 1; 243 | *buffer++ = cDigitsLut[i]; 244 | *buffer++ = cDigitsLut[i + 1]; 245 | *buffer++ = cDigitsLut[j]; 246 | *buffer++ = cDigitsLut[j + 1]; 247 | } 248 | 249 | const uint32_t v0 = static_cast(value / kTen8); 250 | const uint32_t v1 = static_cast(value % kTen8); 251 | 252 | const uint32_t b0 = v0 / 10000; 253 | const uint32_t c0 = v0 % 10000; 254 | 255 | const uint32_t d1 = (b0 / 100) << 1; 256 | const uint32_t d2 = (b0 % 100) << 1; 257 | 258 | const uint32_t d3 = (c0 / 100) << 1; 259 | const uint32_t d4 = (c0 % 100) << 1; 260 | 261 | const uint32_t b1 = v1 / 10000; 262 | const uint32_t c1 = v1 % 10000; 263 | 264 | const uint32_t d5 = (b1 / 100) << 1; 265 | const uint32_t d6 = (b1 % 100) << 1; 266 | 267 | const uint32_t d7 = (c1 / 100) << 1; 268 | const uint32_t d8 = (c1 % 100) << 1; 269 | 270 | *buffer++ = cDigitsLut[d1]; 271 | *buffer++ = cDigitsLut[d1 + 1]; 272 | *buffer++ = cDigitsLut[d2]; 273 | *buffer++ = cDigitsLut[d2 + 1]; 274 | *buffer++ = cDigitsLut[d3]; 275 | *buffer++ = cDigitsLut[d3 + 1]; 276 | *buffer++ = cDigitsLut[d4]; 277 | *buffer++ = cDigitsLut[d4 + 1]; 278 | *buffer++ = cDigitsLut[d5]; 279 | *buffer++ = cDigitsLut[d5 + 1]; 280 | *buffer++ = cDigitsLut[d6]; 281 | *buffer++ = cDigitsLut[d6 + 1]; 282 | *buffer++ = cDigitsLut[d7]; 283 | *buffer++ = cDigitsLut[d7 + 1]; 284 | *buffer++ = cDigitsLut[d8]; 285 | *buffer++ = cDigitsLut[d8 + 1]; 286 | } 287 | 288 | return buffer; 289 | } 290 | 291 | inline char* i64toa(int64_t value, char* buffer) { 292 | uint64_t u = static_cast(value); 293 | if (value < 0) { 294 | *buffer++ = '-'; 295 | u = ~u + 1; 296 | } 297 | 298 | return u64toa(u, buffer); 299 | } 300 | 301 | } // namespace internal 302 | RAPIDJSON_NAMESPACE_END 303 | 304 | #endif // RAPIDJSON_ITOA_ 305 | -------------------------------------------------------------------------------- /rapidjson/internal/meta.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_META_H_ 16 | #define RAPIDJSON_INTERNAL_META_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #ifdef __GNUC__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(effc++) 23 | #endif 24 | #if defined(_MSC_VER) 25 | RAPIDJSON_DIAG_PUSH 26 | RAPIDJSON_DIAG_OFF(6334) 27 | #endif 28 | 29 | #if RAPIDJSON_HAS_CXX11_TYPETRAITS 30 | #include 31 | #endif 32 | 33 | //@cond RAPIDJSON_INTERNAL 34 | RAPIDJSON_NAMESPACE_BEGIN 35 | namespace internal { 36 | 37 | // Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching 38 | template struct Void { typedef void Type; }; 39 | 40 | /////////////////////////////////////////////////////////////////////////////// 41 | // BoolType, TrueType, FalseType 42 | // 43 | template struct BoolType { 44 | static const bool Value = Cond; 45 | typedef BoolType Type; 46 | }; 47 | typedef BoolType TrueType; 48 | typedef BoolType FalseType; 49 | 50 | 51 | /////////////////////////////////////////////////////////////////////////////// 52 | // SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr 53 | // 54 | 55 | template struct SelectIfImpl { template struct Apply { typedef T1 Type; }; }; 56 | template <> struct SelectIfImpl { template struct Apply { typedef T2 Type; }; }; 57 | template struct SelectIfCond : SelectIfImpl::template Apply {}; 58 | template struct SelectIf : SelectIfCond {}; 59 | 60 | template struct AndExprCond : FalseType {}; 61 | template <> struct AndExprCond : TrueType {}; 62 | template struct OrExprCond : TrueType {}; 63 | template <> struct OrExprCond : FalseType {}; 64 | 65 | template struct BoolExpr : SelectIf::Type {}; 66 | template struct NotExpr : SelectIf::Type {}; 67 | template struct AndExpr : AndExprCond::Type {}; 68 | template struct OrExpr : OrExprCond::Type {}; 69 | 70 | 71 | /////////////////////////////////////////////////////////////////////////////// 72 | // AddConst, MaybeAddConst, RemoveConst 73 | template struct AddConst { typedef const T Type; }; 74 | template struct MaybeAddConst : SelectIfCond {}; 75 | template struct RemoveConst { typedef T Type; }; 76 | template struct RemoveConst { typedef T Type; }; 77 | 78 | 79 | /////////////////////////////////////////////////////////////////////////////// 80 | // IsSame, IsConst, IsMoreConst, IsPointer 81 | // 82 | template struct IsSame : FalseType {}; 83 | template struct IsSame : TrueType {}; 84 | 85 | template struct IsConst : FalseType {}; 86 | template struct IsConst : TrueType {}; 87 | 88 | template 89 | struct IsMoreConst 90 | : AndExpr::Type, typename RemoveConst::Type>, 91 | BoolType::Value >= IsConst::Value> >::Type {}; 92 | 93 | template struct IsPointer : FalseType {}; 94 | template struct IsPointer : TrueType {}; 95 | 96 | /////////////////////////////////////////////////////////////////////////////// 97 | // IsBaseOf 98 | // 99 | #if RAPIDJSON_HAS_CXX11_TYPETRAITS 100 | 101 | template struct IsBaseOf 102 | : BoolType< ::std::is_base_of::value> {}; 103 | 104 | #else // simplified version adopted from Boost 105 | 106 | template struct IsBaseOfImpl { 107 | RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0); 108 | RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0); 109 | 110 | typedef char (&Yes)[1]; 111 | typedef char (&No) [2]; 112 | 113 | template 114 | static Yes Check(const D*, T); 115 | static No Check(const B*, int); 116 | 117 | struct Host { 118 | operator const B*() const; 119 | operator const D*(); 120 | }; 121 | 122 | enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) }; 123 | }; 124 | 125 | template struct IsBaseOf 126 | : OrExpr, BoolExpr > >::Type {}; 127 | 128 | #endif // RAPIDJSON_HAS_CXX11_TYPETRAITS 129 | 130 | 131 | ////////////////////////////////////////////////////////////////////////// 132 | // EnableIf / DisableIf 133 | // 134 | template struct EnableIfCond { typedef T Type; }; 135 | template struct EnableIfCond { /* empty */ }; 136 | 137 | template struct DisableIfCond { typedef T Type; }; 138 | template struct DisableIfCond { /* empty */ }; 139 | 140 | template 141 | struct EnableIf : EnableIfCond {}; 142 | 143 | template 144 | struct DisableIf : DisableIfCond {}; 145 | 146 | // SFINAE helpers 147 | struct SfinaeTag {}; 148 | template struct RemoveSfinaeTag; 149 | template struct RemoveSfinaeTag { typedef T Type; }; 150 | 151 | #define RAPIDJSON_REMOVEFPTR_(type) \ 152 | typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \ 153 | < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type 154 | 155 | #define RAPIDJSON_ENABLEIF(cond) \ 156 | typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ 157 | ::Type * = NULL 158 | 159 | #define RAPIDJSON_DISABLEIF(cond) \ 160 | typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ 161 | ::Type * = NULL 162 | 163 | #define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \ 164 | typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ 165 | ::Type 167 | 168 | #define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ 169 | typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ 170 | ::Type 172 | 173 | } // namespace internal 174 | RAPIDJSON_NAMESPACE_END 175 | //@endcond 176 | 177 | #if defined(__GNUC__) || defined(_MSC_VER) 178 | RAPIDJSON_DIAG_POP 179 | #endif 180 | 181 | #endif // RAPIDJSON_INTERNAL_META_H_ 182 | -------------------------------------------------------------------------------- /rapidjson/internal/pow10.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_POW10_ 16 | #define RAPIDJSON_POW10_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | //! Computes integer powers of 10 in double (10.0^n). 24 | /*! This function uses lookup table for fast and accurate results. 25 | \param n non-negative exponent. Must <= 308. 26 | \return 10.0^n 27 | */ 28 | inline double Pow10(int n) { 29 | static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes 30 | 1e+0, 31 | 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, 32 | 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, 33 | 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, 34 | 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, 35 | 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, 36 | 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, 37 | 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, 38 | 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, 39 | 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, 40 | 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, 41 | 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, 42 | 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, 43 | 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, 44 | 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, 45 | 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, 46 | 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 47 | }; 48 | RAPIDJSON_ASSERT(n >= 0 && n <= 308); 49 | return e[n]; 50 | } 51 | 52 | } // namespace internal 53 | RAPIDJSON_NAMESPACE_END 54 | 55 | #endif // RAPIDJSON_POW10_ 56 | -------------------------------------------------------------------------------- /rapidjson/internal/stack.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_STACK_H_ 16 | #define RAPIDJSON_INTERNAL_STACK_H_ 17 | 18 | #include "../allocators.h" 19 | #include "swap.h" 20 | 21 | #if defined(__clang__) 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(c++98-compat) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | namespace internal { 28 | 29 | /////////////////////////////////////////////////////////////////////////////// 30 | // Stack 31 | 32 | //! A type-unsafe stack for storing different types of data. 33 | /*! \tparam Allocator Allocator for allocating stack memory. 34 | */ 35 | template 36 | class Stack { 37 | public: 38 | // Optimization note: Do not allocate memory for stack_ in constructor. 39 | // Do it lazily when first Push() -> Expand() -> Resize(). 40 | Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) { 41 | } 42 | 43 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 44 | Stack(Stack&& rhs) 45 | : allocator_(rhs.allocator_), 46 | ownAllocator_(rhs.ownAllocator_), 47 | stack_(rhs.stack_), 48 | stackTop_(rhs.stackTop_), 49 | stackEnd_(rhs.stackEnd_), 50 | initialCapacity_(rhs.initialCapacity_) 51 | { 52 | rhs.allocator_ = 0; 53 | rhs.ownAllocator_ = 0; 54 | rhs.stack_ = 0; 55 | rhs.stackTop_ = 0; 56 | rhs.stackEnd_ = 0; 57 | rhs.initialCapacity_ = 0; 58 | } 59 | #endif 60 | 61 | ~Stack() { 62 | Destroy(); 63 | } 64 | 65 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 66 | Stack& operator=(Stack&& rhs) { 67 | if (&rhs != this) 68 | { 69 | Destroy(); 70 | 71 | allocator_ = rhs.allocator_; 72 | ownAllocator_ = rhs.ownAllocator_; 73 | stack_ = rhs.stack_; 74 | stackTop_ = rhs.stackTop_; 75 | stackEnd_ = rhs.stackEnd_; 76 | initialCapacity_ = rhs.initialCapacity_; 77 | 78 | rhs.allocator_ = 0; 79 | rhs.ownAllocator_ = 0; 80 | rhs.stack_ = 0; 81 | rhs.stackTop_ = 0; 82 | rhs.stackEnd_ = 0; 83 | rhs.initialCapacity_ = 0; 84 | } 85 | return *this; 86 | } 87 | #endif 88 | 89 | void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT { 90 | internal::Swap(allocator_, rhs.allocator_); 91 | internal::Swap(ownAllocator_, rhs.ownAllocator_); 92 | internal::Swap(stack_, rhs.stack_); 93 | internal::Swap(stackTop_, rhs.stackTop_); 94 | internal::Swap(stackEnd_, rhs.stackEnd_); 95 | internal::Swap(initialCapacity_, rhs.initialCapacity_); 96 | } 97 | 98 | void Clear() { stackTop_ = stack_; } 99 | 100 | void ShrinkToFit() { 101 | if (Empty()) { 102 | // If the stack is empty, completely deallocate the memory. 103 | Allocator::Free(stack_); 104 | stack_ = 0; 105 | stackTop_ = 0; 106 | stackEnd_ = 0; 107 | } 108 | else 109 | Resize(GetSize()); 110 | } 111 | 112 | // Optimization note: try to minimize the size of this function for force inline. 113 | // Expansion is run very infrequently, so it is moved to another (probably non-inline) function. 114 | template 115 | RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) { 116 | // Expand the stack if needed 117 | if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_)) 118 | Expand(count); 119 | } 120 | 121 | template 122 | RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { 123 | Reserve(count); 124 | return PushUnsafe(count); 125 | } 126 | 127 | template 128 | RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) { 129 | RAPIDJSON_ASSERT(stackTop_); 130 | RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_); 131 | T* ret = reinterpret_cast(stackTop_); 132 | stackTop_ += sizeof(T) * count; 133 | return ret; 134 | } 135 | 136 | template 137 | T* Pop(size_t count) { 138 | RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); 139 | stackTop_ -= count * sizeof(T); 140 | return reinterpret_cast(stackTop_); 141 | } 142 | 143 | template 144 | T* Top() { 145 | RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); 146 | return reinterpret_cast(stackTop_ - sizeof(T)); 147 | } 148 | 149 | template 150 | const T* Top() const { 151 | RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); 152 | return reinterpret_cast(stackTop_ - sizeof(T)); 153 | } 154 | 155 | template 156 | T* End() { return reinterpret_cast(stackTop_); } 157 | 158 | template 159 | const T* End() const { return reinterpret_cast(stackTop_); } 160 | 161 | template 162 | T* Bottom() { return reinterpret_cast(stack_); } 163 | 164 | template 165 | const T* Bottom() const { return reinterpret_cast(stack_); } 166 | 167 | bool HasAllocator() const { 168 | return allocator_ != 0; 169 | } 170 | 171 | Allocator& GetAllocator() { 172 | RAPIDJSON_ASSERT(allocator_); 173 | return *allocator_; 174 | } 175 | 176 | bool Empty() const { return stackTop_ == stack_; } 177 | size_t GetSize() const { return static_cast(stackTop_ - stack_); } 178 | size_t GetCapacity() const { return static_cast(stackEnd_ - stack_); } 179 | 180 | private: 181 | template 182 | void Expand(size_t count) { 183 | // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity. 184 | size_t newCapacity; 185 | if (stack_ == 0) { 186 | if (!allocator_) 187 | ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); 188 | newCapacity = initialCapacity_; 189 | } else { 190 | newCapacity = GetCapacity(); 191 | newCapacity += (newCapacity + 1) / 2; 192 | } 193 | size_t newSize = GetSize() + sizeof(T) * count; 194 | if (newCapacity < newSize) 195 | newCapacity = newSize; 196 | 197 | Resize(newCapacity); 198 | } 199 | 200 | void Resize(size_t newCapacity) { 201 | const size_t size = GetSize(); // Backup the current size 202 | stack_ = static_cast(allocator_->Realloc(stack_, GetCapacity(), newCapacity)); 203 | stackTop_ = stack_ + size; 204 | stackEnd_ = stack_ + newCapacity; 205 | } 206 | 207 | void Destroy() { 208 | Allocator::Free(stack_); 209 | RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack 210 | } 211 | 212 | // Prohibit copy constructor & assignment operator. 213 | Stack(const Stack&); 214 | Stack& operator=(const Stack&); 215 | 216 | Allocator* allocator_; 217 | Allocator* ownAllocator_; 218 | char *stack_; 219 | char *stackTop_; 220 | char *stackEnd_; 221 | size_t initialCapacity_; 222 | }; 223 | 224 | } // namespace internal 225 | RAPIDJSON_NAMESPACE_END 226 | 227 | #if defined(__clang__) 228 | RAPIDJSON_DIAG_POP 229 | #endif 230 | 231 | #endif // RAPIDJSON_STACK_H_ 232 | -------------------------------------------------------------------------------- /rapidjson/internal/strfunc.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ 16 | #define RAPIDJSON_INTERNAL_STRFUNC_H_ 17 | 18 | #include "../stream.h" 19 | #include 20 | 21 | RAPIDJSON_NAMESPACE_BEGIN 22 | namespace internal { 23 | 24 | //! Custom strlen() which works on different character types. 25 | /*! \tparam Ch Character type (e.g. char, wchar_t, short) 26 | \param s Null-terminated input string. 27 | \return Number of characters in the string. 28 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. 29 | */ 30 | template 31 | inline SizeType StrLen(const Ch* s) { 32 | RAPIDJSON_ASSERT(s != 0); 33 | const Ch* p = s; 34 | while (*p) ++p; 35 | return SizeType(p - s); 36 | } 37 | 38 | template <> 39 | inline SizeType StrLen(const char* s) { 40 | return SizeType(std::strlen(s)); 41 | } 42 | 43 | template <> 44 | inline SizeType StrLen(const wchar_t* s) { 45 | return SizeType(std::wcslen(s)); 46 | } 47 | 48 | //! Returns number of code points in a encoded string. 49 | template 50 | bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { 51 | RAPIDJSON_ASSERT(s != 0); 52 | RAPIDJSON_ASSERT(outCount != 0); 53 | GenericStringStream is(s); 54 | const typename Encoding::Ch* end = s + length; 55 | SizeType count = 0; 56 | while (is.src_ < end) { 57 | unsigned codepoint; 58 | if (!Encoding::Decode(is, &codepoint)) 59 | return false; 60 | count++; 61 | } 62 | *outCount = count; 63 | return true; 64 | } 65 | 66 | } // namespace internal 67 | RAPIDJSON_NAMESPACE_END 68 | 69 | #endif // RAPIDJSON_INTERNAL_STRFUNC_H_ 70 | -------------------------------------------------------------------------------- /rapidjson/internal/strtod.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_STRTOD_ 16 | #define RAPIDJSON_STRTOD_ 17 | 18 | #include "ieee754.h" 19 | #include "biginteger.h" 20 | #include "diyfp.h" 21 | #include "pow10.h" 22 | 23 | RAPIDJSON_NAMESPACE_BEGIN 24 | namespace internal { 25 | 26 | inline double FastPath(double significand, int exp) { 27 | if (exp < -308) 28 | return 0.0; 29 | else if (exp >= 0) 30 | return significand * internal::Pow10(exp); 31 | else 32 | return significand / internal::Pow10(-exp); 33 | } 34 | 35 | inline double StrtodNormalPrecision(double d, int p) { 36 | if (p < -308) { 37 | // Prevent expSum < -308, making Pow10(p) = 0 38 | d = FastPath(d, -308); 39 | d = FastPath(d, p + 308); 40 | } 41 | else 42 | d = FastPath(d, p); 43 | return d; 44 | } 45 | 46 | template 47 | inline T Min3(T a, T b, T c) { 48 | T m = a; 49 | if (m > b) m = b; 50 | if (m > c) m = c; 51 | return m; 52 | } 53 | 54 | inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) { 55 | const Double db(b); 56 | const uint64_t bInt = db.IntegerSignificand(); 57 | const int bExp = db.IntegerExponent(); 58 | const int hExp = bExp - 1; 59 | 60 | int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0; 61 | 62 | // Adjust for decimal exponent 63 | if (dExp >= 0) { 64 | dS_Exp2 += dExp; 65 | dS_Exp5 += dExp; 66 | } 67 | else { 68 | bS_Exp2 -= dExp; 69 | bS_Exp5 -= dExp; 70 | hS_Exp2 -= dExp; 71 | hS_Exp5 -= dExp; 72 | } 73 | 74 | // Adjust for binary exponent 75 | if (bExp >= 0) 76 | bS_Exp2 += bExp; 77 | else { 78 | dS_Exp2 -= bExp; 79 | hS_Exp2 -= bExp; 80 | } 81 | 82 | // Adjust for half ulp exponent 83 | if (hExp >= 0) 84 | hS_Exp2 += hExp; 85 | else { 86 | dS_Exp2 -= hExp; 87 | bS_Exp2 -= hExp; 88 | } 89 | 90 | // Remove common power of two factor from all three scaled values 91 | int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2); 92 | dS_Exp2 -= common_Exp2; 93 | bS_Exp2 -= common_Exp2; 94 | hS_Exp2 -= common_Exp2; 95 | 96 | BigInteger dS = d; 97 | dS.MultiplyPow5(static_cast(dS_Exp5)) <<= static_cast(dS_Exp2); 98 | 99 | BigInteger bS(bInt); 100 | bS.MultiplyPow5(static_cast(bS_Exp5)) <<= static_cast(bS_Exp2); 101 | 102 | BigInteger hS(1); 103 | hS.MultiplyPow5(static_cast(hS_Exp5)) <<= static_cast(hS_Exp2); 104 | 105 | BigInteger delta(0); 106 | dS.Difference(bS, &delta); 107 | 108 | return delta.Compare(hS); 109 | } 110 | 111 | inline bool StrtodFast(double d, int p, double* result) { 112 | // Use fast path for string-to-double conversion if possible 113 | // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ 114 | if (p > 22 && p < 22 + 16) { 115 | // Fast Path Cases In Disguise 116 | d *= internal::Pow10(p - 22); 117 | p = 22; 118 | } 119 | 120 | if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1 121 | *result = FastPath(d, p); 122 | return true; 123 | } 124 | else 125 | return false; 126 | } 127 | 128 | // Compute an approximation and see if it is within 1/2 ULP 129 | inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) { 130 | uint64_t significand = 0; 131 | size_t i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999 132 | for (; i < length; i++) { 133 | if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || 134 | (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5')) 135 | break; 136 | significand = significand * 10u + static_cast(decimals[i] - '0'); 137 | } 138 | 139 | if (i < length && decimals[i] >= '5') // Rounding 140 | significand++; 141 | 142 | size_t remaining = length - i; 143 | const int kUlpShift = 3; 144 | const int kUlp = 1 << kUlpShift; 145 | int64_t error = (remaining == 0) ? 0 : kUlp / 2; 146 | 147 | DiyFp v(significand, 0); 148 | v = v.Normalize(); 149 | error <<= -v.e; 150 | 151 | const int dExp = static_cast(decimalPosition) - static_cast(i) + exp; 152 | 153 | int actualExp; 154 | DiyFp cachedPower = GetCachedPower10(dExp, &actualExp); 155 | if (actualExp != dExp) { 156 | static const DiyFp kPow10[] = { 157 | DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60), // 10^1 158 | DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57), // 10^2 159 | DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54), // 10^3 160 | DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50), // 10^4 161 | DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47), // 10^5 162 | DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6 163 | DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7 164 | }; 165 | int adjustment = dExp - actualExp - 1; 166 | RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7); 167 | v = v * kPow10[adjustment]; 168 | if (length + static_cast(adjustment)> 19u) // has more digits than decimal digits in 64-bit 169 | error += kUlp / 2; 170 | } 171 | 172 | v = v * cachedPower; 173 | 174 | error += kUlp + (error == 0 ? 0 : 1); 175 | 176 | const int oldExp = v.e; 177 | v = v.Normalize(); 178 | error <<= oldExp - v.e; 179 | 180 | const int effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); 181 | int precisionSize = 64 - effectiveSignificandSize; 182 | if (precisionSize + kUlpShift >= 64) { 183 | int scaleExp = (precisionSize + kUlpShift) - 63; 184 | v.f >>= scaleExp; 185 | v.e += scaleExp; 186 | error = (error >> scaleExp) + 1 + kUlp; 187 | precisionSize -= scaleExp; 188 | } 189 | 190 | DiyFp rounded(v.f >> precisionSize, v.e + precisionSize); 191 | const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp; 192 | const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp; 193 | if (precisionBits >= halfWay + static_cast(error)) { 194 | rounded.f++; 195 | if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340) 196 | rounded.f >>= 1; 197 | rounded.e++; 198 | } 199 | } 200 | 201 | *result = rounded.ToDouble(); 202 | 203 | return halfWay - static_cast(error) >= precisionBits || precisionBits >= halfWay + static_cast(error); 204 | } 205 | 206 | inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) { 207 | const BigInteger dInt(decimals, length); 208 | const int dExp = static_cast(decimalPosition) - static_cast(length) + exp; 209 | Double a(approx); 210 | int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp); 211 | if (cmp < 0) 212 | return a.Value(); // within half ULP 213 | else if (cmp == 0) { 214 | // Round towards even 215 | if (a.Significand() & 1) 216 | return a.NextPositiveDouble(); 217 | else 218 | return a.Value(); 219 | } 220 | else // adjustment 221 | return a.NextPositiveDouble(); 222 | } 223 | 224 | inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) { 225 | RAPIDJSON_ASSERT(d >= 0.0); 226 | RAPIDJSON_ASSERT(length >= 1); 227 | 228 | double result; 229 | if (StrtodFast(d, p, &result)) 230 | return result; 231 | 232 | // Trim leading zeros 233 | while (*decimals == '0' && length > 1) { 234 | length--; 235 | decimals++; 236 | decimalPosition--; 237 | } 238 | 239 | // Trim trailing zeros 240 | while (decimals[length - 1] == '0' && length > 1) { 241 | length--; 242 | decimalPosition--; 243 | exp++; 244 | } 245 | 246 | // Trim right-most digits 247 | const int kMaxDecimalDigit = 780; 248 | if (static_cast(length) > kMaxDecimalDigit) { 249 | int delta = (static_cast(length) - kMaxDecimalDigit); 250 | exp += delta; 251 | decimalPosition -= static_cast(delta); 252 | length = kMaxDecimalDigit; 253 | } 254 | 255 | // If too small, underflow to zero 256 | if (int(length) + exp < -324) 257 | return 0.0; 258 | 259 | if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result)) 260 | return result; 261 | 262 | // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison 263 | return StrtodBigInteger(result, decimals, length, decimalPosition, exp); 264 | } 265 | 266 | } // namespace internal 267 | RAPIDJSON_NAMESPACE_END 268 | 269 | #endif // RAPIDJSON_STRTOD_ 270 | -------------------------------------------------------------------------------- /rapidjson/internal/swap.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_SWAP_H_ 16 | #define RAPIDJSON_INTERNAL_SWAP_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #if defined(__clang__) 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(c++98-compat) 23 | #endif 24 | 25 | RAPIDJSON_NAMESPACE_BEGIN 26 | namespace internal { 27 | 28 | //! Custom swap() to avoid dependency on C++ header 29 | /*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. 30 | \note This has the same semantics as std::swap(). 31 | */ 32 | template 33 | inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { 34 | T tmp = a; 35 | a = b; 36 | b = tmp; 37 | } 38 | 39 | } // namespace internal 40 | RAPIDJSON_NAMESPACE_END 41 | 42 | #if defined(__clang__) 43 | RAPIDJSON_DIAG_POP 44 | #endif 45 | 46 | #endif // RAPIDJSON_INTERNAL_SWAP_H_ 47 | -------------------------------------------------------------------------------- /rapidjson/istreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_ISTREAMWRAPPER_H_ 16 | #define RAPIDJSON_ISTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | #endif 25 | 26 | #ifdef _MSC_VER 27 | RAPIDJSON_DIAG_PUSH 28 | RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized 29 | #endif 30 | 31 | RAPIDJSON_NAMESPACE_BEGIN 32 | 33 | //! Wrapper of \c std::basic_istream into RapidJSON's Stream concept. 34 | /*! 35 | The classes can be wrapped including but not limited to: 36 | 37 | - \c std::istringstream 38 | - \c std::stringstream 39 | - \c std::wistringstream 40 | - \c std::wstringstream 41 | - \c std::ifstream 42 | - \c std::fstream 43 | - \c std::wifstream 44 | - \c std::wfstream 45 | 46 | \tparam StreamType Class derived from \c std::basic_istream. 47 | */ 48 | 49 | template 50 | class BasicIStreamWrapper { 51 | public: 52 | typedef typename StreamType::char_type Ch; 53 | BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {} 54 | 55 | Ch Peek() const { 56 | typename StreamType::int_type c = stream_.peek(); 57 | return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast(c) : static_cast('\0'); 58 | } 59 | 60 | Ch Take() { 61 | typename StreamType::int_type c = stream_.get(); 62 | if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) { 63 | count_++; 64 | return static_cast(c); 65 | } 66 | else 67 | return '\0'; 68 | } 69 | 70 | // tellg() may return -1 when failed. So we count by ourself. 71 | size_t Tell() const { return count_; } 72 | 73 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 74 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 75 | void Flush() { RAPIDJSON_ASSERT(false); } 76 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 77 | 78 | // For encoding detection only. 79 | const Ch* Peek4() const { 80 | RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream. 81 | int i; 82 | bool hasError = false; 83 | for (i = 0; i < 4; ++i) { 84 | typename StreamType::int_type c = stream_.get(); 85 | if (c == StreamType::traits_type::eof()) { 86 | hasError = true; 87 | stream_.clear(); 88 | break; 89 | } 90 | peekBuffer_[i] = static_cast(c); 91 | } 92 | for (--i; i >= 0; --i) 93 | stream_.putback(peekBuffer_[i]); 94 | return !hasError ? peekBuffer_ : 0; 95 | } 96 | 97 | private: 98 | BasicIStreamWrapper(const BasicIStreamWrapper&); 99 | BasicIStreamWrapper& operator=(const BasicIStreamWrapper&); 100 | 101 | StreamType& stream_; 102 | size_t count_; //!< Number of characters read. Note: 103 | mutable Ch peekBuffer_[4]; 104 | }; 105 | 106 | typedef BasicIStreamWrapper IStreamWrapper; 107 | typedef BasicIStreamWrapper WIStreamWrapper; 108 | 109 | #if defined(__clang__) || defined(_MSC_VER) 110 | RAPIDJSON_DIAG_POP 111 | #endif 112 | 113 | RAPIDJSON_NAMESPACE_END 114 | 115 | #endif // RAPIDJSON_ISTREAMWRAPPER_H_ 116 | -------------------------------------------------------------------------------- /rapidjson/memorybuffer.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_MEMORYBUFFER_H_ 16 | #define RAPIDJSON_MEMORYBUFFER_H_ 17 | 18 | #include "stream.h" 19 | #include "internal/stack.h" 20 | 21 | RAPIDJSON_NAMESPACE_BEGIN 22 | 23 | //! Represents an in-memory output byte stream. 24 | /*! 25 | This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. 26 | 27 | It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. 28 | 29 | Differences between MemoryBuffer and StringBuffer: 30 | 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. 31 | 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. 32 | 33 | \tparam Allocator type for allocating memory buffer. 34 | \note implements Stream concept 35 | */ 36 | template 37 | struct GenericMemoryBuffer { 38 | typedef char Ch; // byte 39 | 40 | GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 41 | 42 | void Put(Ch c) { *stack_.template Push() = c; } 43 | void Flush() {} 44 | 45 | void Clear() { stack_.Clear(); } 46 | void ShrinkToFit() { stack_.ShrinkToFit(); } 47 | Ch* Push(size_t count) { return stack_.template Push(count); } 48 | void Pop(size_t count) { stack_.template Pop(count); } 49 | 50 | const Ch* GetBuffer() const { 51 | return stack_.template Bottom(); 52 | } 53 | 54 | size_t GetSize() const { return stack_.GetSize(); } 55 | 56 | static const size_t kDefaultCapacity = 256; 57 | mutable internal::Stack stack_; 58 | }; 59 | 60 | typedef GenericMemoryBuffer<> MemoryBuffer; 61 | 62 | //! Implement specialized version of PutN() with memset() for better performance. 63 | template<> 64 | inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { 65 | std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); 66 | } 67 | 68 | RAPIDJSON_NAMESPACE_END 69 | 70 | #endif // RAPIDJSON_MEMORYBUFFER_H_ 71 | -------------------------------------------------------------------------------- /rapidjson/memorystream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_MEMORYSTREAM_H_ 16 | #define RAPIDJSON_MEMORYSTREAM_H_ 17 | 18 | #include "stream.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(unreachable-code) 23 | RAPIDJSON_DIAG_OFF(missing-noreturn) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Represents an in-memory input byte stream. 29 | /*! 30 | This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. 31 | 32 | It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. 33 | 34 | Differences between MemoryStream and StringStream: 35 | 1. StringStream has encoding but MemoryStream is a byte stream. 36 | 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. 37 | 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). 38 | \note implements Stream concept 39 | */ 40 | struct MemoryStream { 41 | typedef char Ch; // byte 42 | 43 | MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} 44 | 45 | Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } 46 | Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } 47 | size_t Tell() const { return static_cast(src_ - begin_); } 48 | 49 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 50 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 51 | void Flush() { RAPIDJSON_ASSERT(false); } 52 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 53 | 54 | // For encoding detection only. 55 | const Ch* Peek4() const { 56 | return Tell() + 4 <= size_ ? src_ : 0; 57 | } 58 | 59 | const Ch* src_; //!< Current read position. 60 | const Ch* begin_; //!< Original head of the string. 61 | const Ch* end_; //!< End of stream. 62 | size_t size_; //!< Size of the stream. 63 | }; 64 | 65 | RAPIDJSON_NAMESPACE_END 66 | 67 | #ifdef __clang__ 68 | RAPIDJSON_DIAG_POP 69 | #endif 70 | 71 | #endif // RAPIDJSON_MEMORYBUFFER_H_ 72 | -------------------------------------------------------------------------------- /rapidjson/msinttypes/inttypes.h: -------------------------------------------------------------------------------- 1 | // ISO C9x compliant inttypes.h for Microsoft Visual Studio 2 | // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 3 | // 4 | // Copyright (c) 2006-2013 Alexander Chemeris 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | // 9 | // 1. Redistributions of source code must retain the above copyright notice, 10 | // this list of conditions and the following disclaimer. 11 | // 12 | // 2. Redistributions in binary form must reproduce the above copyright 13 | // notice, this list of conditions and the following disclaimer in the 14 | // documentation and/or other materials provided with the distribution. 15 | // 16 | // 3. Neither the name of the product nor the names of its contributors may 17 | // be used to endorse or promote products derived from this software 18 | // without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 23 | // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 | // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 | // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | // 31 | /////////////////////////////////////////////////////////////////////////////// 32 | 33 | // The above software in this distribution may have been modified by 34 | // THL A29 Limited ("Tencent Modifications"). 35 | // All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. 36 | 37 | #ifndef _MSC_VER // [ 38 | #error "Use this header only with Microsoft Visual C++ compilers!" 39 | #endif // _MSC_VER ] 40 | 41 | #ifndef _MSC_INTTYPES_H_ // [ 42 | #define _MSC_INTTYPES_H_ 43 | 44 | #if _MSC_VER > 1000 45 | #pragma once 46 | #endif 47 | 48 | #include "stdint.h" 49 | 50 | // miloyip: VC supports inttypes.h since VC2013 51 | #if _MSC_VER >= 1800 52 | #include 53 | #else 54 | 55 | // 7.8 Format conversion of integer types 56 | 57 | typedef struct { 58 | intmax_t quot; 59 | intmax_t rem; 60 | } imaxdiv_t; 61 | 62 | // 7.8.1 Macros for format specifiers 63 | 64 | #if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 65 | 66 | // The fprintf macros for signed integers are: 67 | #define PRId8 "d" 68 | #define PRIi8 "i" 69 | #define PRIdLEAST8 "d" 70 | #define PRIiLEAST8 "i" 71 | #define PRIdFAST8 "d" 72 | #define PRIiFAST8 "i" 73 | 74 | #define PRId16 "hd" 75 | #define PRIi16 "hi" 76 | #define PRIdLEAST16 "hd" 77 | #define PRIiLEAST16 "hi" 78 | #define PRIdFAST16 "hd" 79 | #define PRIiFAST16 "hi" 80 | 81 | #define PRId32 "I32d" 82 | #define PRIi32 "I32i" 83 | #define PRIdLEAST32 "I32d" 84 | #define PRIiLEAST32 "I32i" 85 | #define PRIdFAST32 "I32d" 86 | #define PRIiFAST32 "I32i" 87 | 88 | #define PRId64 "I64d" 89 | #define PRIi64 "I64i" 90 | #define PRIdLEAST64 "I64d" 91 | #define PRIiLEAST64 "I64i" 92 | #define PRIdFAST64 "I64d" 93 | #define PRIiFAST64 "I64i" 94 | 95 | #define PRIdMAX "I64d" 96 | #define PRIiMAX "I64i" 97 | 98 | #define PRIdPTR "Id" 99 | #define PRIiPTR "Ii" 100 | 101 | // The fprintf macros for unsigned integers are: 102 | #define PRIo8 "o" 103 | #define PRIu8 "u" 104 | #define PRIx8 "x" 105 | #define PRIX8 "X" 106 | #define PRIoLEAST8 "o" 107 | #define PRIuLEAST8 "u" 108 | #define PRIxLEAST8 "x" 109 | #define PRIXLEAST8 "X" 110 | #define PRIoFAST8 "o" 111 | #define PRIuFAST8 "u" 112 | #define PRIxFAST8 "x" 113 | #define PRIXFAST8 "X" 114 | 115 | #define PRIo16 "ho" 116 | #define PRIu16 "hu" 117 | #define PRIx16 "hx" 118 | #define PRIX16 "hX" 119 | #define PRIoLEAST16 "ho" 120 | #define PRIuLEAST16 "hu" 121 | #define PRIxLEAST16 "hx" 122 | #define PRIXLEAST16 "hX" 123 | #define PRIoFAST16 "ho" 124 | #define PRIuFAST16 "hu" 125 | #define PRIxFAST16 "hx" 126 | #define PRIXFAST16 "hX" 127 | 128 | #define PRIo32 "I32o" 129 | #define PRIu32 "I32u" 130 | #define PRIx32 "I32x" 131 | #define PRIX32 "I32X" 132 | #define PRIoLEAST32 "I32o" 133 | #define PRIuLEAST32 "I32u" 134 | #define PRIxLEAST32 "I32x" 135 | #define PRIXLEAST32 "I32X" 136 | #define PRIoFAST32 "I32o" 137 | #define PRIuFAST32 "I32u" 138 | #define PRIxFAST32 "I32x" 139 | #define PRIXFAST32 "I32X" 140 | 141 | #define PRIo64 "I64o" 142 | #define PRIu64 "I64u" 143 | #define PRIx64 "I64x" 144 | #define PRIX64 "I64X" 145 | #define PRIoLEAST64 "I64o" 146 | #define PRIuLEAST64 "I64u" 147 | #define PRIxLEAST64 "I64x" 148 | #define PRIXLEAST64 "I64X" 149 | #define PRIoFAST64 "I64o" 150 | #define PRIuFAST64 "I64u" 151 | #define PRIxFAST64 "I64x" 152 | #define PRIXFAST64 "I64X" 153 | 154 | #define PRIoMAX "I64o" 155 | #define PRIuMAX "I64u" 156 | #define PRIxMAX "I64x" 157 | #define PRIXMAX "I64X" 158 | 159 | #define PRIoPTR "Io" 160 | #define PRIuPTR "Iu" 161 | #define PRIxPTR "Ix" 162 | #define PRIXPTR "IX" 163 | 164 | // The fscanf macros for signed integers are: 165 | #define SCNd8 "d" 166 | #define SCNi8 "i" 167 | #define SCNdLEAST8 "d" 168 | #define SCNiLEAST8 "i" 169 | #define SCNdFAST8 "d" 170 | #define SCNiFAST8 "i" 171 | 172 | #define SCNd16 "hd" 173 | #define SCNi16 "hi" 174 | #define SCNdLEAST16 "hd" 175 | #define SCNiLEAST16 "hi" 176 | #define SCNdFAST16 "hd" 177 | #define SCNiFAST16 "hi" 178 | 179 | #define SCNd32 "ld" 180 | #define SCNi32 "li" 181 | #define SCNdLEAST32 "ld" 182 | #define SCNiLEAST32 "li" 183 | #define SCNdFAST32 "ld" 184 | #define SCNiFAST32 "li" 185 | 186 | #define SCNd64 "I64d" 187 | #define SCNi64 "I64i" 188 | #define SCNdLEAST64 "I64d" 189 | #define SCNiLEAST64 "I64i" 190 | #define SCNdFAST64 "I64d" 191 | #define SCNiFAST64 "I64i" 192 | 193 | #define SCNdMAX "I64d" 194 | #define SCNiMAX "I64i" 195 | 196 | #ifdef _WIN64 // [ 197 | # define SCNdPTR "I64d" 198 | # define SCNiPTR "I64i" 199 | #else // _WIN64 ][ 200 | # define SCNdPTR "ld" 201 | # define SCNiPTR "li" 202 | #endif // _WIN64 ] 203 | 204 | // The fscanf macros for unsigned integers are: 205 | #define SCNo8 "o" 206 | #define SCNu8 "u" 207 | #define SCNx8 "x" 208 | #define SCNX8 "X" 209 | #define SCNoLEAST8 "o" 210 | #define SCNuLEAST8 "u" 211 | #define SCNxLEAST8 "x" 212 | #define SCNXLEAST8 "X" 213 | #define SCNoFAST8 "o" 214 | #define SCNuFAST8 "u" 215 | #define SCNxFAST8 "x" 216 | #define SCNXFAST8 "X" 217 | 218 | #define SCNo16 "ho" 219 | #define SCNu16 "hu" 220 | #define SCNx16 "hx" 221 | #define SCNX16 "hX" 222 | #define SCNoLEAST16 "ho" 223 | #define SCNuLEAST16 "hu" 224 | #define SCNxLEAST16 "hx" 225 | #define SCNXLEAST16 "hX" 226 | #define SCNoFAST16 "ho" 227 | #define SCNuFAST16 "hu" 228 | #define SCNxFAST16 "hx" 229 | #define SCNXFAST16 "hX" 230 | 231 | #define SCNo32 "lo" 232 | #define SCNu32 "lu" 233 | #define SCNx32 "lx" 234 | #define SCNX32 "lX" 235 | #define SCNoLEAST32 "lo" 236 | #define SCNuLEAST32 "lu" 237 | #define SCNxLEAST32 "lx" 238 | #define SCNXLEAST32 "lX" 239 | #define SCNoFAST32 "lo" 240 | #define SCNuFAST32 "lu" 241 | #define SCNxFAST32 "lx" 242 | #define SCNXFAST32 "lX" 243 | 244 | #define SCNo64 "I64o" 245 | #define SCNu64 "I64u" 246 | #define SCNx64 "I64x" 247 | #define SCNX64 "I64X" 248 | #define SCNoLEAST64 "I64o" 249 | #define SCNuLEAST64 "I64u" 250 | #define SCNxLEAST64 "I64x" 251 | #define SCNXLEAST64 "I64X" 252 | #define SCNoFAST64 "I64o" 253 | #define SCNuFAST64 "I64u" 254 | #define SCNxFAST64 "I64x" 255 | #define SCNXFAST64 "I64X" 256 | 257 | #define SCNoMAX "I64o" 258 | #define SCNuMAX "I64u" 259 | #define SCNxMAX "I64x" 260 | #define SCNXMAX "I64X" 261 | 262 | #ifdef _WIN64 // [ 263 | # define SCNoPTR "I64o" 264 | # define SCNuPTR "I64u" 265 | # define SCNxPTR "I64x" 266 | # define SCNXPTR "I64X" 267 | #else // _WIN64 ][ 268 | # define SCNoPTR "lo" 269 | # define SCNuPTR "lu" 270 | # define SCNxPTR "lx" 271 | # define SCNXPTR "lX" 272 | #endif // _WIN64 ] 273 | 274 | #endif // __STDC_FORMAT_MACROS ] 275 | 276 | // 7.8.2 Functions for greatest-width integer types 277 | 278 | // 7.8.2.1 The imaxabs function 279 | #define imaxabs _abs64 280 | 281 | // 7.8.2.2 The imaxdiv function 282 | 283 | // This is modified version of div() function from Microsoft's div.c found 284 | // in %MSVC.NET%\crt\src\div.c 285 | #ifdef STATIC_IMAXDIV // [ 286 | static 287 | #else // STATIC_IMAXDIV ][ 288 | _inline 289 | #endif // STATIC_IMAXDIV ] 290 | imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) 291 | { 292 | imaxdiv_t result; 293 | 294 | result.quot = numer / denom; 295 | result.rem = numer % denom; 296 | 297 | if (numer < 0 && result.rem > 0) { 298 | // did division wrong; must fix up 299 | ++result.quot; 300 | result.rem -= denom; 301 | } 302 | 303 | return result; 304 | } 305 | 306 | // 7.8.2.3 The strtoimax and strtoumax functions 307 | #define strtoimax _strtoi64 308 | #define strtoumax _strtoui64 309 | 310 | // 7.8.2.4 The wcstoimax and wcstoumax functions 311 | #define wcstoimax _wcstoi64 312 | #define wcstoumax _wcstoui64 313 | 314 | #endif // _MSC_VER >= 1800 315 | 316 | #endif // _MSC_INTTYPES_H_ ] 317 | -------------------------------------------------------------------------------- /rapidjson/msinttypes/stdint.h: -------------------------------------------------------------------------------- 1 | // ISO C9x compliant stdint.h for Microsoft Visual Studio 2 | // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 3 | // 4 | // Copyright (c) 2006-2013 Alexander Chemeris 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are met: 8 | // 9 | // 1. Redistributions of source code must retain the above copyright notice, 10 | // this list of conditions and the following disclaimer. 11 | // 12 | // 2. Redistributions in binary form must reproduce the above copyright 13 | // notice, this list of conditions and the following disclaimer in the 14 | // documentation and/or other materials provided with the distribution. 15 | // 16 | // 3. Neither the name of the product nor the names of its contributors may 17 | // be used to endorse or promote products derived from this software 18 | // without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 23 | // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 | // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 | // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | // 31 | /////////////////////////////////////////////////////////////////////////////// 32 | 33 | // The above software in this distribution may have been modified by 34 | // THL A29 Limited ("Tencent Modifications"). 35 | // All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. 36 | 37 | #ifndef _MSC_VER // [ 38 | #error "Use this header only with Microsoft Visual C++ compilers!" 39 | #endif // _MSC_VER ] 40 | 41 | #ifndef _MSC_STDINT_H_ // [ 42 | #define _MSC_STDINT_H_ 43 | 44 | #if _MSC_VER > 1000 45 | #pragma once 46 | #endif 47 | 48 | // miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010. 49 | #if _MSC_VER >= 1600 // [ 50 | #include 51 | 52 | #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 53 | 54 | #undef INT8_C 55 | #undef INT16_C 56 | #undef INT32_C 57 | #undef INT64_C 58 | #undef UINT8_C 59 | #undef UINT16_C 60 | #undef UINT32_C 61 | #undef UINT64_C 62 | 63 | // 7.18.4.1 Macros for minimum-width integer constants 64 | 65 | #define INT8_C(val) val##i8 66 | #define INT16_C(val) val##i16 67 | #define INT32_C(val) val##i32 68 | #define INT64_C(val) val##i64 69 | 70 | #define UINT8_C(val) val##ui8 71 | #define UINT16_C(val) val##ui16 72 | #define UINT32_C(val) val##ui32 73 | #define UINT64_C(val) val##ui64 74 | 75 | // 7.18.4.2 Macros for greatest-width integer constants 76 | // These #ifndef's are needed to prevent collisions with . 77 | // Check out Issue 9 for the details. 78 | #ifndef INTMAX_C // [ 79 | # define INTMAX_C INT64_C 80 | #endif // INTMAX_C ] 81 | #ifndef UINTMAX_C // [ 82 | # define UINTMAX_C UINT64_C 83 | #endif // UINTMAX_C ] 84 | 85 | #endif // __STDC_CONSTANT_MACROS ] 86 | 87 | #else // ] _MSC_VER >= 1700 [ 88 | 89 | #include 90 | 91 | // For Visual Studio 6 in C++ mode and for many Visual Studio versions when 92 | // compiling for ARM we have to wrap include with 'extern "C++" {}' 93 | // or compiler would give many errors like this: 94 | // error C2733: second C linkage of overloaded function 'wmemchr' not allowed 95 | #if defined(__cplusplus) && !defined(_M_ARM) 96 | extern "C" { 97 | #endif 98 | # include 99 | #if defined(__cplusplus) && !defined(_M_ARM) 100 | } 101 | #endif 102 | 103 | // Define _W64 macros to mark types changing their size, like intptr_t. 104 | #ifndef _W64 105 | # if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 106 | # define _W64 __w64 107 | # else 108 | # define _W64 109 | # endif 110 | #endif 111 | 112 | 113 | // 7.18.1 Integer types 114 | 115 | // 7.18.1.1 Exact-width integer types 116 | 117 | // Visual Studio 6 and Embedded Visual C++ 4 doesn't 118 | // realize that, e.g. char has the same size as __int8 119 | // so we give up on __intX for them. 120 | #if (_MSC_VER < 1300) 121 | typedef signed char int8_t; 122 | typedef signed short int16_t; 123 | typedef signed int int32_t; 124 | typedef unsigned char uint8_t; 125 | typedef unsigned short uint16_t; 126 | typedef unsigned int uint32_t; 127 | #else 128 | typedef signed __int8 int8_t; 129 | typedef signed __int16 int16_t; 130 | typedef signed __int32 int32_t; 131 | typedef unsigned __int8 uint8_t; 132 | typedef unsigned __int16 uint16_t; 133 | typedef unsigned __int32 uint32_t; 134 | #endif 135 | typedef signed __int64 int64_t; 136 | typedef unsigned __int64 uint64_t; 137 | 138 | 139 | // 7.18.1.2 Minimum-width integer types 140 | typedef int8_t int_least8_t; 141 | typedef int16_t int_least16_t; 142 | typedef int32_t int_least32_t; 143 | typedef int64_t int_least64_t; 144 | typedef uint8_t uint_least8_t; 145 | typedef uint16_t uint_least16_t; 146 | typedef uint32_t uint_least32_t; 147 | typedef uint64_t uint_least64_t; 148 | 149 | // 7.18.1.3 Fastest minimum-width integer types 150 | typedef int8_t int_fast8_t; 151 | typedef int16_t int_fast16_t; 152 | typedef int32_t int_fast32_t; 153 | typedef int64_t int_fast64_t; 154 | typedef uint8_t uint_fast8_t; 155 | typedef uint16_t uint_fast16_t; 156 | typedef uint32_t uint_fast32_t; 157 | typedef uint64_t uint_fast64_t; 158 | 159 | // 7.18.1.4 Integer types capable of holding object pointers 160 | #ifdef _WIN64 // [ 161 | typedef signed __int64 intptr_t; 162 | typedef unsigned __int64 uintptr_t; 163 | #else // _WIN64 ][ 164 | typedef _W64 signed int intptr_t; 165 | typedef _W64 unsigned int uintptr_t; 166 | #endif // _WIN64 ] 167 | 168 | // 7.18.1.5 Greatest-width integer types 169 | typedef int64_t intmax_t; 170 | typedef uint64_t uintmax_t; 171 | 172 | 173 | // 7.18.2 Limits of specified-width integer types 174 | 175 | #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 176 | 177 | // 7.18.2.1 Limits of exact-width integer types 178 | #define INT8_MIN ((int8_t)_I8_MIN) 179 | #define INT8_MAX _I8_MAX 180 | #define INT16_MIN ((int16_t)_I16_MIN) 181 | #define INT16_MAX _I16_MAX 182 | #define INT32_MIN ((int32_t)_I32_MIN) 183 | #define INT32_MAX _I32_MAX 184 | #define INT64_MIN ((int64_t)_I64_MIN) 185 | #define INT64_MAX _I64_MAX 186 | #define UINT8_MAX _UI8_MAX 187 | #define UINT16_MAX _UI16_MAX 188 | #define UINT32_MAX _UI32_MAX 189 | #define UINT64_MAX _UI64_MAX 190 | 191 | // 7.18.2.2 Limits of minimum-width integer types 192 | #define INT_LEAST8_MIN INT8_MIN 193 | #define INT_LEAST8_MAX INT8_MAX 194 | #define INT_LEAST16_MIN INT16_MIN 195 | #define INT_LEAST16_MAX INT16_MAX 196 | #define INT_LEAST32_MIN INT32_MIN 197 | #define INT_LEAST32_MAX INT32_MAX 198 | #define INT_LEAST64_MIN INT64_MIN 199 | #define INT_LEAST64_MAX INT64_MAX 200 | #define UINT_LEAST8_MAX UINT8_MAX 201 | #define UINT_LEAST16_MAX UINT16_MAX 202 | #define UINT_LEAST32_MAX UINT32_MAX 203 | #define UINT_LEAST64_MAX UINT64_MAX 204 | 205 | // 7.18.2.3 Limits of fastest minimum-width integer types 206 | #define INT_FAST8_MIN INT8_MIN 207 | #define INT_FAST8_MAX INT8_MAX 208 | #define INT_FAST16_MIN INT16_MIN 209 | #define INT_FAST16_MAX INT16_MAX 210 | #define INT_FAST32_MIN INT32_MIN 211 | #define INT_FAST32_MAX INT32_MAX 212 | #define INT_FAST64_MIN INT64_MIN 213 | #define INT_FAST64_MAX INT64_MAX 214 | #define UINT_FAST8_MAX UINT8_MAX 215 | #define UINT_FAST16_MAX UINT16_MAX 216 | #define UINT_FAST32_MAX UINT32_MAX 217 | #define UINT_FAST64_MAX UINT64_MAX 218 | 219 | // 7.18.2.4 Limits of integer types capable of holding object pointers 220 | #ifdef _WIN64 // [ 221 | # define INTPTR_MIN INT64_MIN 222 | # define INTPTR_MAX INT64_MAX 223 | # define UINTPTR_MAX UINT64_MAX 224 | #else // _WIN64 ][ 225 | # define INTPTR_MIN INT32_MIN 226 | # define INTPTR_MAX INT32_MAX 227 | # define UINTPTR_MAX UINT32_MAX 228 | #endif // _WIN64 ] 229 | 230 | // 7.18.2.5 Limits of greatest-width integer types 231 | #define INTMAX_MIN INT64_MIN 232 | #define INTMAX_MAX INT64_MAX 233 | #define UINTMAX_MAX UINT64_MAX 234 | 235 | // 7.18.3 Limits of other integer types 236 | 237 | #ifdef _WIN64 // [ 238 | # define PTRDIFF_MIN _I64_MIN 239 | # define PTRDIFF_MAX _I64_MAX 240 | #else // _WIN64 ][ 241 | # define PTRDIFF_MIN _I32_MIN 242 | # define PTRDIFF_MAX _I32_MAX 243 | #endif // _WIN64 ] 244 | 245 | #define SIG_ATOMIC_MIN INT_MIN 246 | #define SIG_ATOMIC_MAX INT_MAX 247 | 248 | #ifndef SIZE_MAX // [ 249 | # ifdef _WIN64 // [ 250 | # define SIZE_MAX _UI64_MAX 251 | # else // _WIN64 ][ 252 | # define SIZE_MAX _UI32_MAX 253 | # endif // _WIN64 ] 254 | #endif // SIZE_MAX ] 255 | 256 | // WCHAR_MIN and WCHAR_MAX are also defined in 257 | #ifndef WCHAR_MIN // [ 258 | # define WCHAR_MIN 0 259 | #endif // WCHAR_MIN ] 260 | #ifndef WCHAR_MAX // [ 261 | # define WCHAR_MAX _UI16_MAX 262 | #endif // WCHAR_MAX ] 263 | 264 | #define WINT_MIN 0 265 | #define WINT_MAX _UI16_MAX 266 | 267 | #endif // __STDC_LIMIT_MACROS ] 268 | 269 | 270 | // 7.18.4 Limits of other integer types 271 | 272 | #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 273 | 274 | // 7.18.4.1 Macros for minimum-width integer constants 275 | 276 | #define INT8_C(val) val##i8 277 | #define INT16_C(val) val##i16 278 | #define INT32_C(val) val##i32 279 | #define INT64_C(val) val##i64 280 | 281 | #define UINT8_C(val) val##ui8 282 | #define UINT16_C(val) val##ui16 283 | #define UINT32_C(val) val##ui32 284 | #define UINT64_C(val) val##ui64 285 | 286 | // 7.18.4.2 Macros for greatest-width integer constants 287 | // These #ifndef's are needed to prevent collisions with . 288 | // Check out Issue 9 for the details. 289 | #ifndef INTMAX_C // [ 290 | # define INTMAX_C INT64_C 291 | #endif // INTMAX_C ] 292 | #ifndef UINTMAX_C // [ 293 | # define UINTMAX_C UINT64_C 294 | #endif // UINTMAX_C ] 295 | 296 | #endif // __STDC_CONSTANT_MACROS ] 297 | 298 | #endif // _MSC_VER >= 1600 ] 299 | 300 | #endif // _MSC_STDINT_H_ ] 301 | -------------------------------------------------------------------------------- /rapidjson/ostreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_OSTREAMWRAPPER_H_ 16 | #define RAPIDJSON_OSTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. 29 | /*! 30 | The classes can be wrapped including but not limited to: 31 | 32 | - \c std::ostringstream 33 | - \c std::stringstream 34 | - \c std::wpstringstream 35 | - \c std::wstringstream 36 | - \c std::ifstream 37 | - \c std::fstream 38 | - \c std::wofstream 39 | - \c std::wfstream 40 | 41 | \tparam StreamType Class derived from \c std::basic_ostream. 42 | */ 43 | 44 | template 45 | class BasicOStreamWrapper { 46 | public: 47 | typedef typename StreamType::char_type Ch; 48 | BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} 49 | 50 | void Put(Ch c) { 51 | stream_.put(c); 52 | } 53 | 54 | void Flush() { 55 | stream_.flush(); 56 | } 57 | 58 | // Not implemented 59 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; } 60 | char Take() { RAPIDJSON_ASSERT(false); return 0; } 61 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 62 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 63 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 64 | 65 | private: 66 | BasicOStreamWrapper(const BasicOStreamWrapper&); 67 | BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); 68 | 69 | StreamType& stream_; 70 | }; 71 | 72 | typedef BasicOStreamWrapper OStreamWrapper; 73 | typedef BasicOStreamWrapper WOStreamWrapper; 74 | 75 | #ifdef __clang__ 76 | RAPIDJSON_DIAG_POP 77 | #endif 78 | 79 | RAPIDJSON_NAMESPACE_END 80 | 81 | #endif // RAPIDJSON_OSTREAMWRAPPER_H_ 82 | -------------------------------------------------------------------------------- /rapidjson/prettywriter.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_PRETTYWRITER_H_ 16 | #define RAPIDJSON_PRETTYWRITER_H_ 17 | 18 | #include "writer.h" 19 | 20 | #ifdef __GNUC__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(effc++) 23 | #endif 24 | 25 | #if defined(__clang__) 26 | RAPIDJSON_DIAG_PUSH 27 | RAPIDJSON_DIAG_OFF(c++98-compat) 28 | #endif 29 | 30 | RAPIDJSON_NAMESPACE_BEGIN 31 | 32 | //! Combination of PrettyWriter format flags. 33 | /*! \see PrettyWriter::SetFormatOptions 34 | */ 35 | enum PrettyFormatOptions { 36 | kFormatDefault = 0, //!< Default pretty formatting. 37 | kFormatSingleLineArray = 1 //!< Format arrays on a single line. 38 | }; 39 | 40 | //! Writer with indentation and spacing. 41 | /*! 42 | \tparam OutputStream Type of ouptut os. 43 | \tparam SourceEncoding Encoding of source string. 44 | \tparam TargetEncoding Encoding of output stream. 45 | \tparam StackAllocator Type of allocator for allocating memory of stack. 46 | */ 47 | template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> 48 | class PrettyWriter : public Writer { 49 | public: 50 | typedef Writer Base; 51 | typedef typename Base::Ch Ch; 52 | 53 | //! Constructor 54 | /*! \param os Output stream. 55 | \param allocator User supplied allocator. If it is null, it will create a private one. 56 | \param levelDepth Initial capacity of stack. 57 | */ 58 | explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : 59 | Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} 60 | 61 | 62 | explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : 63 | Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} 64 | 65 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 66 | PrettyWriter(PrettyWriter&& rhs) : 67 | Base(std::forward(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {} 68 | #endif 69 | 70 | //! Set custom indentation. 71 | /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r'). 72 | \param indentCharCount Number of indent characters for each indentation level. 73 | \note The default indentation is 4 spaces. 74 | */ 75 | PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { 76 | RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); 77 | indentChar_ = indentChar; 78 | indentCharCount_ = indentCharCount; 79 | return *this; 80 | } 81 | 82 | //! Set pretty writer formatting options. 83 | /*! \param options Formatting options. 84 | */ 85 | PrettyWriter& SetFormatOptions(PrettyFormatOptions options) { 86 | formatOptions_ = options; 87 | return *this; 88 | } 89 | 90 | /*! @name Implementation of Handler 91 | \see Handler 92 | */ 93 | //@{ 94 | 95 | bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); } 96 | bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); } 97 | bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); } 98 | bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); } 99 | bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); } 100 | bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); } 101 | bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); } 102 | 103 | bool RawNumber(const Ch* str, SizeType length, bool copy = false) { 104 | RAPIDJSON_ASSERT(str != 0); 105 | (void)copy; 106 | PrettyPrefix(kNumberType); 107 | return Base::WriteString(str, length); 108 | } 109 | 110 | bool String(const Ch* str, SizeType length, bool copy = false) { 111 | RAPIDJSON_ASSERT(str != 0); 112 | (void)copy; 113 | PrettyPrefix(kStringType); 114 | return Base::WriteString(str, length); 115 | } 116 | 117 | #if RAPIDJSON_HAS_STDSTRING 118 | bool String(const std::basic_string& str) { 119 | return String(str.data(), SizeType(str.size())); 120 | } 121 | #endif 122 | 123 | bool StartObject() { 124 | PrettyPrefix(kObjectType); 125 | new (Base::level_stack_.template Push()) typename Base::Level(false); 126 | return Base::WriteStartObject(); 127 | } 128 | 129 | bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } 130 | 131 | #if RAPIDJSON_HAS_STDSTRING 132 | bool Key(const std::basic_string& str) { 133 | return Key(str.data(), SizeType(str.size())); 134 | } 135 | #endif 136 | 137 | bool EndObject(SizeType memberCount = 0) { 138 | (void)memberCount; 139 | RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); // not inside an Object 140 | RAPIDJSON_ASSERT(!Base::level_stack_.template Top()->inArray); // currently inside an Array, not Object 141 | RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top()->valueCount % 2); // Object has a Key without a Value 142 | 143 | bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; 144 | 145 | if (!empty) { 146 | Base::os_->Put('\n'); 147 | WriteIndent(); 148 | } 149 | bool ret = Base::WriteEndObject(); 150 | (void)ret; 151 | RAPIDJSON_ASSERT(ret == true); 152 | if (Base::level_stack_.Empty()) // end of json text 153 | Base::Flush(); 154 | return true; 155 | } 156 | 157 | bool StartArray() { 158 | PrettyPrefix(kArrayType); 159 | new (Base::level_stack_.template Push()) typename Base::Level(true); 160 | return Base::WriteStartArray(); 161 | } 162 | 163 | bool EndArray(SizeType memberCount = 0) { 164 | (void)memberCount; 165 | RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); 166 | RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); 167 | bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; 168 | 169 | if (!empty && !(formatOptions_ & kFormatSingleLineArray)) { 170 | Base::os_->Put('\n'); 171 | WriteIndent(); 172 | } 173 | bool ret = Base::WriteEndArray(); 174 | (void)ret; 175 | RAPIDJSON_ASSERT(ret == true); 176 | if (Base::level_stack_.Empty()) // end of json text 177 | Base::Flush(); 178 | return true; 179 | } 180 | 181 | //@} 182 | 183 | /*! @name Convenience extensions */ 184 | //@{ 185 | 186 | //! Simpler but slower overload. 187 | bool String(const Ch* str) { return String(str, internal::StrLen(str)); } 188 | bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } 189 | 190 | //@} 191 | 192 | //! Write a raw JSON value. 193 | /*! 194 | For user to write a stringified JSON as a value. 195 | 196 | \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. 197 | \param length Length of the json. 198 | \param type Type of the root of json. 199 | \note When using PrettyWriter::RawValue(), the result json may not be indented correctly. 200 | */ 201 | bool RawValue(const Ch* json, size_t length, Type type) { 202 | RAPIDJSON_ASSERT(json != 0); 203 | PrettyPrefix(type); 204 | return Base::WriteRawValue(json, length); 205 | } 206 | 207 | protected: 208 | void PrettyPrefix(Type type) { 209 | (void)type; 210 | if (Base::level_stack_.GetSize() != 0) { // this value is not at root 211 | typename Base::Level* level = Base::level_stack_.template Top(); 212 | 213 | if (level->inArray) { 214 | if (level->valueCount > 0) { 215 | Base::os_->Put(','); // add comma if it is not the first element in array 216 | if (formatOptions_ & kFormatSingleLineArray) 217 | Base::os_->Put(' '); 218 | } 219 | 220 | if (!(formatOptions_ & kFormatSingleLineArray)) { 221 | Base::os_->Put('\n'); 222 | WriteIndent(); 223 | } 224 | } 225 | else { // in object 226 | if (level->valueCount > 0) { 227 | if (level->valueCount % 2 == 0) { 228 | Base::os_->Put(','); 229 | Base::os_->Put('\n'); 230 | } 231 | else { 232 | Base::os_->Put(':'); 233 | Base::os_->Put(' '); 234 | } 235 | } 236 | else 237 | Base::os_->Put('\n'); 238 | 239 | if (level->valueCount % 2 == 0) 240 | WriteIndent(); 241 | } 242 | if (!level->inArray && level->valueCount % 2 == 0) 243 | RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name 244 | level->valueCount++; 245 | } 246 | else { 247 | RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. 248 | Base::hasRoot_ = true; 249 | } 250 | } 251 | 252 | void WriteIndent() { 253 | size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; 254 | PutN(*Base::os_, static_cast(indentChar_), count); 255 | } 256 | 257 | Ch indentChar_; 258 | unsigned indentCharCount_; 259 | PrettyFormatOptions formatOptions_; 260 | 261 | private: 262 | // Prohibit copy constructor & assignment operator. 263 | PrettyWriter(const PrettyWriter&); 264 | PrettyWriter& operator=(const PrettyWriter&); 265 | }; 266 | 267 | RAPIDJSON_NAMESPACE_END 268 | 269 | #if defined(__clang__) 270 | RAPIDJSON_DIAG_POP 271 | #endif 272 | 273 | #ifdef __GNUC__ 274 | RAPIDJSON_DIAG_POP 275 | #endif 276 | 277 | #endif // RAPIDJSON_RAPIDJSON_H_ 278 | -------------------------------------------------------------------------------- /rapidjson/stream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #include "rapidjson.h" 16 | 17 | #ifndef RAPIDJSON_STREAM_H_ 18 | #define RAPIDJSON_STREAM_H_ 19 | 20 | #include "encodings.h" 21 | 22 | RAPIDJSON_NAMESPACE_BEGIN 23 | 24 | /////////////////////////////////////////////////////////////////////////////// 25 | // Stream 26 | 27 | /*! \class rapidjson::Stream 28 | \brief Concept for reading and writing characters. 29 | 30 | For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). 31 | 32 | For write-only stream, only need to implement Put() and Flush(). 33 | 34 | \code 35 | concept Stream { 36 | typename Ch; //!< Character type of the stream. 37 | 38 | //! Read the current character from stream without moving the read cursor. 39 | Ch Peek() const; 40 | 41 | //! Read the current character from stream and moving the read cursor to next character. 42 | Ch Take(); 43 | 44 | //! Get the current read cursor. 45 | //! \return Number of characters read from start. 46 | size_t Tell(); 47 | 48 | //! Begin writing operation at the current read pointer. 49 | //! \return The begin writer pointer. 50 | Ch* PutBegin(); 51 | 52 | //! Write a character. 53 | void Put(Ch c); 54 | 55 | //! Flush the buffer. 56 | void Flush(); 57 | 58 | //! End the writing operation. 59 | //! \param begin The begin write pointer returned by PutBegin(). 60 | //! \return Number of characters written. 61 | size_t PutEnd(Ch* begin); 62 | } 63 | \endcode 64 | */ 65 | 66 | //! Provides additional information for stream. 67 | /*! 68 | By using traits pattern, this type provides a default configuration for stream. 69 | For custom stream, this type can be specialized for other configuration. 70 | See TEST(Reader, CustomStringStream) in readertest.cpp for example. 71 | */ 72 | template 73 | struct StreamTraits { 74 | //! Whether to make local copy of stream for optimization during parsing. 75 | /*! 76 | By default, for safety, streams do not use local copy optimization. 77 | Stream that can be copied fast should specialize this, like StreamTraits. 78 | */ 79 | enum { copyOptimization = 0 }; 80 | }; 81 | 82 | //! Reserve n characters for writing to a stream. 83 | template 84 | inline void PutReserve(Stream& stream, size_t count) { 85 | (void)stream; 86 | (void)count; 87 | } 88 | 89 | //! Write character to a stream, presuming buffer is reserved. 90 | template 91 | inline void PutUnsafe(Stream& stream, typename Stream::Ch c) { 92 | stream.Put(c); 93 | } 94 | 95 | //! Put N copies of a character to a stream. 96 | template 97 | inline void PutN(Stream& stream, Ch c, size_t n) { 98 | PutReserve(stream, n); 99 | for (size_t i = 0; i < n; i++) 100 | PutUnsafe(stream, c); 101 | } 102 | 103 | /////////////////////////////////////////////////////////////////////////////// 104 | // StringStream 105 | 106 | //! Read-only string stream. 107 | /*! \note implements Stream concept 108 | */ 109 | template 110 | struct GenericStringStream { 111 | typedef typename Encoding::Ch Ch; 112 | 113 | GenericStringStream(const Ch *src) : src_(src), head_(src) {} 114 | 115 | Ch Peek() const { return *src_; } 116 | Ch Take() { return *src_++; } 117 | size_t Tell() const { return static_cast(src_ - head_); } 118 | 119 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 120 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 121 | void Flush() { RAPIDJSON_ASSERT(false); } 122 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 123 | 124 | const Ch* src_; //!< Current read position. 125 | const Ch* head_; //!< Original head of the string. 126 | }; 127 | 128 | template 129 | struct StreamTraits > { 130 | enum { copyOptimization = 1 }; 131 | }; 132 | 133 | //! String stream with UTF8 encoding. 134 | typedef GenericStringStream > StringStream; 135 | 136 | /////////////////////////////////////////////////////////////////////////////// 137 | // InsituStringStream 138 | 139 | //! A read-write string stream. 140 | /*! This string stream is particularly designed for in-situ parsing. 141 | \note implements Stream concept 142 | */ 143 | template 144 | struct GenericInsituStringStream { 145 | typedef typename Encoding::Ch Ch; 146 | 147 | GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} 148 | 149 | // Read 150 | Ch Peek() { return *src_; } 151 | Ch Take() { return *src_++; } 152 | size_t Tell() { return static_cast(src_ - head_); } 153 | 154 | // Write 155 | void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } 156 | 157 | Ch* PutBegin() { return dst_ = src_; } 158 | size_t PutEnd(Ch* begin) { return static_cast(dst_ - begin); } 159 | void Flush() {} 160 | 161 | Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } 162 | void Pop(size_t count) { dst_ -= count; } 163 | 164 | Ch* src_; 165 | Ch* dst_; 166 | Ch* head_; 167 | }; 168 | 169 | template 170 | struct StreamTraits > { 171 | enum { copyOptimization = 1 }; 172 | }; 173 | 174 | //! Insitu string stream with UTF8 encoding. 175 | typedef GenericInsituStringStream > InsituStringStream; 176 | 177 | RAPIDJSON_NAMESPACE_END 178 | 179 | #endif // RAPIDJSON_STREAM_H_ 180 | -------------------------------------------------------------------------------- /rapidjson/stringbuffer.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_STRINGBUFFER_H_ 16 | #define RAPIDJSON_STRINGBUFFER_H_ 17 | 18 | #include "stream.h" 19 | #include "internal/stack.h" 20 | 21 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 22 | #include // std::move 23 | #endif 24 | 25 | #include "internal/stack.h" 26 | 27 | #if defined(__clang__) 28 | RAPIDJSON_DIAG_PUSH 29 | RAPIDJSON_DIAG_OFF(c++98-compat) 30 | #endif 31 | 32 | RAPIDJSON_NAMESPACE_BEGIN 33 | 34 | //! Represents an in-memory output stream. 35 | /*! 36 | \tparam Encoding Encoding of the stream. 37 | \tparam Allocator type for allocating memory buffer. 38 | \note implements Stream concept 39 | */ 40 | template 41 | class GenericStringBuffer { 42 | public: 43 | typedef typename Encoding::Ch Ch; 44 | 45 | GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 46 | 47 | #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 48 | GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} 49 | GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { 50 | if (&rhs != this) 51 | stack_ = std::move(rhs.stack_); 52 | return *this; 53 | } 54 | #endif 55 | 56 | void Put(Ch c) { *stack_.template Push() = c; } 57 | void PutUnsafe(Ch c) { *stack_.template PushUnsafe() = c; } 58 | void Flush() {} 59 | 60 | void Clear() { stack_.Clear(); } 61 | void ShrinkToFit() { 62 | // Push and pop a null terminator. This is safe. 63 | *stack_.template Push() = '\0'; 64 | stack_.ShrinkToFit(); 65 | stack_.template Pop(1); 66 | } 67 | 68 | void Reserve(size_t count) { stack_.template Reserve(count); } 69 | Ch* Push(size_t count) { return stack_.template Push(count); } 70 | Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe(count); } 71 | void Pop(size_t count) { stack_.template Pop(count); } 72 | 73 | const Ch* GetString() const { 74 | // Push and pop a null terminator. This is safe. 75 | *stack_.template Push() = '\0'; 76 | stack_.template Pop(1); 77 | 78 | return stack_.template Bottom(); 79 | } 80 | 81 | //! Get the size of string in bytes in the string buffer. 82 | size_t GetSize() const { return stack_.GetSize(); } 83 | 84 | //! Get the length of string in Ch in the string buffer. 85 | size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); } 86 | 87 | static const size_t kDefaultCapacity = 256; 88 | mutable internal::Stack stack_; 89 | 90 | private: 91 | // Prohibit copy constructor & assignment operator. 92 | GenericStringBuffer(const GenericStringBuffer&); 93 | GenericStringBuffer& operator=(const GenericStringBuffer&); 94 | }; 95 | 96 | //! String buffer with UTF8 encoding 97 | typedef GenericStringBuffer > StringBuffer; 98 | 99 | template 100 | inline void PutReserve(GenericStringBuffer& stream, size_t count) { 101 | stream.Reserve(count); 102 | } 103 | 104 | template 105 | inline void PutUnsafe(GenericStringBuffer& stream, typename Encoding::Ch c) { 106 | stream.PutUnsafe(c); 107 | } 108 | 109 | //! Implement specialized version of PutN() with memset() for better performance. 110 | template<> 111 | inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { 112 | std::memset(stream.stack_.Push(n), c, n * sizeof(c)); 113 | } 114 | 115 | RAPIDJSON_NAMESPACE_END 116 | 117 | #if defined(__clang__) 118 | RAPIDJSON_DIAG_POP 119 | #endif 120 | 121 | #endif // RAPIDJSON_STRINGBUFFER_H_ 122 | -------------------------------------------------------------------------------- /utils/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.hpp" 2 | 3 | string CUtils::GetAppData() 4 | { 5 | static TCHAR szPath[MAX_PATH]; 6 | SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, szPath); 7 | 8 | return string(szPath); 9 | } 10 | 11 | bool CUtils::dirExists(const string& dirName) 12 | { 13 | DWORD ftyp = GetFileAttributesA(dirName.c_str()); 14 | if (ftyp == INVALID_FILE_ATTRIBUTES) 15 | return false; // something is wrong with your path! 16 | 17 | if (ftyp & FILE_ATTRIBUTE_DIRECTORY) 18 | return true; // this directory exists 19 | 20 | return false; // this directory doesn't exists 21 | } 22 | 23 | void CUtils::StoreLogin(string username, string password, string hwid, string file) 24 | { 25 | ofstream output(file.c_str()); 26 | output.close(); 27 | 28 | // storing username and password within appdata for possible authentication checks withing the cheat, i will maybe go more indepth with this. 29 | configmanager->PushValue("logindata", "username", username, file.c_str()); 30 | configmanager->PushValue("logindata", "password", password, file.c_str()); 31 | configmanager->PushValue("logindata", "hwid", hwid, file.c_str()); 32 | } 33 | 34 | DWORD CUtils::GetHWID() // using the system volume informations as hwid for testing purposes 35 | { 36 | DWORD VolumeSerialNumber; 37 | 38 | BOOL GetVolumeInformationFlag = GetVolumeInformationA( 39 | "c:\\", 40 | 0, 41 | 0, 42 | &VolumeSerialNumber, 43 | 0, 44 | 0, 45 | 0, 46 | 0 47 | ); 48 | 49 | if (GetVolumeInformationFlag) 50 | return VolumeSerialNumber; 51 | 52 | return 0; 53 | } 54 | 55 | CUtils* utils; -------------------------------------------------------------------------------- /utils/utils.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "../configmanager/configmanager.hpp" 7 | 8 | using namespace std; 9 | 10 | class CUtils 11 | { 12 | public: 13 | string GetAppData(); 14 | bool dirExists(const string& dirName); 15 | void StoreLogin(string username, string password, string hwid, string file); 16 | DWORD GetHWID(); 17 | }; 18 | 19 | extern CUtils* utils; -------------------------------------------------------------------------------- /webfiles/hwid.php: -------------------------------------------------------------------------------- 1 | query($sql); 13 | 14 | if ($result->num_rows > 0) { 15 | // Outputting the rows 16 | while($row = $result->fetch_assoc()) 17 | { 18 | function Redirect($url, $permanent = false) 19 | { 20 | if (headers_sent() === false) 21 | { 22 | header('Location: ' . $url, true, ($permanent === true) ? 301 : 302); 23 | } 24 | exit(); 25 | } 26 | 27 | if($token != $storedtoken){ 28 | return; 29 | } 30 | 31 | if (strlen($row['hwid']) > 1) 32 | { 33 | if ($hwid != $row['hwid']) 34 | { 35 | echo 'declined'; 36 | } 37 | else 38 | { 39 | echo 'accepted'; 40 | } 41 | } 42 | else 43 | { 44 | $sql = "UPDATE ". $tables ." SET hwid='$hwid' WHERE username='$user'"; 45 | if(mysqli_query($link, $sql)) 46 | { 47 | echo 'new'; 48 | } 49 | else 50 | { 51 | echo 'error'; 52 | } 53 | } 54 | } 55 | } 56 | ?> 57 | --------------------------------------------------------------------------------