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