Skip to content

Commit

Permalink
Slight API change enabling opting out from null termination in String…
Browse files Browse the repository at this point in the history
…::Write*().

BUG=v8:1537
TEST=cctest test-api/StringWrite

Review URL: http://codereview.chromium.org/7706002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@8996 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
  • Loading branch information
yangguo@chromium.org committed Aug 23, 2011
1 parent bda3004 commit 3cc4ef2
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 17 deletions.
17 changes: 9 additions & 8 deletions include/v8.h
Expand Up @@ -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.
Expand Down
20 changes: 11 additions & 9 deletions src/api.cc
Expand Up @@ -3621,15 +3621,15 @@ 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");
ENTER_V8(isolate);
i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
i::Handle<i::String> 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();
Expand Down Expand Up @@ -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;
}
Expand All @@ -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");
Expand All @@ -3687,7 +3688,7 @@ int String::WriteAscii(char* buffer,
ASSERT(start >= 0 && length >= -1);
i::Handle<i::String> 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();
Expand All @@ -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;
}
Expand All @@ -3712,15 +3713,15 @@ 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");
ENTER_V8(isolate);
ASSERT(start >= 0 && length >= -1);
i::Handle<i::String> 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();
Expand All @@ -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;
Expand Down
34 changes: 34 additions & 0 deletions test/cctest/test-api.cc
Expand Up @@ -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"));
}


Expand Down

0 comments on commit 3cc4ef2

Please sign in to comment.