|
1 | 1 | #include "util.h"
|
| 2 | +#include "node_buffer.h" |
2 | 3 | #include "string_bytes.h"
|
3 | 4 |
|
4 | 5 | namespace node {
|
5 | 6 |
|
6 |
| -Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> value) |
7 |
| - : length_(0), str_(str_st_) { |
8 |
| - // Make sure result is always zero-terminated, even if conversion to string |
9 |
| - // fails. |
10 |
| - str_st_[0] = '\0'; |
| 7 | +using v8::Isolate; |
| 8 | +using v8::Local; |
| 9 | +using v8::String; |
| 10 | +using v8::Value; |
11 | 11 |
|
| 12 | +template <typename T> |
| 13 | +static void MakeUtf8String(Isolate* isolate, |
| 14 | + Local<Value> value, |
| 15 | + T* target) { |
| 16 | + Local<String> string = value->ToString(isolate); |
| 17 | + if (string.IsEmpty()) |
| 18 | + return; |
| 19 | + |
| 20 | + const size_t storage = StringBytes::StorageSize(isolate, string, UTF8) + 1; |
| 21 | + target->AllocateSufficientStorage(storage); |
| 22 | + const int flags = |
| 23 | + String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8; |
| 24 | + const int length = string->WriteUtf8(target->out(), storage, 0, flags); |
| 25 | + target->SetLengthAndZeroTerminate(length); |
| 26 | +} |
| 27 | + |
| 28 | +Utf8Value::Utf8Value(Isolate* isolate, Local<Value> value) { |
12 | 29 | if (value.IsEmpty())
|
13 | 30 | return;
|
14 | 31 |
|
| 32 | + MakeUtf8String(isolate, value, this); |
| 33 | +} |
| 34 | + |
| 35 | + |
| 36 | +TwoByteValue::TwoByteValue(Isolate* isolate, Local<Value> value) { |
| 37 | + if (value.IsEmpty()) { |
| 38 | + return; |
| 39 | + } |
| 40 | + |
15 | 41 | v8::Local<v8::String> string = value->ToString(isolate);
|
16 | 42 | if (string.IsEmpty())
|
17 | 43 | return;
|
18 | 44 |
|
19 | 45 | // Allocate enough space to include the null terminator
|
20 |
| - size_t len = StringBytes::StorageSize(isolate, string, UTF8) + 1; |
21 |
| - if (len > sizeof(str_st_)) { |
22 |
| - str_ = static_cast<char*>(malloc(len)); |
23 |
| - CHECK_NE(str_, nullptr); |
24 |
| - } |
| 46 | + const size_t storage = string->Length() + 1; |
| 47 | + AllocateSufficientStorage(storage); |
25 | 48 |
|
26 | 49 | const int flags =
|
27 |
| - v8::String::NO_NULL_TERMINATION | v8::String::REPLACE_INVALID_UTF8; |
28 |
| - length_ = string->WriteUtf8(str_, len, 0, flags); |
29 |
| - str_[length_] = '\0'; |
| 50 | + String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8; |
| 51 | + const int length = string->Write(out(), 0, storage, flags); |
| 52 | + SetLengthAndZeroTerminate(length); |
| 53 | +} |
| 54 | + |
| 55 | +BufferValue::BufferValue(Isolate* isolate, Local<Value> value) { |
| 56 | + // Slightly different take on Utf8Value. If value is a String, |
| 57 | + // it will return a Utf8 encoded string. If value is a Buffer, |
| 58 | + // it will copy the data out of the Buffer as is. |
| 59 | + if (value.IsEmpty()) { |
| 60 | + // Dereferencing this object will return nullptr. |
| 61 | + Invalidate(); |
| 62 | + return; |
| 63 | + } |
| 64 | + |
| 65 | + if (value->IsString()) { |
| 66 | + MakeUtf8String(isolate, value, this); |
| 67 | + } else if (Buffer::HasInstance(value)) { |
| 68 | + const size_t len = Buffer::Length(value); |
| 69 | + // Leave place for the terminating '\0' byte. |
| 70 | + AllocateSufficientStorage(len + 1); |
| 71 | + memcpy(out(), Buffer::Data(value), len); |
| 72 | + SetLengthAndZeroTerminate(len); |
| 73 | + } else { |
| 74 | + Invalidate(); |
| 75 | + } |
30 | 76 | }
|
31 | 77 |
|
32 | 78 | } // namespace node
|
0 commit comments