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 20RAPIDJSON_NAMESPACE_BEGIN 21namespace internal { 22 23inline 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 39inline 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<char>('0' + static_cast<char>(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 113inline char* i32toa(int32_t value, char* buffer) { 114 uint32_t u = static_cast<uint32_t>(value); 115 if (value < 0) { 116 *buffer++ = '-'; 117 u = ~u + 1; 118 } 119 120 return u32toa(u, buffer); 121} 122 123inline 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<uint32_t>(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<uint32_t>(value / kTen8); 176 const uint32_t v1 = static_cast<uint32_t>(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<uint32_t>(value / kTen16); // 1 to 1844 224 value %= kTen16; 225 226 if (a < 10) 227 *buffer++ = static_cast<char>('0' + static_cast<char>(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<char>('0' + static_cast<char>(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<uint32_t>(value / kTen8); 250 const uint32_t v1 = static_cast<uint32_t>(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 291inline char* i64toa(int64_t value, char* buffer) { 292 uint64_t u = static_cast<uint64_t>(value); 293 if (value < 0) { 294 *buffer++ = '-'; 295 u = ~u + 1; 296 } 297 298 return u64toa(u, buffer); 299} 300 301} // namespace internal 302RAPIDJSON_NAMESPACE_END 303 304#endif // RAPIDJSON_ITOA_ 305