itoa.h

Engine/source/persistence/rapidjson/internal/itoa.h

More...

Namespaces:

namespace

Detailed Description

  1
  2// Tencent is pleased to support the open source community by making RapidJSON available.
  3//
  4// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
  5//
  6// Licensed under the MIT License (the "License"); you may not use this file except
  7// in compliance with the License. You may obtain a copy of the License at
  8//
  9// http://opensource.org/licenses/MIT
 10//
 11// Unless required by applicable law or agreed to in writing, software distributed
 12// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 13// CONDITIONS OF ANY KIND, either express or implied. See the License for the
 14// specific language governing permissions and limitations under the License.
 15
 16#ifndef RAPIDJSON_ITOA_
 17#define RAPIDJSON_ITOA_
 18
 19#include "../rapidjson.h"
 20
 21RAPIDJSON_NAMESPACE_BEGIN
 22namespace internal {
 23
 24inline const char* GetDigitsLut() {
 25    static const char cDigitsLut[200] = {
 26        '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',
 27        '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',
 28        '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',
 29        '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9',
 30        '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9',
 31        '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9',
 32        '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9',
 33        '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9',
 34        '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9',
 35        '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9'
 36    };
 37    return cDigitsLut;
 38}
 39
 40inline char* u32toa(uint32_t value, char* buffer) {
 41    RAPIDJSON_ASSERT(buffer != 0);
 42
 43    const char* cDigitsLut = GetDigitsLut();
 44
 45    if (value < 10000) {
 46        const uint32_t d1 = (value / 100) << 1;
 47        const uint32_t d2 = (value % 100) << 1;
 48
 49        if (value >= 1000)
 50            *buffer++ = cDigitsLut[d1];
 51        if (value >= 100)
 52            *buffer++ = cDigitsLut[d1 + 1];
 53        if (value >= 10)
 54            *buffer++ = cDigitsLut[d2];
 55        *buffer++ = cDigitsLut[d2 + 1];
 56    }
 57    else if (value < 100000000) {
 58        // value = bbbbcccc
 59        const uint32_t b = value / 10000;
 60        const uint32_t c = value % 10000;
 61
 62        const uint32_t d1 = (b / 100) << 1;
 63        const uint32_t d2 = (b % 100) << 1;
 64
 65        const uint32_t d3 = (c / 100) << 1;
 66        const uint32_t d4 = (c % 100) << 1;
 67
 68        if (value >= 10000000)
 69            *buffer++ = cDigitsLut[d1];
 70        if (value >= 1000000)
 71            *buffer++ = cDigitsLut[d1 + 1];
 72        if (value >= 100000)
 73            *buffer++ = cDigitsLut[d2];
 74        *buffer++ = cDigitsLut[d2 + 1];
 75
 76        *buffer++ = cDigitsLut[d3];
 77        *buffer++ = cDigitsLut[d3 + 1];
 78        *buffer++ = cDigitsLut[d4];
 79        *buffer++ = cDigitsLut[d4 + 1];
 80    }
 81    else {
 82        // value = aabbbbcccc in decimal
 83
 84        const uint32_t a = value / 100000000; // 1 to 42
 85        value %= 100000000;
 86
 87        if (a >= 10) {
 88            const unsigned i = a << 1;
 89            *buffer++ = cDigitsLut[i];
 90            *buffer++ = cDigitsLut[i + 1];
 91        }
 92        else
 93            *buffer++ = static_cast<char>('0' + static_cast<char>(a));
 94
 95        const uint32_t b = value / 10000; // 0 to 9999
 96        const uint32_t c = value % 10000; // 0 to 9999
 97
 98        const uint32_t d1 = (b / 100) << 1;
 99        const uint32_t d2 = (b % 100) << 1;
100
101        const uint32_t d3 = (c / 100) << 1;
102        const uint32_t d4 = (c % 100) << 1;
103
104        *buffer++ = cDigitsLut[d1];
105        *buffer++ = cDigitsLut[d1 + 1];
106        *buffer++ = cDigitsLut[d2];
107        *buffer++ = cDigitsLut[d2 + 1];
108        *buffer++ = cDigitsLut[d3];
109        *buffer++ = cDigitsLut[d3 + 1];
110        *buffer++ = cDigitsLut[d4];
111        *buffer++ = cDigitsLut[d4 + 1];
112    }
113    return buffer;
114}
115
116inline char* i32toa(int32_t value, char* buffer) {
117    RAPIDJSON_ASSERT(buffer != 0);
118    uint32_t u = static_cast<uint32_t>(value);
119    if (value < 0) {
120        *buffer++ = '-';
121        u = ~u + 1;
122    }
123
124    return u32toa(u, buffer);
125}
126
127inline char* u64toa(uint64_t value, char* buffer) {
128    RAPIDJSON_ASSERT(buffer != 0);
129    const char* cDigitsLut = GetDigitsLut();
130    const uint64_t  kTen8 = 100000000;
131    const uint64_t  kTen9 = kTen8 * 10;
132    const uint64_t kTen10 = kTen8 * 100;
133    const uint64_t kTen11 = kTen8 * 1000;
134    const uint64_t kTen12 = kTen8 * 10000;
135    const uint64_t kTen13 = kTen8 * 100000;
136    const uint64_t kTen14 = kTen8 * 1000000;
137    const uint64_t kTen15 = kTen8 * 10000000;
138    const uint64_t kTen16 = kTen8 * kTen8;
139
140    if (value < kTen8) {
141        uint32_t v = static_cast<uint32_t>(value);
142        if (v < 10000) {
143            const uint32_t d1 = (v / 100) << 1;
144            const uint32_t d2 = (v % 100) << 1;
145
146            if (v >= 1000)
147                *buffer++ = cDigitsLut[d1];
148            if (v >= 100)
149                *buffer++ = cDigitsLut[d1 + 1];
150            if (v >= 10)
151                *buffer++ = cDigitsLut[d2];
152            *buffer++ = cDigitsLut[d2 + 1];
153        }
154        else {
155            // value = bbbbcccc
156            const uint32_t b = v / 10000;
157            const uint32_t c = v % 10000;
158
159            const uint32_t d1 = (b / 100) << 1;
160            const uint32_t d2 = (b % 100) << 1;
161
162            const uint32_t d3 = (c / 100) << 1;
163            const uint32_t d4 = (c % 100) << 1;
164
165            if (value >= 10000000)
166                *buffer++ = cDigitsLut[d1];
167            if (value >= 1000000)
168                *buffer++ = cDigitsLut[d1 + 1];
169            if (value >= 100000)
170                *buffer++ = cDigitsLut[d2];
171            *buffer++ = cDigitsLut[d2 + 1];
172
173            *buffer++ = cDigitsLut[d3];
174            *buffer++ = cDigitsLut[d3 + 1];
175            *buffer++ = cDigitsLut[d4];
176            *buffer++ = cDigitsLut[d4 + 1];
177        }
178    }
179    else if (value < kTen16) {
180        const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
181        const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
182
183        const uint32_t b0 = v0 / 10000;
184        const uint32_t c0 = v0 % 10000;
185
186        const uint32_t d1 = (b0 / 100) << 1;
187        const uint32_t d2 = (b0 % 100) << 1;
188
189        const uint32_t d3 = (c0 / 100) << 1;
190        const uint32_t d4 = (c0 % 100) << 1;
191
192        const uint32_t b1 = v1 / 10000;
193        const uint32_t c1 = v1 % 10000;
194
195        const uint32_t d5 = (b1 / 100) << 1;
196        const uint32_t d6 = (b1 % 100) << 1;
197
198        const uint32_t d7 = (c1 / 100) << 1;
199        const uint32_t d8 = (c1 % 100) << 1;
200
201        if (value >= kTen15)
202            *buffer++ = cDigitsLut[d1];
203        if (value >= kTen14)
204            *buffer++ = cDigitsLut[d1 + 1];
205        if (value >= kTen13)
206            *buffer++ = cDigitsLut[d2];
207        if (value >= kTen12)
208            *buffer++ = cDigitsLut[d2 + 1];
209        if (value >= kTen11)
210            *buffer++ = cDigitsLut[d3];
211        if (value >= kTen10)
212            *buffer++ = cDigitsLut[d3 + 1];
213        if (value >= kTen9)
214            *buffer++ = cDigitsLut[d4];
215
216        *buffer++ = cDigitsLut[d4 + 1];
217        *buffer++ = cDigitsLut[d5];
218        *buffer++ = cDigitsLut[d5 + 1];
219        *buffer++ = cDigitsLut[d6];
220        *buffer++ = cDigitsLut[d6 + 1];
221        *buffer++ = cDigitsLut[d7];
222        *buffer++ = cDigitsLut[d7 + 1];
223        *buffer++ = cDigitsLut[d8];
224        *buffer++ = cDigitsLut[d8 + 1];
225    }
226    else {
227        const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844
228        value %= kTen16;
229
230        if (a < 10)
231            *buffer++ = static_cast<char>('0' + static_cast<char>(a));
232        else if (a < 100) {
233            const uint32_t i = a << 1;
234            *buffer++ = cDigitsLut[i];
235            *buffer++ = cDigitsLut[i + 1];
236        }
237        else if (a < 1000) {
238            *buffer++ = static_cast<char>('0' + static_cast<char>(a / 100));
239
240            const uint32_t i = (a % 100) << 1;
241            *buffer++ = cDigitsLut[i];
242            *buffer++ = cDigitsLut[i + 1];
243        }
244        else {
245            const uint32_t i = (a / 100) << 1;
246            const uint32_t j = (a % 100) << 1;
247            *buffer++ = cDigitsLut[i];
248            *buffer++ = cDigitsLut[i + 1];
249            *buffer++ = cDigitsLut[j];
250            *buffer++ = cDigitsLut[j + 1];
251        }
252
253        const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
254        const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
255
256        const uint32_t b0 = v0 / 10000;
257        const uint32_t c0 = v0 % 10000;
258
259        const uint32_t d1 = (b0 / 100) << 1;
260        const uint32_t d2 = (b0 % 100) << 1;
261
262        const uint32_t d3 = (c0 / 100) << 1;
263        const uint32_t d4 = (c0 % 100) << 1;
264
265        const uint32_t b1 = v1 / 10000;
266        const uint32_t c1 = v1 % 10000;
267
268        const uint32_t d5 = (b1 / 100) << 1;
269        const uint32_t d6 = (b1 % 100) << 1;
270
271        const uint32_t d7 = (c1 / 100) << 1;
272        const uint32_t d8 = (c1 % 100) << 1;
273
274        *buffer++ = cDigitsLut[d1];
275        *buffer++ = cDigitsLut[d1 + 1];
276        *buffer++ = cDigitsLut[d2];
277        *buffer++ = cDigitsLut[d2 + 1];
278        *buffer++ = cDigitsLut[d3];
279        *buffer++ = cDigitsLut[d3 + 1];
280        *buffer++ = cDigitsLut[d4];
281        *buffer++ = cDigitsLut[d4 + 1];
282        *buffer++ = cDigitsLut[d5];
283        *buffer++ = cDigitsLut[d5 + 1];
284        *buffer++ = cDigitsLut[d6];
285        *buffer++ = cDigitsLut[d6 + 1];
286        *buffer++ = cDigitsLut[d7];
287        *buffer++ = cDigitsLut[d7 + 1];
288        *buffer++ = cDigitsLut[d8];
289        *buffer++ = cDigitsLut[d8 + 1];
290    }
291
292    return buffer;
293}
294
295inline char* i64toa(int64_t value, char* buffer) {
296    RAPIDJSON_ASSERT(buffer != 0);
297    uint64_t u = static_cast<uint64_t>(value);
298    if (value < 0) {
299        *buffer++ = '-';
300        u = ~u + 1;
301    }
302
303    return u64toa(u, buffer);
304}
305
306} // namespace internal
307RAPIDJSON_NAMESPACE_END
308
309#endif // RAPIDJSON_ITOA_
310