Home | History | Annotate | Download | only in text
      1 /*
      2  * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef StringBuilder_h
     27 #define StringBuilder_h
     28 
     29 #include <wtf/Vector.h>
     30 #include <wtf/text/WTFString.h>
     31 
     32 namespace WTF {
     33 
     34 class StringBuilder {
     35 public:
     36     StringBuilder()
     37         : m_length(0)
     38     {
     39     }
     40 
     41     void append(const UChar*, unsigned);
     42     void append(const char*, unsigned);
     43 
     44     void append(const String& string)
     45     {
     46         // If we're appending to an empty string, and there is not buffer
     47         // (in case reserveCapacity has been called) then just retain the
     48         // string.
     49         if (!m_length && !m_buffer) {
     50             m_string = string;
     51             m_length = string.length();
     52             return;
     53         }
     54         append(string.characters(), string.length());
     55     }
     56 
     57     void append(const char* characters)
     58     {
     59         if (characters)
     60             append(characters, strlen(characters));
     61     }
     62 
     63     void append(UChar c)
     64     {
     65         if (m_buffer && m_length < m_buffer->length() && m_string.isNull())
     66             m_bufferCharacters[m_length++] = c;
     67         else
     68             append(&c, 1);
     69     }
     70 
     71     void append(char c)
     72     {
     73         if (m_buffer && m_length < m_buffer->length() && m_string.isNull())
     74             m_bufferCharacters[m_length++] = (unsigned char)c;
     75         else
     76             append(&c, 1);
     77     }
     78 
     79     String toString()
     80     {
     81         if (m_string.isNull()) {
     82             shrinkToFit();
     83             reifyString();
     84         }
     85         return m_string;
     86     }
     87 
     88     String toStringPreserveCapacity()
     89     {
     90         if (m_string.isNull())
     91             reifyString();
     92         return m_string;
     93     }
     94 
     95     unsigned length() const
     96     {
     97         return m_length;
     98     }
     99 
    100     bool isEmpty() const { return !length(); }
    101 
    102     void reserveCapacity(unsigned newCapacity);
    103 
    104     void resize(unsigned newSize);
    105 
    106     void shrinkToFit();
    107 
    108     UChar operator[](unsigned i) const
    109     {
    110         ASSERT(i < m_length);
    111         if (!m_string.isNull())
    112             return m_string[i];
    113         ASSERT(m_buffer);
    114         return m_buffer->characters()[i];
    115     }
    116 
    117     void clear()
    118     {
    119         m_length = 0;
    120         m_string = String();
    121         m_buffer = 0;
    122     }
    123 
    124 private:
    125     void allocateBuffer(const UChar* currentCharacters, unsigned requiredLength);
    126     UChar* appendUninitialized(unsigned length);
    127     void reifyString();
    128 
    129     unsigned m_length;
    130     String m_string;
    131     RefPtr<StringImpl> m_buffer;
    132     UChar* m_bufferCharacters;
    133 };
    134 
    135 } // namespace WTF
    136 
    137 using WTF::StringBuilder;
    138 
    139 #endif // StringBuilder_h
    140