Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Unified Diff: src/api.cc

Issue 16530003: add function to test whether string contents are definitely one byte (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« include/v8.h ('K') | « include/v8.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index b2dc2e1e943abbd81efadccc18fb6ed5c5f1c299..07f34f78ccea044eeefd5a7ee1aaf1d2cfbdda85 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -4304,6 +4304,84 @@ bool String::IsOneByte() const {
}
+class DefinitelyContainsOnlyOneByteHelper {
+ public:
+ DefinitelyContainsOnlyOneByteHelper() : is_one_byte_(true) {}
+ bool Check(i::String* string) {
+ i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
+ if (cons_string == NULL) return is_one_byte_;
+ return CheckCons(cons_string);
+ }
+ void VisitOneByteString(const uint8_t* chars, int length) {
+ // Nothing to do.
+ }
+ void VisitTwoByteString(const uint16_t* chars, int length) {
+ for (int i = 0; i < length; i++) {
+ if (chars[i] >> 8) {
+ is_one_byte_ = false;
+ return;
+ }
+ }
+ }
+
+ private:
+ bool CheckCons(i::ConsString* cons_string) {
+ while (true) {
+ // Check left side if flat.
+ i::String* left = cons_string->first();
+ i::ConsString* left_as_cons =
+ i::String::VisitFlat(this, left, 0);
+ if (!is_one_byte_) return false;
+ // Check right side if flat.
+ i::String* right = cons_string->second();
+ i::ConsString* right_as_cons =
+ i::String::VisitFlat(this, right, 0);
+ if (!is_one_byte_) return false;
+ // Standard recurse/iterate trick.
+ // Falls through to the cases below for the iteration.
+ if (left_as_cons != NULL && right_as_cons != NULL) {
+ if (left->length() < right->length()) {
+ CheckCons(right_as_cons);
+ right_as_cons = NULL;
Yang 2013/06/06 09:12:59 I think it's a bit easier to read if you just set
dcarney 2013/06/06 09:17:26 okay
+ } else {
+ CheckCons(left_as_cons);
+ left_as_cons = NULL;
+ }
+ // Check fast return.
+ if (!is_one_byte_) return false;
+ }
+ // Descend left in place.
+ if (left_as_cons != NULL) {
+ cons_string = left_as_cons;
+ continue;
+ }
+ // Descend right in place.
+ if (right_as_cons != NULL) {
+ cons_string = right_as_cons;
+ continue;
+ }
+ // Terminate.
+ break;
+ }
+ return is_one_byte_;
+ }
+ bool is_one_byte_;
+ DISALLOW_COPY_AND_ASSIGN(DefinitelyContainsOnlyOneByteHelper);
+};
+
+
+bool String::DefinitelyContainsOnlyOneByte() const {
+ i::Handle<i::String> str = Utils::OpenHandle(this);
+ if (IsDeadCheck(str->GetIsolate(),
+ "v8::String::DefinitelyContainsOnlyOneByte()")) {
+ return false;
+ }
+ if (str->HasOnlyOneByteChars()) return true;
+ DefinitelyContainsOnlyOneByteHelper helper;
+ return helper.Check(*str);
Yang 2013/06/06 09:12:59 If we find that the string only contains one byte
dcarney 2013/06/06 09:17:26 will do
+}
+
+
class Utf8LengthHelper : public i::AllStatic {
public:
enum State {
« include/v8.h ('K') | « include/v8.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698