1e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Tencent is pleased to support the open source community by making RapidJSON available. 2e462795ff5d4c7359f9e8637c10544bb2de70107tturney// 3e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4e462795ff5d4c7359f9e8637c10544bb2de70107tturney// 5e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Licensed under the MIT License (the "License"); you may not use this file except 6e462795ff5d4c7359f9e8637c10544bb2de70107tturney// in compliance with the License. You may obtain a copy of the License at 7e462795ff5d4c7359f9e8637c10544bb2de70107tturney// 8e462795ff5d4c7359f9e8637c10544bb2de70107tturney// http://opensource.org/licenses/MIT 9e462795ff5d4c7359f9e8637c10544bb2de70107tturney// 10e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Unless required by applicable law or agreed to in writing, software distributed 11e462795ff5d4c7359f9e8637c10544bb2de70107tturney// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12e462795ff5d4c7359f9e8637c10544bb2de70107tturney// CONDITIONS OF ANY KIND, either express or implied. See the License for the 13e462795ff5d4c7359f9e8637c10544bb2de70107tturney// specific language governing permissions and limitations under the License. 14e462795ff5d4c7359f9e8637c10544bb2de70107tturney 15e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include "unittest.h" 16e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include "rapidjson/internal/itoa.h" 17e462795ff5d4c7359f9e8637c10544bb2de70107tturney 18e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifdef __GNUC__ 19e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_DIAG_PUSH 20e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_DIAG_OFF(type-limits) 21e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif 22e462795ff5d4c7359f9e8637c10544bb2de70107tturney 23e462795ff5d4c7359f9e8637c10544bb2de70107tturneyusing namespace rapidjson::internal; 24e462795ff5d4c7359f9e8637c10544bb2de70107tturney 25e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate <typename T> 26e462795ff5d4c7359f9e8637c10544bb2de70107tturneystruct Traits { 27e462795ff5d4c7359f9e8637c10544bb2de70107tturney}; 28e462795ff5d4c7359f9e8637c10544bb2de70107tturney 29e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate <> 30e462795ff5d4c7359f9e8637c10544bb2de70107tturneystruct Traits<uint32_t> { 31e462795ff5d4c7359f9e8637c10544bb2de70107tturney enum { kBufferSize = 11 }; 32e462795ff5d4c7359f9e8637c10544bb2de70107tturney enum { kMaxDigit = 10 }; 33e462795ff5d4c7359f9e8637c10544bb2de70107tturney static uint32_t Negate(uint32_t x) { return x; }; 34e462795ff5d4c7359f9e8637c10544bb2de70107tturney}; 35e462795ff5d4c7359f9e8637c10544bb2de70107tturney 36e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate <> 37e462795ff5d4c7359f9e8637c10544bb2de70107tturneystruct Traits<int32_t> { 38e462795ff5d4c7359f9e8637c10544bb2de70107tturney enum { kBufferSize = 12 }; 39e462795ff5d4c7359f9e8637c10544bb2de70107tturney enum { kMaxDigit = 10 }; 40e462795ff5d4c7359f9e8637c10544bb2de70107tturney static int32_t Negate(int32_t x) { return -x; }; 41e462795ff5d4c7359f9e8637c10544bb2de70107tturney}; 42e462795ff5d4c7359f9e8637c10544bb2de70107tturney 43e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate <> 44e462795ff5d4c7359f9e8637c10544bb2de70107tturneystruct Traits<uint64_t> { 45e462795ff5d4c7359f9e8637c10544bb2de70107tturney enum { kBufferSize = 21 }; 46e462795ff5d4c7359f9e8637c10544bb2de70107tturney enum { kMaxDigit = 20 }; 47e462795ff5d4c7359f9e8637c10544bb2de70107tturney static uint64_t Negate(uint64_t x) { return x; }; 48e462795ff5d4c7359f9e8637c10544bb2de70107tturney}; 49e462795ff5d4c7359f9e8637c10544bb2de70107tturney 50e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate <> 51e462795ff5d4c7359f9e8637c10544bb2de70107tturneystruct Traits<int64_t> { 52e462795ff5d4c7359f9e8637c10544bb2de70107tturney enum { kBufferSize = 22 }; 53e462795ff5d4c7359f9e8637c10544bb2de70107tturney enum { kMaxDigit = 20 }; 54e462795ff5d4c7359f9e8637c10544bb2de70107tturney static int64_t Negate(int64_t x) { return -x; }; 55e462795ff5d4c7359f9e8637c10544bb2de70107tturney}; 56e462795ff5d4c7359f9e8637c10544bb2de70107tturney 57e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate <typename T> 58e462795ff5d4c7359f9e8637c10544bb2de70107tturneystatic void VerifyValue(T value, void(*f)(T, char*), char* (*g)(T, char*)) { 59e462795ff5d4c7359f9e8637c10544bb2de70107tturney char buffer1[Traits<T>::kBufferSize]; 60e462795ff5d4c7359f9e8637c10544bb2de70107tturney char buffer2[Traits<T>::kBufferSize]; 61e462795ff5d4c7359f9e8637c10544bb2de70107tturney 62e462795ff5d4c7359f9e8637c10544bb2de70107tturney f(value, buffer1); 63e462795ff5d4c7359f9e8637c10544bb2de70107tturney *g(value, buffer2) = '\0'; 64e462795ff5d4c7359f9e8637c10544bb2de70107tturney 65e462795ff5d4c7359f9e8637c10544bb2de70107tturney 66e462795ff5d4c7359f9e8637c10544bb2de70107tturney EXPECT_STREQ(buffer1, buffer2); 67e462795ff5d4c7359f9e8637c10544bb2de70107tturney} 68e462795ff5d4c7359f9e8637c10544bb2de70107tturney 69e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate <typename T> 70e462795ff5d4c7359f9e8637c10544bb2de70107tturneystatic void Verify(void(*f)(T, char*), char* (*g)(T, char*)) { 71e462795ff5d4c7359f9e8637c10544bb2de70107tturney // Boundary cases 72e462795ff5d4c7359f9e8637c10544bb2de70107tturney VerifyValue<T>(0, f, g); 73e462795ff5d4c7359f9e8637c10544bb2de70107tturney VerifyValue<T>(std::numeric_limits<T>::min(), f, g); 74e462795ff5d4c7359f9e8637c10544bb2de70107tturney VerifyValue<T>(std::numeric_limits<T>::max(), f, g); 75e462795ff5d4c7359f9e8637c10544bb2de70107tturney 76e462795ff5d4c7359f9e8637c10544bb2de70107tturney // 2^n - 1, 2^n, 10^n - 1, 10^n until overflow 77e462795ff5d4c7359f9e8637c10544bb2de70107tturney for (uint32_t power = 2; power <= 10; power += 8) { 78e462795ff5d4c7359f9e8637c10544bb2de70107tturney T i = 1, last; 79e462795ff5d4c7359f9e8637c10544bb2de70107tturney do { 80e462795ff5d4c7359f9e8637c10544bb2de70107tturney VerifyValue<T>(i - 1, f, g); 81e462795ff5d4c7359f9e8637c10544bb2de70107tturney VerifyValue<T>(i, f, g); 82e462795ff5d4c7359f9e8637c10544bb2de70107tturney if (std::numeric_limits<T>::min() < 0) { 83e462795ff5d4c7359f9e8637c10544bb2de70107tturney VerifyValue<T>(Traits<T>::Negate(i), f, g); 84e462795ff5d4c7359f9e8637c10544bb2de70107tturney VerifyValue<T>(Traits<T>::Negate(i + 1), f, g); 85e462795ff5d4c7359f9e8637c10544bb2de70107tturney } 86e462795ff5d4c7359f9e8637c10544bb2de70107tturney last = i; 87e462795ff5d4c7359f9e8637c10544bb2de70107tturney i *= power; 88e462795ff5d4c7359f9e8637c10544bb2de70107tturney } while (last < i); 89e462795ff5d4c7359f9e8637c10544bb2de70107tturney } 90e462795ff5d4c7359f9e8637c10544bb2de70107tturney} 91e462795ff5d4c7359f9e8637c10544bb2de70107tturney 92e462795ff5d4c7359f9e8637c10544bb2de70107tturneystatic void u32toa_naive(uint32_t value, char* buffer) { 93e462795ff5d4c7359f9e8637c10544bb2de70107tturney char temp[10]; 94e462795ff5d4c7359f9e8637c10544bb2de70107tturney char *p = temp; 95e462795ff5d4c7359f9e8637c10544bb2de70107tturney do { 96e462795ff5d4c7359f9e8637c10544bb2de70107tturney *p++ = char(value % 10) + '0'; 97e462795ff5d4c7359f9e8637c10544bb2de70107tturney value /= 10; 98e462795ff5d4c7359f9e8637c10544bb2de70107tturney } while (value > 0); 99e462795ff5d4c7359f9e8637c10544bb2de70107tturney 100e462795ff5d4c7359f9e8637c10544bb2de70107tturney do { 101e462795ff5d4c7359f9e8637c10544bb2de70107tturney *buffer++ = *--p; 102e462795ff5d4c7359f9e8637c10544bb2de70107tturney } while (p != temp); 103e462795ff5d4c7359f9e8637c10544bb2de70107tturney 104e462795ff5d4c7359f9e8637c10544bb2de70107tturney *buffer = '\0'; 105e462795ff5d4c7359f9e8637c10544bb2de70107tturney} 106e462795ff5d4c7359f9e8637c10544bb2de70107tturney 107e462795ff5d4c7359f9e8637c10544bb2de70107tturneystatic void i32toa_naive(int32_t value, char* buffer) { 108e462795ff5d4c7359f9e8637c10544bb2de70107tturney uint32_t u = static_cast<uint32_t>(value); 109e462795ff5d4c7359f9e8637c10544bb2de70107tturney if (value < 0) { 110e462795ff5d4c7359f9e8637c10544bb2de70107tturney *buffer++ = '-'; 111e462795ff5d4c7359f9e8637c10544bb2de70107tturney u = ~u + 1; 112e462795ff5d4c7359f9e8637c10544bb2de70107tturney } 113e462795ff5d4c7359f9e8637c10544bb2de70107tturney u32toa_naive(u, buffer); 114e462795ff5d4c7359f9e8637c10544bb2de70107tturney} 115e462795ff5d4c7359f9e8637c10544bb2de70107tturney 116e462795ff5d4c7359f9e8637c10544bb2de70107tturneystatic void u64toa_naive(uint64_t value, char* buffer) { 117e462795ff5d4c7359f9e8637c10544bb2de70107tturney char temp[20]; 118e462795ff5d4c7359f9e8637c10544bb2de70107tturney char *p = temp; 119e462795ff5d4c7359f9e8637c10544bb2de70107tturney do { 120e462795ff5d4c7359f9e8637c10544bb2de70107tturney *p++ = char(value % 10) + '0'; 121e462795ff5d4c7359f9e8637c10544bb2de70107tturney value /= 10; 122e462795ff5d4c7359f9e8637c10544bb2de70107tturney } while (value > 0); 123e462795ff5d4c7359f9e8637c10544bb2de70107tturney 124e462795ff5d4c7359f9e8637c10544bb2de70107tturney do { 125e462795ff5d4c7359f9e8637c10544bb2de70107tturney *buffer++ = *--p; 126e462795ff5d4c7359f9e8637c10544bb2de70107tturney } while (p != temp); 127e462795ff5d4c7359f9e8637c10544bb2de70107tturney 128e462795ff5d4c7359f9e8637c10544bb2de70107tturney *buffer = '\0'; 129e462795ff5d4c7359f9e8637c10544bb2de70107tturney} 130e462795ff5d4c7359f9e8637c10544bb2de70107tturney 131e462795ff5d4c7359f9e8637c10544bb2de70107tturneystatic void i64toa_naive(int64_t value, char* buffer) { 132e462795ff5d4c7359f9e8637c10544bb2de70107tturney uint64_t u = static_cast<uint64_t>(value); 133e462795ff5d4c7359f9e8637c10544bb2de70107tturney if (value < 0) { 134e462795ff5d4c7359f9e8637c10544bb2de70107tturney *buffer++ = '-'; 135e462795ff5d4c7359f9e8637c10544bb2de70107tturney u = ~u + 1; 136e462795ff5d4c7359f9e8637c10544bb2de70107tturney } 137e462795ff5d4c7359f9e8637c10544bb2de70107tturney u64toa_naive(u, buffer); 138e462795ff5d4c7359f9e8637c10544bb2de70107tturney} 139e462795ff5d4c7359f9e8637c10544bb2de70107tturney 140e462795ff5d4c7359f9e8637c10544bb2de70107tturneyTEST(itoa, u32toa) { 141e462795ff5d4c7359f9e8637c10544bb2de70107tturney Verify(u32toa_naive, u32toa); 142e462795ff5d4c7359f9e8637c10544bb2de70107tturney} 143e462795ff5d4c7359f9e8637c10544bb2de70107tturney 144e462795ff5d4c7359f9e8637c10544bb2de70107tturneyTEST(itoa, i32toa) { 145e462795ff5d4c7359f9e8637c10544bb2de70107tturney Verify(i32toa_naive, i32toa); 146e462795ff5d4c7359f9e8637c10544bb2de70107tturney} 147e462795ff5d4c7359f9e8637c10544bb2de70107tturney 148e462795ff5d4c7359f9e8637c10544bb2de70107tturneyTEST(itoa, u64toa) { 149e462795ff5d4c7359f9e8637c10544bb2de70107tturney Verify(u64toa_naive, u64toa); 150e462795ff5d4c7359f9e8637c10544bb2de70107tturney} 151e462795ff5d4c7359f9e8637c10544bb2de70107tturney 152e462795ff5d4c7359f9e8637c10544bb2de70107tturneyTEST(itoa, i64toa) { 153e462795ff5d4c7359f9e8637c10544bb2de70107tturney Verify(i64toa_naive, i64toa); 154e462795ff5d4c7359f9e8637c10544bb2de70107tturney} 155e462795ff5d4c7359f9e8637c10544bb2de70107tturney 156e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifdef __GNUC__ 157e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_DIAG_POP 158e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif 159