15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Copyright 2010 the V8 project authors. All rights reserved.
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Redistribution and use in source and binary forms, with or without
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// modification, are permitted provided that the following conditions are
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// met:
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//     * Redistributions of source code must retain the above copyright
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       notice, this list of conditions and the following disclaimer.
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//     * Redistributions in binary form must reproduce the above
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       copyright notice, this list of conditions and the following
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       disclaimer in the documentation and/or other materials provided
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       with the distribution.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       contributors may be used to endorse or promote products derived
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       from this software without specific prior written permission.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef DOUBLE_CONVERSION_UTILS_H_
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define DOUBLE_CONVERSION_UTILS_H_
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/Assertions.h"
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <string.h>
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define UNIMPLEMENTED ASSERT_NOT_REACHED
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define UNREACHABLE ASSERT_NOT_REACHED
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Double operations detection based on target architecture.
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Linux uses a 80bit wide floating point stack on x86. This induces double
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// rounding, which in turn leads to wrong results.
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// An easy way to test if the floating-point operations are correct is to
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// the result is equal to 89255e-22.
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// The best way to test this, is to create a division-function and to compare
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// the output of the division with the expected result. (Inlining must be
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// disabled.)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// On Linux,x86 89255e-22 != Div_double(89255.0/1e22)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if defined(_M_X64) || defined(__x86_64__) || \
4807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochdefined(__ARMEL__) || defined(__aarch64__) || \
498abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)defined(__MIPSEL__)
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#elif defined(_M_IX86) || defined(__i386__)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if defined(_WIN32)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Windows uses a 64bit wide floating point stack.
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif  // _WIN32
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#error Target architecture was not detected as supported by Double-Conversion.
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if defined(_WIN32) && !defined(__MINGW32__)
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef signed char int8_t;
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef unsigned char uint8_t;
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef short int16_t;  // NOLINT
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef unsigned short uint16_t;  // NOLINT
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef int int32_t;
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef unsigned int uint32_t;
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef __int64 int64_t;
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef unsigned __int64 uint64_t;
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// intptr_t and friends are defined in crtdefs.h through stdio.h.
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <stdint.h>
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// The following macro works on both 32 and 64-bit platforms.
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Usage: instead of writing 0x1234567890123456
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//      write UINT64_2PART_C(0x12345678,90123456);
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// The expression ARRAY_SIZE(a) is a compile-time constant of type
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// size_t which represents the number of elements of the given
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// array. You should only use ARRAY_SIZE on statically allocated
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// arrays.
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define ARRAY_SIZE(a)                                   \
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)((sizeof(a) / sizeof(*(a))) /                         \
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// A macro to disallow the evil copy constructor and operator= functions
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This should be used in the private: declarations for a class
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define DISALLOW_COPY_AND_ASSIGN(TypeName)      \
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TypeName(const TypeName&);                    \
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void operator=(const TypeName&)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// A macro to disallow all the implicit constructors, namely the
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// default constructor, copy constructor and operator= functions.
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This should be used in the private: declarations for a class
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// that wants to prevent anyone from instantiating it. This is
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// especially useful for classes containing only static methods.
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TypeName();                                    \
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DISALLOW_COPY_AND_ASSIGN(TypeName)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WTF {
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace double_conversion {
11402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static const int kCharSize = sizeof(char);
11602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Returns the maximum of the two parameters.
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template <typename T>
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static T Max(T a, T b) {
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return a < b ? b : a;
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
12302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Returns the minimum of the two parameters.
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template <typename T>
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static T Min(T a, T b) {
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return a < b ? a : b;
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
13002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    inline int StrLength(const char* string) {
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        size_t length = strlen(string);
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return static_cast<int>(length);
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This is a simplified version of V8's Vector class.
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template <typename T>
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    class Vector {
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    public:
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Vector() : start_(NULL), length_(0) {}
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Vector(T* data, int length) : start_(data), length_(length) {
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(length == 0 || (length > 0 && data != NULL));
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
14502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Returns a vector using the same backing storage as this one,
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // spanning from and including 'from', to but not including 'to'.
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Vector<T> SubVector(int from, int to) {
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(to <= length_);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(from < to);
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(0 <= from);
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return Vector<T>(start() + from, to - from);
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
15402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Returns the length of the vector.
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int length() const { return length_; }
15702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Returns whether or not the vector is empty.
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool is_empty() const { return length_ == 0; }
16002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Returns the pointer to the start of the data in the vector.
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        T* start() const { return start_; }
16302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Access individual vector elements - checks bounds in debug mode.
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        T& operator[](int index) const {
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(0 <= index && index < length_);
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return start_[index];
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
16902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        T& first() { return start_[0]; }
17102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        T& last() { return start_[length_ - 1]; }
17302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    private:
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        T* start_;
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int length_;
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
17802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
17902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Helper class for building result strings in a character buffer. The
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // purpose of the class is to use safe operations that checks the
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // buffer bounds on all operations in debug mode.
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    class StringBuilder {
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    public:
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        StringBuilder(char* buffer, int size)
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : buffer_(buffer, size), position_(0) { }
18702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ~StringBuilder() { if (!is_finalized()) Finalize(); }
18902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int size() const { return buffer_.length(); }
19102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Get the current position in the builder.
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int position() const {
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(!is_finalized());
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return position_;
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
19702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Set the current position in the builder.
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void SetPosition(int position)
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(!is_finalized());
202926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            ASSERT_WITH_SECURITY_IMPLICATION(position < size());
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            position_ = position;
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
20502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Reset the position.
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void Reset() { position_ = 0; }
20802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Add a single character to the builder. It is not allowed to add
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // 0-characters; use the Finalize() method to terminate the string
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // instead.
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void AddCharacter(char c) {
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(c != '\0');
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(!is_finalized() && position_ < buffer_.length());
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            buffer_[position_++] = c;
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
21702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Add an entire string to the builder. Uses strlen() internally to
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // compute the length of the input string.
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void AddString(const char* s) {
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            AddSubstring(s, StrLength(s));
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
22302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Add the first 'n' characters of the given string 's' to the
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // builder. The input string must have enough characters.
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void AddSubstring(const char* s, int n) {
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(!is_finalized() && position_ + n < buffer_.length());
228926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            ASSERT_WITH_SECURITY_IMPLICATION(static_cast<size_t>(n) <= strlen(s));
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            memcpy(&buffer_[position_], s, n * kCharSize);
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            position_ += n;
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
23202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
23302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Add character padding to the builder. If count is non-positive,
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // nothing is added to the builder.
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void AddPadding(char c, int count) {
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (int i = 0; i < count; i++) {
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                AddCharacter(c);
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
24102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Finalize the string by 0-terminating it and returning the buffer.
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        char* Finalize() {
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(!is_finalized() && position_ < buffer_.length());
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            buffer_[position_] = '\0';
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Make sure nobody managed to add a 0-character to the
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // buffer while building the string.
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            position_ = -1;
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(is_finalized());
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return buffer_.start();
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
25302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    private:
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Vector<char> buffer_;
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int position_;
25702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool is_finalized() const { return position_ < 0; }
25902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
26202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The type-based aliasing rule allows the compiler to assume that pointers of
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // different types (for some definition of different) never alias each other.
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Thus the following code does not work:
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // float f = foo();
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // int fbits = *(int*)(&f);
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The compiler 'knows' that the int pointer can't refer to f since the types
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // don't match, so the compiler may cache f in a register, leaving random data
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // in fbits.  Using C++ style casts makes no difference, however a pointer to
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // char data is assumed to alias any other pointer.  This is the 'memcpy
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // exception'.
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Bit_cast uses the memcpy exception to move the bits from a variable of one
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // type of a variable of another type.  Of course the end result is likely to
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // be implementation dependent.  Most compilers (gcc-4.2 and MSVC 2005)
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // will completely optimize BitCast away.
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // There is an additional use for BitCast.
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Recent gccs will warn when they see casts that may result in breakage due to
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the type-based aliasing rule.  If you have checked that there is no breakage
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // you can use BitCast to cast one pointer type to another.  This confuses gcc
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // enough that it can no longer see that you have cast one pointer type to
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // another thus avoiding the warning.
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template <class Dest, class Source>
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    inline Dest BitCast(const Source& source) {
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Compile time assertion: sizeof(Dest) == sizeof(Source)
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // A compile error here means your Dest and Source have different sizes.
291a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), VerifySizesAreEqual);
29202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Dest dest;
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        memcpy(&dest, &source, sizeof(dest));
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return dest;
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
29702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template <class Dest, class Source>
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    inline Dest BitCast(Source* source) {
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
30202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}  // namespace double_conversion
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WTF
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif  // DOUBLE_CONVERSION_UTILS_H_
308