Home | History | Annotate | Download | only in src
      1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_STRING_STREAM_H_
     29 #define V8_STRING_STREAM_H_
     30 
     31 namespace v8 {
     32 namespace internal {
     33 
     34 
     35 class StringAllocator {
     36  public:
     37   virtual ~StringAllocator() {}
     38   // Allocate a number of bytes.
     39   virtual char* allocate(unsigned bytes) = 0;
     40   // Allocate a larger number of bytes and copy the old buffer to the new one.
     41   // bytes is an input and output parameter passing the old size of the buffer
     42   // and returning the new size.  If allocation fails then we return the old
     43   // buffer and do not increase the size.
     44   virtual char* grow(unsigned* bytes) = 0;
     45 };
     46 
     47 
     48 // Normal allocator uses new[] and delete[].
     49 class HeapStringAllocator: public StringAllocator {
     50  public:
     51   ~HeapStringAllocator() { DeleteArray(space_); }
     52   char* allocate(unsigned bytes);
     53   char* grow(unsigned* bytes);
     54  private:
     55   char* space_;
     56 };
     57 
     58 
     59 // Allocator for use when no new c++ heap allocation is allowed.
     60 // Given a preallocated buffer up front and does no allocation while
     61 // building message.
     62 class NoAllocationStringAllocator: public StringAllocator {
     63  public:
     64   NoAllocationStringAllocator(char* memory, unsigned size);
     65   char* allocate(unsigned bytes) { return space_; }
     66   char* grow(unsigned* bytes);
     67  private:
     68   unsigned size_;
     69   char* space_;
     70 };
     71 
     72 
     73 class FmtElm {
     74  public:
     75   FmtElm(int value) : type_(INT) {  // NOLINT
     76     data_.u_int_ = value;
     77   }
     78   explicit FmtElm(double value) : type_(DOUBLE) {
     79     data_.u_double_ = value;
     80   }
     81   FmtElm(const char* value) : type_(C_STR) {  // NOLINT
     82     data_.u_c_str_ = value;
     83   }
     84   FmtElm(const Vector<const uc16>& value) : type_(LC_STR) {  // NOLINT
     85     data_.u_lc_str_ = &value;
     86   }
     87   FmtElm(Object* value) : type_(OBJ) {  // NOLINT
     88     data_.u_obj_ = value;
     89   }
     90   FmtElm(Handle<Object> value) : type_(HANDLE) {  // NOLINT
     91     data_.u_handle_ = value.location();
     92   }
     93   FmtElm(void* value) : type_(POINTER) {  // NOLINT
     94     data_.u_pointer_ = value;
     95   }
     96 
     97  private:
     98   friend class StringStream;
     99   enum Type { INT, DOUBLE, C_STR, LC_STR, OBJ, HANDLE, POINTER };
    100   Type type_;
    101   union {
    102     int u_int_;
    103     double u_double_;
    104     const char* u_c_str_;
    105     const Vector<const uc16>* u_lc_str_;
    106     Object* u_obj_;
    107     Object** u_handle_;
    108     void* u_pointer_;
    109   } data_;
    110 };
    111 
    112 
    113 class StringStream {
    114  public:
    115   explicit StringStream(StringAllocator* allocator):
    116     allocator_(allocator),
    117     capacity_(kInitialCapacity),
    118     length_(0),
    119     buffer_(allocator_->allocate(kInitialCapacity)) {
    120     buffer_[0] = 0;
    121   }
    122 
    123   ~StringStream() {
    124   }
    125 
    126   bool Put(char c);
    127   bool Put(String* str);
    128   bool Put(String* str, int start, int end);
    129   void Add(Vector<const char> format, Vector<FmtElm> elms);
    130   void Add(const char* format);
    131   void Add(Vector<const char> format);
    132   void Add(const char* format, FmtElm arg0);
    133   void Add(const char* format, FmtElm arg0, FmtElm arg1);
    134   void Add(const char* format, FmtElm arg0, FmtElm arg1, FmtElm arg2);
    135   void Add(const char* format,
    136            FmtElm arg0,
    137            FmtElm arg1,
    138            FmtElm arg2,
    139            FmtElm arg3);
    140   void Add(const char* format,
    141            FmtElm arg0,
    142            FmtElm arg1,
    143            FmtElm arg2,
    144            FmtElm arg3,
    145            FmtElm arg4);
    146 
    147   // Getting the message out.
    148   void OutputToFile(FILE* out);
    149   void OutputToStdOut() { OutputToFile(stdout); }
    150   void Log();
    151   Handle<String> ToString();
    152   SmartArrayPointer<const char> ToCString() const;
    153   int length() const { return length_; }
    154 
    155   // Object printing support.
    156   void PrintName(Object* o);
    157   void PrintFixedArray(FixedArray* array, unsigned int limit);
    158   void PrintByteArray(ByteArray* ba);
    159   void PrintUsingMap(JSObject* js_object);
    160   void PrintPrototype(JSFunction* fun, Object* receiver);
    161   void PrintSecurityTokenIfChanged(Object* function);
    162   // NOTE: Returns the code in the output parameter.
    163   void PrintFunction(Object* function, Object* receiver, Code** code);
    164 
    165   // Reset the stream.
    166   void Reset() {
    167     length_ = 0;
    168     buffer_[0] = 0;
    169   }
    170 
    171   // Mentioned object cache support.
    172   void PrintMentionedObjectCache();
    173   static void ClearMentionedObjectCache();
    174 #ifdef DEBUG
    175   static bool IsMentionedObjectCacheClear();
    176 #endif
    177 
    178 
    179   static const int kInitialCapacity = 16;
    180 
    181  private:
    182   void PrintObject(Object* obj);
    183 
    184   StringAllocator* allocator_;
    185   unsigned capacity_;
    186   unsigned length_;  // does not include terminating 0-character
    187   char* buffer_;
    188 
    189   bool full() const { return (capacity_ - length_) == 1; }
    190   int space() const { return capacity_ - length_; }
    191 
    192   DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream);
    193 };
    194 
    195 
    196 // Utility class to print a list of items to a stream, divided by a separator.
    197 class SimpleListPrinter {
    198  public:
    199   explicit SimpleListPrinter(StringStream* stream, char separator = ',') {
    200     separator_ = separator;
    201     stream_ = stream;
    202     first_ = true;
    203   }
    204 
    205   void Add(const char* str) {
    206     if (first_) {
    207       first_ = false;
    208     } else {
    209       stream_->Put(separator_);
    210     }
    211     stream_->Add(str);
    212   }
    213 
    214  private:
    215   bool first_;
    216   char separator_;
    217   StringStream* stream_;
    218 };
    219 
    220 
    221 } }  // namespace v8::internal
    222 
    223 #endif  // V8_STRING_STREAM_H_
    224