📄 string-stream.cc.svn-base
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met://// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following// disclaimer in the documentation and/or other materials provided// with the distribution.// * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived// from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include "v8.h"#include "factory.h"#include "string-stream.h"namespace v8 { namespace internal {static const int kMentionedObjectCacheMaxSize = 256;static List<HeapObject*, PreallocatedStorage>* debug_object_cache = NULL;static Object* current_security_token = NULL;char* HeapStringAllocator::allocate(unsigned bytes) { space_ = NewArray<char>(bytes); return space_;}NoAllocationStringAllocator::NoAllocationStringAllocator(unsigned bytes) { size_ = bytes; space_ = NewArray<char>(bytes);}NoAllocationStringAllocator::NoAllocationStringAllocator(char* memory, unsigned size) { size_ = size; space_ = memory;}bool StringStream::Put(char c) { if (space() == 0) return false; if (length_ >= capacity_ - 1) { unsigned new_capacity = capacity_; char* new_buffer = allocator_->grow(&new_capacity); if (new_capacity > capacity_) { capacity_ = new_capacity; buffer_ = new_buffer; } else { // Indicate truncation with dots. memset(cursor(), '.', space()); length_ = capacity_; buffer_[length_ - 2] = '\n'; buffer_[length_ - 1] = '\0'; return false; } } buffer_[length_] = c; buffer_[length_ + 1] = '\0'; length_++; return true;}// A control character is one that configures a format element. For// instance, in %.5s, .5 are control characters.static bool IsControlChar(char c) { switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case '-': return true; default: return false; }}void StringStream::Add(const char* format, Vector<FmtElm> elms) { // If we already ran out of space then return immediately. if (space() == 0) return; int offset = 0; int elm = 0; while (format[offset] != '\0') { if (format[offset] != '%' || elm == elms.length()) { Put(format[offset]); offset++; continue; } // Read this formatting directive into a temporary buffer EmbeddedVector<char, 24> temp; int format_length = 0; // Skip over the whole control character sequence until the // format element type temp[format_length++] = format[offset++]; // '\0' is not a control character so we don't have to // explicitly check for the end of the string while (IsControlChar(format[offset])) temp[format_length++] = format[offset++]; char type = format[offset]; if (type == '\0') return; temp[format_length++] = type; temp[format_length] = '\0'; offset++; FmtElm current = elms[elm++]; switch (type) { case 's': { ASSERT_EQ(FmtElm::C_STR, current.type_); const char* value = current.data_.u_c_str_; Add(value); break; } case 'o': { ASSERT_EQ(FmtElm::OBJ, current.type_); Object* obj = current.data_.u_obj_; PrintObject(obj); break; } case 'i': case 'd': case 'u': case 'x': case 'c': case 'p': { int value = current.data_.u_int_; EmbeddedVector<char, 24> formatted; OS::SNPrintF(formatted, temp.start(), value); Add(formatted.start()); break; } default: UNREACHABLE(); break; } } // Verify that the buffer is 0-terminated and doesn't contain any // other 0-characters. ASSERT(buffer_[length_] == '\0'); ASSERT(strlen(buffer_) == length_);}void StringStream::PrintObject(Object* o) { o->ShortPrint(this); if (o->IsString()) { if (String::cast(o)->length() <= String::kMaxMediumStringSize) { return; } } else if (o->IsNumber() || o->IsOddball()) { return; } if (o->IsHeapObject()) { for (int i = 0; i < debug_object_cache->length(); i++) { if ((*debug_object_cache)[i] == o) { Add("#%d#", i); return; } } if (debug_object_cache->length() < kMentionedObjectCacheMaxSize) { Add("#%d#", debug_object_cache->length()); debug_object_cache->Add(HeapObject::cast(o)); } else { Add("@%p", o); } }}void StringStream::Add(const char* format) { Add(format, Vector<FmtElm>::empty());}void StringStream::Add(const char* format, FmtElm arg0) { const char argc = 1; FmtElm argv[argc] = { arg0 }; Add(format, Vector<FmtElm>(argv, argc));}void StringStream::Add(const char* format, FmtElm arg0, FmtElm arg1) { const char argc = 2; FmtElm argv[argc] = { arg0, arg1 }; Add(format, Vector<FmtElm>(argv, argc));}void StringStream::Add(const char* format, FmtElm arg0, FmtElm arg1, FmtElm arg2) { const char argc = 3; FmtElm argv[argc] = { arg0, arg1, arg2 }; Add(format, Vector<FmtElm>(argv, argc));}SmartPointer<char> StringStream::ToCString() { char* str = NewArray<char>(length_ + 1); memcpy(str, buffer_, length_); str[length_] = '\0'; return SmartPointer<char>(str);}void StringStream::Log() { LOG(StringEvent("StackDump", buffer_));}void StringStream::OutputToStdOut() { // Dump the output to stdout, but make sure to break it up into // manageable chunks to avoid losing parts of the output in the OS // printing code. This is a problem on Windows in particular; see // the VPrint() function implementations in platform-win32.cc. unsigned position = 0; for (unsigned next; (next = position + 2048) < length_; position = next) { char save = buffer_[next]; buffer_[next] = '\0'; internal::PrintF("%s", &buffer_[position]); buffer_[next] = save; } internal::PrintF("%s", &buffer_[position]);}Handle<String> StringStream::ToString() { return Factory::NewStringFromUtf8(Vector<const char>(buffer_, length_));}void StringStream::ClearMentionedObjectCache() { current_security_token = NULL; if (debug_object_cache == NULL) { debug_object_cache = new List<HeapObject*, PreallocatedStorage>(0); } debug_object_cache->Clear();}#ifdef DEBUGbool StringStream::IsMentionedObjectCacheClear() { return (debug_object_cache->length() == 0);}#endifbool StringStream::Put(String* str) { return Put(str, 0, str->length());}bool StringStream::Put(String* str, int start, int end) { StringInputBuffer name_buffer(str); name_buffer.Seek(start); for (int i = start; i < end && name_buffer.has_more(); i++) { int c = name_buffer.GetNext(); if (c >= 127 || c < 32) { c = '?'; } if (!Put(c)) { return false; // Output was truncated. } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -