OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "v8_binding.h" | |
6 | |
7 #include "AtomicString.h" | |
8 #include "CString.h" | |
9 #include "MathExtras.h" | |
10 #include "PlatformString.h" | |
11 #include "StringBuffer.h" | |
12 | |
13 #include <v8.h> | |
14 | |
15 namespace WebCore { | |
16 | |
17 // WebCoreStringResource is a helper class for v8ExternalString. It is used | |
18 // to manage the life-cycle of the underlying buffer of the external string. | |
19 class WebCoreStringResource: public v8::String::ExternalStringResource { | |
20 public: | |
21 explicit WebCoreStringResource(const String& str) | |
22 : impl_(str.impl()) { } | |
23 | |
24 virtual ~WebCoreStringResource() {} | |
25 | |
26 const uint16_t* data() const { | |
27 return reinterpret_cast<const uint16_t*>(impl_.characters()); | |
28 } | |
29 | |
30 size_t length() const { return impl_.length(); } | |
31 | |
32 String webcore_string() { return impl_; } | |
33 | |
34 private: | |
35 // A shallow copy of the string. | |
36 // Keeps the string buffer alive until the V8 engine garbage collects it. | |
37 String impl_; | |
38 }; | |
39 | |
40 | |
41 String v8StringToWebCoreString( | |
42 v8::Handle<v8::String> v8_str, bool externalize) { | |
43 WebCoreStringResource* str_resource = static_cast<WebCoreStringResource*>( | |
44 v8_str->GetExternalStringResource()); | |
45 if (str_resource) { | |
46 return str_resource->webcore_string(); | |
47 } | |
48 | |
49 int length = v8_str->Length(); | |
50 if (length == 0) { | |
51 // Avoid trying to morph empty strings, as they do not have enough room to | |
52 // contain the external reference. | |
53 return StringImpl::empty(); | |
54 } | |
55 | |
56 UChar* buffer; | |
57 String result = String::createUninitialized(length, buffer); | |
58 v8_str->Write(reinterpret_cast<uint16_t*>(buffer), 0, length); | |
59 | |
60 if (externalize) { | |
61 WebCoreStringResource* resource = new WebCoreStringResource(result); | |
62 if (!v8_str->MakeExternal(resource)) { | |
63 // In case of a failure delete the external resource as it was not used. | |
64 delete resource; | |
65 } | |
66 } | |
67 return result; | |
68 } | |
69 | |
70 | |
71 String v8ValueToWebCoreString(v8::Handle<v8::Value> obj) { | |
72 if (obj->IsString()) { | |
73 v8::Handle<v8::String> v8_str = v8::Handle<v8::String>::Cast(obj); | |
74 String webCoreString = v8StringToWebCoreString(v8_str, true); | |
75 return webCoreString; | |
76 } else if (obj->IsInt32()) { | |
77 int value = obj->Int32Value(); | |
78 // Most numbers used are <= 100. Even if they aren't used | |
79 // there's very little in using the space. | |
80 const int kLowNumbers = 100; | |
81 static AtomicString lowNumbers[kLowNumbers + 1]; | |
82 String webCoreString; | |
83 if (0 <= value && value <= kLowNumbers) { | |
84 webCoreString = lowNumbers[value]; | |
85 if (!webCoreString) { | |
86 AtomicString valueString = AtomicString(String::number(value)); | |
87 lowNumbers[value] = valueString; | |
88 webCoreString = valueString; | |
89 } | |
90 } else { | |
91 webCoreString = String::number(value); | |
92 } | |
93 return webCoreString; | |
94 } else { | |
95 v8::TryCatch block; | |
96 v8::Handle<v8::String> v8_str = obj->ToString(); | |
97 // Check for empty handles to handle the case where an exception | |
98 // is thrown as part of invoking toString on the object. | |
99 if (v8_str.IsEmpty()) | |
100 return StringImpl::empty(); | |
101 return v8StringToWebCoreString(v8_str, false); | |
102 } | |
103 } | |
104 | |
105 | |
106 AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String> v8_str) { | |
107 String str = v8StringToWebCoreString(v8_str, true); | |
108 return AtomicString(str); | |
109 } | |
110 | |
111 | |
112 AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> v8_str) { | |
113 String str = v8ValueToWebCoreString(v8_str); | |
114 return AtomicString(str); | |
115 } | |
116 | |
117 | |
118 v8::Handle<v8::String> v8String(const String& str) { | |
119 if (!str.length()) | |
120 return v8::String::Empty(); | |
121 return v8::String::NewExternal(new WebCoreStringResource(str)); | |
122 } | |
123 | |
124 v8::Local<v8::String> v8ExternalString(const String& str) { | |
125 if (!str.length()) | |
126 return v8::String::Empty(); | |
127 return v8::String::NewExternal(new WebCoreStringResource(str)); | |
128 } | |
129 | |
130 } // namespace WebCore | |
OLD | NEW |