From 011b136ee057af3554e64e816e6b98113c2cd8ca Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Tue, 23 Aug 2011 11:11:12 +0000 Subject: [PATCH] Slight API change enabling opting out from null termination in String::Write*(). BUG=v8:1537 TEST=cctest test-api/StringWrite Review URL: http://codereview.chromium.org/7706002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8996 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 17 +++++++++-------- src/api.cc | 20 +++++++++++--------- test/cctest/test-api.cc | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 17 deletions(-) diff --git a/include/v8.h b/include/v8.h index 46e4f0d..5a78160 100644 --- a/include/v8.h +++ b/include/v8.h @@ -1039,29 +1039,30 @@ class String : public Primitive { * \param length The number of characters to copy from the string. For * WriteUtf8 the number of bytes in the buffer. * \param nchars_ref The number of characters written, can be NULL. - * \param hints Various hints that might affect performance of this or + * \param options Various options that might affect performance of this or * subsequent operations. * \return The number of characters copied to the buffer excluding the null * terminator. For WriteUtf8: The number of bytes copied to the buffer - * including the null terminator. + * including the null terminator (if written). */ - enum WriteHints { - NO_HINTS = 0, - HINT_MANY_WRITES_EXPECTED = 1 + enum WriteOptions { + NO_OPTIONS = 0, + HINT_MANY_WRITES_EXPECTED = 1, + NO_NULL_TERMINATION = 2 }; V8EXPORT int Write(uint16_t* buffer, int start = 0, int length = -1, - WriteHints hints = NO_HINTS) const; // UTF-16 + int options = NO_OPTIONS) const; // UTF-16 V8EXPORT int WriteAscii(char* buffer, int start = 0, int length = -1, - WriteHints hints = NO_HINTS) const; // ASCII + int options = NO_OPTIONS) const; // ASCII V8EXPORT int WriteUtf8(char* buffer, int length = -1, int* nchars_ref = NULL, - WriteHints hints = NO_HINTS) const; // UTF-8 + int options = NO_OPTIONS) const; // UTF-8 /** * A zero length string. diff --git a/src/api.cc b/src/api.cc index f629116..0207f51 100644 --- a/src/api.cc +++ b/src/api.cc @@ -3621,7 +3621,7 @@ int String::Utf8Length() const { int String::WriteUtf8(char* buffer, int capacity, int* nchars_ref, - WriteHints hints) const { + int options) const { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0; LOG_API(isolate, "String::WriteUtf8"); @@ -3629,7 +3629,7 @@ int String::WriteUtf8(char* buffer, i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer(); i::Handle str = Utils::OpenHandle(this); isolate->string_tracker()->RecordWrite(str); - if (hints & HINT_MANY_WRITES_EXPECTED) { + if (options & HINT_MANY_WRITES_EXPECTED) { // Flatten the string for efficiency. This applies whether we are // using StringInputBuffer or Get(i) to access the characters. str->TryFlatten(); @@ -3669,7 +3669,8 @@ int String::WriteUtf8(char* buffer, } } if (nchars_ref != NULL) *nchars_ref = nchars; - if (i == len && (capacity == -1 || pos < capacity)) + if (!(options & NO_NULL_TERMINATION) && + (i == len && (capacity == -1 || pos < capacity))) buffer[pos++] = '\0'; return pos; } @@ -3678,7 +3679,7 @@ int String::WriteUtf8(char* buffer, int String::WriteAscii(char* buffer, int start, int length, - WriteHints hints) const { + int options) const { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0; LOG_API(isolate, "String::WriteAscii"); @@ -3687,7 +3688,7 @@ int String::WriteAscii(char* buffer, ASSERT(start >= 0 && length >= -1); i::Handle str = Utils::OpenHandle(this); isolate->string_tracker()->RecordWrite(str); - if (hints & HINT_MANY_WRITES_EXPECTED) { + if (options & HINT_MANY_WRITES_EXPECTED) { // Flatten the string for efficiency. This applies whether we are // using StringInputBuffer or Get(i) to access the characters. str->TryFlatten(); @@ -3703,7 +3704,7 @@ int String::WriteAscii(char* buffer, if (c == '\0') c = ' '; buffer[i] = c; } - if (length == -1 || i < length) + if (!(options & NO_NULL_TERMINATION) && (length == -1 || i < length)) buffer[i] = '\0'; return i; } @@ -3712,7 +3713,7 @@ int String::WriteAscii(char* buffer, int String::Write(uint16_t* buffer, int start, int length, - WriteHints hints) const { + int options) const { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); if (IsDeadCheck(isolate, "v8::String::Write()")) return 0; LOG_API(isolate, "String::Write"); @@ -3720,7 +3721,7 @@ int String::Write(uint16_t* buffer, ASSERT(start >= 0 && length >= -1); i::Handle str = Utils::OpenHandle(this); isolate->string_tracker()->RecordWrite(str); - if (hints & HINT_MANY_WRITES_EXPECTED) { + if (options & HINT_MANY_WRITES_EXPECTED) { // Flatten the string for efficiency. This applies whether we are // using StringInputBuffer or Get(i) to access the characters. str->TryFlatten(); @@ -3730,7 +3731,8 @@ int String::Write(uint16_t* buffer, end = str->length(); if (end < 0) return 0; i::String::WriteToFlat(*str, buffer, start, end); - if (length == -1 || end - start < length) { + if (!(options & NO_NULL_TERMINATION) && + (length == -1 || end - start < length)) { buffer[end - start] = '\0'; } return end - start; diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index e206bb9..aeb4cbe 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -5296,6 +5296,40 @@ THREADED_TEST(StringWrite) { CHECK_EQ(0, strncmp("d\1", buf, 2)); uint16_t answer7[] = {'d', 0x101}; CHECK_EQ(0, StrNCmp16(answer7, wbuf, 2)); + + memset(wbuf, 0x1, sizeof(wbuf)); + wbuf[5] = 'X'; + len = str->Write(wbuf, 0, 6, String::NO_NULL_TERMINATION); + CHECK_EQ(5, len); + CHECK_EQ('X', wbuf[5]); + uint16_t answer8a[] = {'a', 'b', 'c', 'd', 'e'}; + uint16_t answer8b[] = {'a', 'b', 'c', 'd', 'e', '\0'}; + CHECK_EQ(0, StrNCmp16(answer8a, wbuf, 5)); + CHECK_NE(0, StrCmp16(answer8b, wbuf)); + wbuf[5] = '\0'; + CHECK_EQ(0, StrCmp16(answer8b, wbuf)); + + memset(buf, 0x1, sizeof(buf)); + buf[5] = 'X'; + len = str->WriteAscii(buf, 0, 6, String::NO_NULL_TERMINATION); + CHECK_EQ(5, len); + CHECK_EQ('X', buf[5]); + CHECK_EQ(0, strncmp("abcde", buf, 5)); + CHECK_NE(0, strcmp("abcde", buf)); + buf[5] = '\0'; + CHECK_EQ(0, strcmp("abcde", buf)); + + memset(utf8buf, 0x1, sizeof(utf8buf)); + utf8buf[8] = 'X'; + len = str2->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen, + String::NO_NULL_TERMINATION); + CHECK_EQ(8, len); + CHECK_EQ('X', utf8buf[8]); + CHECK_EQ(5, charlen); + CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\342\230\203", 8)); + CHECK_NE(0, strcmp(utf8buf, "abc\303\260\342\230\203")); + utf8buf[8] = '\0'; + CHECK_EQ(0, strcmp(utf8buf, "abc\303\260\342\230\203")); } -- 2.7.4