Index: src/json-stringifier.h |
diff --git a/src/json-stringifier.h b/src/json-stringifier.h |
index f89a19fd4a9b06abf2b1dd4e17a86ef09d38cdd0..88309f318fdead7074ef1257ab020ed05208e4c7 100644 |
--- a/src/json-stringifier.h |
+++ b/src/json-stringifier.h |
@@ -8,6 +8,7 @@ |
#include "src/v8.h" |
#include "src/conversions.h" |
+#include "src/string-builder.h" |
#include "src/utils.h" |
namespace v8 { |
@@ -24,42 +25,8 @@ class BasicJsonStringifier BASE_EMBEDDED { |
Handle<String> object)); |
private: |
- static const int kInitialPartLength = 32; |
- static const int kMaxPartLength = 16 * 1024; |
- static const int kPartLengthGrowthFactor = 2; |
- |
enum Result { UNCHANGED, SUCCESS, EXCEPTION }; |
- void Accumulate(); |
- |
- void Extend(); |
- |
- void ChangeEncoding(); |
- |
- INLINE(void ShrinkCurrentPart()); |
- |
- template <bool is_one_byte, typename Char> |
- INLINE(void Append_(Char c)); |
- |
- template <bool is_one_byte, typename Char> |
- INLINE(void Append_(const Char* chars)); |
- |
- INLINE(void Append(uint8_t c)) { |
- if (is_one_byte_) { |
- Append_<true>(c); |
- } else { |
- Append_<false>(c); |
- } |
- } |
- |
- INLINE(void AppendOneByte(const char* chars)) { |
- if (is_one_byte_) { |
- Append_<true>(reinterpret_cast<const uint8_t*>(chars)); |
- } else { |
- Append_<false>(reinterpret_cast<const uint8_t*>(chars)); |
- } |
- } |
- |
MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction( |
Handle<Object> object, |
Handle<Object> key); |
@@ -69,14 +36,9 @@ class BasicJsonStringifier BASE_EMBEDDED { |
bool deferred_comma, |
bool deferred_key); |
- template <typename ResultType, typename Char> |
- INLINE(static Handle<String> StringifyString_(Isolate* isolate, |
- Vector<Char> vector, |
- Handle<String> result)); |
- |
// Entry point to serialize the object. |
INLINE(Result SerializeObject(Handle<Object> obj)) { |
- return Serialize_<false>(obj, false, factory_->empty_string()); |
+ return Serialize_<false>(obj, false, factory()->empty_string()); |
} |
// Serialize an array element. |
@@ -103,9 +65,9 @@ class BasicJsonStringifier BASE_EMBEDDED { |
Result Serialize_(Handle<Object> object, bool comma, Handle<Object> key); |
void SerializeDeferredKey(bool deferred_comma, Handle<Object> deferred_key) { |
- if (deferred_comma) Append(','); |
+ if (deferred_comma) builder_.AppendCharacter(','); |
SerializeString(Handle<String>::cast(deferred_key)); |
- Append(':'); |
+ builder_.AppendCharacter(':'); |
} |
Result SerializeSmi(Smi* object); |
@@ -125,11 +87,11 @@ class BasicJsonStringifier BASE_EMBEDDED { |
void SerializeString(Handle<String> object); |
template <typename SrcChar, typename DestChar> |
- INLINE(static int SerializeStringUnchecked_(const SrcChar* src, |
- DestChar* dest, |
- int length)); |
+ INLINE(static void SerializeStringUnchecked_( |
+ Vector<const SrcChar> src, |
+ IncrementalStringBuilder::NoExtend<DestChar>* dest)); |
- template <bool is_one_byte, typename Char> |
+ template <typename SrcChar, typename DestChar> |
INLINE(void SerializeString_(Handle<String> string)); |
template <typename Char> |
@@ -141,26 +103,12 @@ class BasicJsonStringifier BASE_EMBEDDED { |
Result StackPush(Handle<Object> object); |
void StackPop(); |
- INLINE(Handle<String> accumulator()) { |
- return Handle<String>(String::cast(accumulator_store_->value()), isolate_); |
- } |
- |
- INLINE(void set_accumulator(Handle<String> string)) { |
- return accumulator_store_->set_value(*string); |
- } |
+ Factory* factory() { return isolate_->factory(); } |
Isolate* isolate_; |
- Factory* factory_; |
- // We use a value wrapper for the string accumulator to keep the |
- // (indirect) handle to it in the outermost handle scope. |
- Handle<JSValue> accumulator_store_; |
- Handle<String> current_part_; |
+ IncrementalStringBuilder builder_; |
Handle<String> tojson_string_; |
Handle<JSArray> stack_; |
- int current_index_; |
- int part_length_; |
- bool is_one_byte_; |
- bool overflowed_; |
static const int kJsonEscapeTableEntrySize = 8; |
static const char* const JsonEscapeTable; |
@@ -237,31 +185,16 @@ const char* const BasicJsonStringifier::JsonEscapeTable = |
BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate) |
- : isolate_(isolate), |
- current_index_(0), |
- is_one_byte_(true), |
- overflowed_(false) { |
- factory_ = isolate_->factory(); |
- accumulator_store_ = Handle<JSValue>::cast( |
- Object::ToObject(isolate, factory_->empty_string()).ToHandleChecked()); |
- part_length_ = kInitialPartLength; |
- current_part_ = factory_->NewRawOneByteString(part_length_).ToHandleChecked(); |
- tojson_string_ = factory_->toJSON_string(); |
- stack_ = factory_->NewJSArray(8); |
+ : isolate_(isolate), builder_(isolate) { |
+ tojson_string_ = factory()->toJSON_string(); |
+ stack_ = factory()->NewJSArray(8); |
} |
MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object) { |
Result result = SerializeObject(object); |
- if (result == UNCHANGED) return isolate_->factory()->undefined_value(); |
- if (result == SUCCESS) { |
- ShrinkCurrentPart(); |
- Accumulate(); |
- if (overflowed_) { |
- THROW_NEW_ERROR(isolate_, NewInvalidStringLengthError(), Object); |
- } |
- return accumulator(); |
- } |
+ if (result == UNCHANGED) return factory()->undefined_value(); |
+ if (result == SUCCESS) return builder_.Finish(); |
DCHECK(result == EXCEPTION); |
return MaybeHandle<Object>(); |
} |
@@ -281,58 +214,29 @@ MaybeHandle<Object> BasicJsonStringifier::StringifyString( |
object = String::Flatten(object); |
DCHECK(object->IsFlat()); |
+ Handle<SeqString> result; |
if (object->IsOneByteRepresentationUnderneath()) { |
- Handle<String> result = isolate->factory()->NewRawOneByteString( |
- worst_case_length).ToHandleChecked(); |
- DisallowHeapAllocation no_gc; |
- return StringifyString_<SeqOneByteString>( |
- isolate, |
- object->GetFlatContent().ToOneByteVector(), |
- result); |
- } else { |
- Handle<String> result = isolate->factory()->NewRawTwoByteString( |
- worst_case_length).ToHandleChecked(); |
- DisallowHeapAllocation no_gc; |
- return StringifyString_<SeqTwoByteString>( |
- isolate, |
- object->GetFlatContent().ToUC16Vector(), |
- result); |
- } |
-} |
- |
- |
-template <typename ResultType, typename Char> |
-Handle<String> BasicJsonStringifier::StringifyString_(Isolate* isolate, |
- Vector<Char> vector, |
- Handle<String> result) { |
- DisallowHeapAllocation no_gc; |
- int final_size = 0; |
- ResultType* dest = ResultType::cast(*result); |
- dest->Set(final_size++, '\"'); |
- final_size += SerializeStringUnchecked_(vector.start(), |
- dest->GetChars() + 1, |
- vector.length()); |
- dest->Set(final_size++, '\"'); |
- return SeqString::Truncate(Handle<SeqString>::cast(result), final_size); |
-} |
- |
- |
-template <bool is_one_byte, typename Char> |
-void BasicJsonStringifier::Append_(Char c) { |
- if (is_one_byte) { |
- SeqOneByteString::cast(*current_part_)->SeqOneByteStringSet( |
- current_index_++, c); |
+ result = isolate->factory() |
+ ->NewRawOneByteString(worst_case_length) |
+ .ToHandleChecked(); |
+ IncrementalStringBuilder::NoExtendString<uint8_t> no_extend( |
+ result, worst_case_length); |
+ no_extend.Append('\"'); |
+ SerializeStringUnchecked_(object->GetFlatContent().ToOneByteVector(), |
+ &no_extend); |
+ no_extend.Append('\"'); |
} else { |
- SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet( |
- current_index_++, c); |
+ result = isolate->factory() |
+ ->NewRawTwoByteString(worst_case_length) |
+ .ToHandleChecked(); |
+ IncrementalStringBuilder::NoExtendString<uc16> no_extend(result, |
+ worst_case_length); |
+ no_extend.Append('\"'); |
+ SerializeStringUnchecked_(object->GetFlatContent().ToUC16Vector(), |
+ &no_extend); |
+ no_extend.Append('\"'); |
} |
- if (current_index_ == part_length_) Extend(); |
-} |
- |
- |
-template <bool is_one_byte, typename Char> |
-void BasicJsonStringifier::Append_(const Char* chars) { |
- for (; *chars != '\0'; chars++) Append_<is_one_byte, Char>(*chars); |
+ return result; |
} |
@@ -345,7 +249,7 @@ MaybeHandle<Object> BasicJsonStringifier::ApplyToJsonFunction( |
if (!fun->IsJSFunction()) return object; |
// Call toJSON function. |
- if (key->IsSmi()) key = factory_->NumberToString(key); |
+ if (key->IsSmi()) key = factory()->NumberToString(key); |
Handle<Object> argv[] = { key }; |
HandleScope scope(isolate_); |
ASSIGN_RETURN_ON_EXCEPTION( |
@@ -372,7 +276,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::StackPush( |
if (elements->get(i) == *object) { |
AllowHeapAllocation allow_to_return_error; |
Handle<Object> error; |
- MaybeHandle<Object> maybe_error = factory_->NewTypeError( |
+ MaybeHandle<Object> maybe_error = factory()->NewTypeError( |
"circular_structure", HandleVector<Object>(NULL, 0)); |
if (maybe_error.ToHandle(&error)) isolate_->Throw(*error); |
return EXCEPTION; |
@@ -416,15 +320,15 @@ BasicJsonStringifier::Result BasicJsonStringifier::Serialize_( |
switch (Oddball::cast(*object)->kind()) { |
case Oddball::kFalse: |
if (deferred_string_key) SerializeDeferredKey(comma, key); |
- AppendOneByte("false"); |
+ builder_.AppendCString("false"); |
return SUCCESS; |
case Oddball::kTrue: |
if (deferred_string_key) SerializeDeferredKey(comma, key); |
- AppendOneByte("true"); |
+ builder_.AppendCString("true"); |
return SUCCESS; |
case Oddball::kNull: |
if (deferred_string_key) SerializeDeferredKey(comma, key); |
- AppendOneByte("null"); |
+ builder_.AppendCString("null"); |
return SUCCESS; |
default: |
return UNCHANGED; |
@@ -472,23 +376,11 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric( |
EXCEPTION); |
if (result->IsUndefined()) return UNCHANGED; |
if (deferred_key) { |
- if (key->IsSmi()) key = factory_->NumberToString(key); |
+ if (key->IsSmi()) key = factory()->NumberToString(key); |
SerializeDeferredKey(deferred_comma, key); |
} |
- Handle<String> result_string = Handle<String>::cast(result); |
- // Shrink current part, attach it to the accumulator, also attach the result |
- // string to the accumulator, and allocate a new part. |
- ShrinkCurrentPart(); // Shrink. |
- part_length_ = kInitialPartLength; // Allocate conservatively. |
- Extend(); // Attach current part and allocate new part. |
- // Attach result string to the accumulator. |
- Handle<String> cons; |
- ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
- isolate_, cons, |
- factory_->NewConsString(accumulator(), result_string), |
- EXCEPTION); |
- set_accumulator(cons); |
+ builder_.AppendString(Handle<String>::cast(result)); |
return SUCCESS; |
} |
@@ -511,7 +403,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue( |
DCHECK(class_name == isolate_->heap()->Boolean_string()); |
Object* value = JSValue::cast(*object)->value(); |
DCHECK(value->IsBoolean()); |
- AppendOneByte(value->IsTrue() ? "true" : "false"); |
+ builder_.AppendCString(value->IsTrue() ? "true" : "false"); |
} |
return SUCCESS; |
} |
@@ -521,7 +413,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeSmi(Smi* object) { |
static const int kBufferSize = 100; |
char chars[kBufferSize]; |
Vector<char> buffer(chars, kBufferSize); |
- AppendOneByte(IntToCString(object->value(), buffer)); |
+ builder_.AppendCString(IntToCString(object->value(), buffer)); |
return SUCCESS; |
} |
@@ -529,13 +421,13 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeSmi(Smi* object) { |
BasicJsonStringifier::Result BasicJsonStringifier::SerializeDouble( |
double number) { |
if (std::isinf(number) || std::isnan(number)) { |
- AppendOneByte("null"); |
+ builder_.AppendCString("null"); |
return SUCCESS; |
} |
static const int kBufferSize = 100; |
char chars[kBufferSize]; |
Vector<char> buffer(chars, kBufferSize); |
- AppendOneByte(DoubleToCString(number, buffer)); |
+ builder_.AppendCString(DoubleToCString(number, buffer)); |
return SUCCESS; |
} |
@@ -547,13 +439,13 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( |
if (stack_push != SUCCESS) return stack_push; |
uint32_t length = 0; |
CHECK(object->length()->ToArrayIndex(&length)); |
- Append('['); |
+ builder_.AppendCharacter('['); |
switch (object->GetElementsKind()) { |
case FAST_SMI_ELEMENTS: { |
Handle<FixedArray> elements( |
FixedArray::cast(object->elements()), isolate_); |
for (uint32_t i = 0; i < length; i++) { |
- if (i > 0) Append(','); |
+ if (i > 0) builder_.AppendCharacter(','); |
SerializeSmi(Smi::cast(elements->get(i))); |
} |
break; |
@@ -564,7 +456,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( |
Handle<FixedDoubleArray> elements( |
FixedDoubleArray::cast(object->elements()), isolate_); |
for (uint32_t i = 0; i < length; i++) { |
- if (i > 0) Append(','); |
+ if (i > 0) builder_.AppendCharacter(','); |
SerializeDouble(elements->get_scalar(i)); |
} |
break; |
@@ -573,14 +465,14 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( |
Handle<FixedArray> elements( |
FixedArray::cast(object->elements()), isolate_); |
for (uint32_t i = 0; i < length; i++) { |
- if (i > 0) Append(','); |
+ if (i > 0) builder_.AppendCharacter(','); |
Result result = |
SerializeElement(isolate_, |
Handle<Object>(elements->get(i), isolate_), |
i); |
if (result == SUCCESS) continue; |
if (result == UNCHANGED) { |
- AppendOneByte("null"); |
+ builder_.AppendCString("null"); |
} else { |
return result; |
} |
@@ -596,9 +488,8 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( |
break; |
} |
} |
- Append(']'); |
+ builder_.AppendCharacter(']'); |
StackPop(); |
- current_part_ = handle_scope.CloseAndEscape(current_part_); |
return SUCCESS; |
} |
@@ -606,19 +497,19 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( |
BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArraySlow( |
Handle<JSArray> object, uint32_t length) { |
for (uint32_t i = 0; i < length; i++) { |
- if (i > 0) Append(','); |
+ if (i > 0) builder_.AppendCharacter(','); |
Handle<Object> element; |
ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
isolate_, element, |
Object::GetElement(isolate_, object, i), |
EXCEPTION); |
if (element->IsUndefined()) { |
- AppendOneByte("null"); |
+ builder_.AppendCString("null"); |
} else { |
Result result = SerializeElement(isolate_, element, i); |
if (result == SUCCESS) continue; |
if (result == UNCHANGED) { |
- AppendOneByte("null"); |
+ builder_.AppendCString("null"); |
} else { |
return result; |
} |
@@ -635,7 +526,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( |
if (stack_push != SUCCESS) return stack_push; |
DCHECK(!object->IsJSGlobalProxy() && !object->IsGlobalObject()); |
- Append('{'); |
+ builder_.AppendCharacter('{'); |
bool comma = false; |
if (object->HasFastProperties() && |
@@ -680,7 +571,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( |
maybe_property = Object::GetPropertyOrElement(object, key_handle); |
} else { |
DCHECK(key->IsNumber()); |
- key_handle = factory_->NumberToString(Handle<Object>(key, isolate_)); |
+ key_handle = factory()->NumberToString(Handle<Object>(key, isolate_)); |
uint32_t index; |
if (key->IsSmi()) { |
maybe_property = Object::GetElement( |
@@ -700,130 +591,67 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( |
} |
} |
- Append('}'); |
+ builder_.AppendCharacter('}'); |
StackPop(); |
- current_part_ = handle_scope.CloseAndEscape(current_part_); |
return SUCCESS; |
} |
-void BasicJsonStringifier::ShrinkCurrentPart() { |
- DCHECK(current_index_ < part_length_); |
- current_part_ = SeqString::Truncate(Handle<SeqString>::cast(current_part_), |
- current_index_); |
-} |
- |
- |
-void BasicJsonStringifier::Accumulate() { |
- if (accumulator()->length() + current_part_->length() > String::kMaxLength) { |
- // Screw it. Simply set the flag and carry on. Throw exception at the end. |
- set_accumulator(factory_->empty_string()); |
- overflowed_ = true; |
- } else { |
- set_accumulator(factory_->NewConsString(accumulator(), |
- current_part_).ToHandleChecked()); |
- } |
-} |
- |
- |
-void BasicJsonStringifier::Extend() { |
- Accumulate(); |
- if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) { |
- part_length_ *= kPartLengthGrowthFactor; |
- } |
- if (is_one_byte_) { |
- current_part_ = |
- factory_->NewRawOneByteString(part_length_).ToHandleChecked(); |
- } else { |
- current_part_ = |
- factory_->NewRawTwoByteString(part_length_).ToHandleChecked(); |
- } |
- DCHECK(!current_part_.is_null()); |
- current_index_ = 0; |
-} |
- |
- |
-void BasicJsonStringifier::ChangeEncoding() { |
- ShrinkCurrentPart(); |
- Accumulate(); |
- current_part_ = |
- factory_->NewRawTwoByteString(part_length_).ToHandleChecked(); |
- DCHECK(!current_part_.is_null()); |
- current_index_ = 0; |
- is_one_byte_ = false; |
-} |
- |
- |
template <typename SrcChar, typename DestChar> |
-int BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src, |
- DestChar* dest, |
- int length) { |
- DestChar* dest_start = dest; |
- |
+void BasicJsonStringifier::SerializeStringUnchecked_( |
+ Vector<const SrcChar> src, |
+ IncrementalStringBuilder::NoExtend<DestChar>* dest) { |
// Assert that uc16 character is not truncated down to 8 bit. |
// The <uc16, char> version of this method must not be called. |
- DCHECK(sizeof(*dest) >= sizeof(*src)); |
+ DCHECK(sizeof(DestChar) >= sizeof(SrcChar)); |
- for (int i = 0; i < length; i++) { |
+ for (int i = 0; i < src.length(); i++) { |
SrcChar c = src[i]; |
if (DoNotEscape(c)) { |
- *(dest++) = static_cast<DestChar>(c); |
+ dest->Append(c); |
} else { |
- const uint8_t* chars = reinterpret_cast<const uint8_t*>( |
- &JsonEscapeTable[c * kJsonEscapeTableEntrySize]); |
- while (*chars != '\0') *(dest++) = *(chars++); |
+ dest->AppendCString(&JsonEscapeTable[c * kJsonEscapeTableEntrySize]); |
} |
} |
- |
- return static_cast<int>(dest - dest_start); |
} |
-template <bool is_one_byte, typename Char> |
+template <typename SrcChar, typename DestChar> |
void BasicJsonStringifier::SerializeString_(Handle<String> string) { |
int length = string->length(); |
- Append_<is_one_byte, char>('"'); |
+ builder_.Append<uint8_t, DestChar>('"'); |
// We make a rough estimate to find out if the current string can be |
// serialized without allocating a new string part. The worst case length of |
// an escaped character is 6. Shifting the remainin string length right by 3 |
// is a more pessimistic estimate, but faster to calculate. |
- |
- if (((part_length_ - current_index_) >> 3) > length) { |
+ int worst_case_length = length << 3; |
+ if (builder_.CurrentPartCanFit(worst_case_length)) { |
DisallowHeapAllocation no_gc; |
- Vector<const Char> vector = GetCharVector<Char>(string); |
- if (is_one_byte) { |
- current_index_ += SerializeStringUnchecked_( |
- vector.start(), |
- SeqOneByteString::cast(*current_part_)->GetChars() + current_index_, |
- length); |
- } else { |
- current_index_ += SerializeStringUnchecked_( |
- vector.start(), |
- SeqTwoByteString::cast(*current_part_)->GetChars() + current_index_, |
- length); |
- } |
+ Vector<const SrcChar> vector = GetCharVector<SrcChar>(string); |
+ IncrementalStringBuilder::NoExtendBuilder<DestChar> no_extend( |
+ &builder_, worst_case_length); |
+ SerializeStringUnchecked_(vector, &no_extend); |
} else { |
String* string_location = NULL; |
- Vector<const Char> vector(NULL, 0); |
+ Vector<const SrcChar> vector(NULL, 0); |
for (int i = 0; i < length; i++) { |
// If GC moved the string, we need to refresh the vector. |
if (*string != string_location) { |
DisallowHeapAllocation no_gc; |
// This does not actually prevent the string from being relocated later. |
- vector = GetCharVector<Char>(string); |
+ vector = GetCharVector<SrcChar>(string); |
string_location = *string; |
} |
- Char c = vector[i]; |
+ SrcChar c = vector[i]; |
if (DoNotEscape(c)) { |
- Append_<is_one_byte, Char>(c); |
+ builder_.Append<SrcChar, DestChar>(c); |
} else { |
- Append_<is_one_byte, uint8_t>(reinterpret_cast<const uint8_t*>( |
- &JsonEscapeTable[c * kJsonEscapeTableEntrySize])); |
+ builder_.AppendCString(&JsonEscapeTable[c * kJsonEscapeTableEntrySize]); |
} |
} |
} |
- Append_<is_one_byte, uint8_t>('"'); |
+ builder_.Append<uint8_t, DestChar>('"'); |
} |
@@ -858,18 +686,18 @@ Vector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) { |
void BasicJsonStringifier::SerializeString(Handle<String> object) { |
object = String::Flatten(object); |
- if (is_one_byte_) { |
+ if (builder_.CurrentEncoding() == String::ONE_BYTE_ENCODING) { |
if (object->IsOneByteRepresentationUnderneath()) { |
- SerializeString_<true, uint8_t>(object); |
+ SerializeString_<uint8_t, uint8_t>(object); |
} else { |
- ChangeEncoding(); |
+ builder_.ChangeEncoding(); |
SerializeString(object); |
} |
} else { |
if (object->IsOneByteRepresentationUnderneath()) { |
- SerializeString_<false, uint8_t>(object); |
+ SerializeString_<uint8_t, uc16>(object); |
} else { |
- SerializeString_<false, uc16>(object); |
+ SerializeString_<uc16, uc16>(object); |
} |
} |
} |