• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~StringAllocator()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:
~HeapStringAllocator()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);
allocate(unsigned bytes)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:
FmtElm(int value)75   FmtElm(int value) : type_(INT) {  // NOLINT
76     data_.u_int_ = value;
77   }
FmtElm(double value)78   explicit FmtElm(double value) : type_(DOUBLE) {
79     data_.u_double_ = value;
80   }
FmtElm(const char * value)81   FmtElm(const char* value) : type_(C_STR) {  // NOLINT
82     data_.u_c_str_ = value;
83   }
FmtElm(const Vector<const uc16> & value)84   FmtElm(const Vector<const uc16>& value) : type_(LC_STR) {  // NOLINT
85     data_.u_lc_str_ = &value;
86   }
FmtElm(Object * value)87   FmtElm(Object* value) : type_(OBJ) {  // NOLINT
88     data_.u_obj_ = value;
89   }
FmtElm(Handle<Object> value)90   FmtElm(Handle<Object> value) : type_(HANDLE) {  // NOLINT
91     data_.u_handle_ = value.location();
92   }
FmtElm(void * value)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:
StringStream(StringAllocator * allocator)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 
~StringStream()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 
141   // Getting the message out.
142   void OutputToFile(FILE* out);
OutputToStdOut()143   void OutputToStdOut() { OutputToFile(stdout); }
144   void Log();
145   Handle<String> ToString();
146   SmartArrayPointer<const char> ToCString() const;
length()147   int length() const { return length_; }
148 
149   // Object printing support.
150   void PrintName(Object* o);
151   void PrintFixedArray(FixedArray* array, unsigned int limit);
152   void PrintByteArray(ByteArray* ba);
153   void PrintUsingMap(JSObject* js_object);
154   void PrintPrototype(JSFunction* fun, Object* receiver);
155   void PrintSecurityTokenIfChanged(Object* function);
156   // NOTE: Returns the code in the output parameter.
157   void PrintFunction(Object* function, Object* receiver, Code** code);
158 
159   // Reset the stream.
Reset()160   void Reset() {
161     length_ = 0;
162     buffer_[0] = 0;
163   }
164 
165   // Mentioned object cache support.
166   void PrintMentionedObjectCache();
167   static void ClearMentionedObjectCache();
168 #ifdef DEBUG
169   static bool IsMentionedObjectCacheClear();
170 #endif
171 
172 
173   static const int kInitialCapacity = 16;
174 
175  private:
176   void PrintObject(Object* obj);
177 
178   StringAllocator* allocator_;
179   unsigned capacity_;
180   unsigned length_;  // does not include terminating 0-character
181   char* buffer_;
182 
full()183   bool full() const { return (capacity_ - length_) == 1; }
space()184   int space() const { return capacity_ - length_; }
185 
186   DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream);
187 };
188 
189 
190 } }  // namespace v8::internal
191 
192 #endif  // V8_STRING_STREAM_H_
193