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  private:
     97   friend class StringStream;
     98   enum Type { INT, DOUBLE, C_STR, LC_STR, OBJ, HANDLE, POINTER };
     99   Type type_;
    100   union {
    101     int u_int_;
    102     double u_double_;
    103     const char* u_c_str_;
    104     const Vector<const uc16>* u_lc_str_;
    105     Object* u_obj_;
    106     Object** u_handle_;
    107     void* u_pointer_;
    108   } data_;
    109 };
    110 
    111 
    112 class StringStream {
    113  public:
    114   explicit StringStream(StringAllocator* allocator):
    115     allocator_(allocator),
    116     capacity_(kInitialCapacity),
    117     length_(0),
    118     buffer_(allocator_->allocate(kInitialCapacity)) {
    119     buffer_[0] = 0;
    120   }
    121 
    122   ~StringStream() {
    123   }
    124 
    125   bool Put(char c);
    126   bool Put(String* str);
    127   bool Put(String* str, int start, int end);
    128   void Add(Vector<const char> format, Vector<FmtElm> elms);
    129   void Add(const char* format);
    130   void Add(Vector<const char> format);
    131   void Add(const char* format, FmtElm arg0);
    132   void Add(const char* format, FmtElm arg0, FmtElm arg1);
    133   void Add(const char* format, FmtElm arg0, FmtElm arg1, FmtElm arg2);
    134   void Add(const char* format,
    135            FmtElm arg0,
    136            FmtElm arg1,
    137            FmtElm arg2,
    138            FmtElm arg3);
    139 
    140   // Getting the message out.
    141   void OutputToStdOut();
    142   void Log();
    143   Handle<String> ToString();
    144   SmartPointer<const char> ToCString() const;
    145 
    146   // Object printing support.
    147   void PrintName(Object* o);
    148   void PrintFixedArray(FixedArray* array, unsigned int limit);
    149   void PrintByteArray(ByteArray* ba);
    150   void PrintUsingMap(JSObject* js_object);
    151   void PrintPrototype(JSFunction* fun, Object* receiver);
    152   void PrintSecurityTokenIfChanged(Object* function);
    153   // NOTE: Returns the code in the output parameter.
    154   void PrintFunction(Object* function, Object* receiver, Code** code);
    155 
    156   // Reset the stream.
    157   void Reset() {
    158     length_ = 0;
    159     buffer_[0] = 0;
    160   }
    161 
    162   // Mentioned object cache support.
    163   void PrintMentionedObjectCache();
    164   static void ClearMentionedObjectCache();
    165 #ifdef DEBUG
    166   static bool IsMentionedObjectCacheClear();
    167 #endif
    168 
    169 
    170   static const int kInitialCapacity = 16;
    171 
    172  private:
    173   void PrintObject(Object* obj);
    174 
    175   StringAllocator* allocator_;
    176   unsigned capacity_;
    177   unsigned length_;  // does not include terminating 0-character
    178   char* buffer_;
    179 
    180   bool full() const { return (capacity_ - length_) == 1; }
    181   int space() const { return capacity_ - length_; }
    182 
    183   DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream);
    184 };
    185 
    186 
    187 } }  // namespace v8::internal
    188 
    189 #endif  // V8_STRING_STREAM_H_
    190