1/*
2 * Copyright (C) 2012 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2012 Patrick Gansterer <paroga@paroga.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB.  If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22#ifndef IntegerToStringConversion_h
23#define IntegerToStringConversion_h
24
25#include "wtf/text/StringBuilder.h"
26#include "wtf/text/StringImpl.h"
27
28namespace WTF {
29
30enum PositiveOrNegativeNumber {
31    PositiveNumber,
32    NegativeNumber
33};
34
35template<typename T> struct ConversionTrait;
36
37template<> struct ConversionTrait<String> {
38    typedef PassRefPtr<StringImpl> ReturnType;
39    typedef void AdditionalArgumentType;
40    static inline ReturnType flush(LChar* characters, unsigned length, void*) { return StringImpl::create(characters, length); }
41};
42template<> struct ConversionTrait<StringBuilder> {
43    typedef void ReturnType;
44    typedef StringBuilder AdditionalArgumentType;
45    static inline ReturnType flush(LChar* characters, unsigned length, StringBuilder* stringBuilder) { stringBuilder->append(characters, length); }
46};
47template<> struct ConversionTrait<AtomicString> {
48    typedef AtomicString ReturnType;
49    typedef void AdditionalArgumentType;
50    static inline ReturnType flush(LChar* characters, unsigned length, void*) { return AtomicString(characters, length); }
51};
52
53template<typename T> struct UnsignedIntegerTrait;
54
55template<> struct UnsignedIntegerTrait<int> {
56    typedef unsigned Type;
57};
58template<> struct UnsignedIntegerTrait<long> {
59    typedef unsigned long Type;
60};
61template<> struct UnsignedIntegerTrait<long long> {
62    typedef unsigned long long Type;
63};
64
65template<typename T, typename UnsignedIntegerType, PositiveOrNegativeNumber NumberType>
66static typename ConversionTrait<T>::ReturnType numberToStringImpl(UnsignedIntegerType number, typename ConversionTrait<T>::AdditionalArgumentType* additionalArgument)
67{
68    LChar buf[sizeof(UnsignedIntegerType) * 3 + 1];
69    LChar* end = buf + WTF_ARRAY_LENGTH(buf);
70    LChar* p = end;
71
72    do {
73        *--p = static_cast<LChar>((number % 10) + '0');
74        number /= 10;
75    } while (number);
76
77    if (NumberType == NegativeNumber)
78        *--p = '-';
79
80    return ConversionTrait<T>::flush(p, static_cast<unsigned>(end - p), additionalArgument);
81}
82
83template<typename T, typename SignedIntegerType>
84inline typename ConversionTrait<T>::ReturnType numberToStringSigned(SignedIntegerType number, typename ConversionTrait<T>::AdditionalArgumentType* additionalArgument = 0)
85{
86    if (number < 0)
87        return numberToStringImpl<T, typename UnsignedIntegerTrait<SignedIntegerType>::Type, NegativeNumber>(-number, additionalArgument);
88    return numberToStringImpl<T, typename UnsignedIntegerTrait<SignedIntegerType>::Type, PositiveNumber>(number, additionalArgument);
89}
90
91template<typename T, typename UnsignedIntegerType>
92inline typename ConversionTrait<T>::ReturnType numberToStringUnsigned(UnsignedIntegerType number, typename ConversionTrait<T>::AdditionalArgumentType* additionalArgument = 0)
93{
94    return numberToStringImpl<T, UnsignedIntegerType, PositiveNumber>(number, additionalArgument);
95}
96
97} // namespace WTF
98
99#endif // IntegerToStringConversion_h
100