Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: compiled/String.h

Issue 29333474: Issue 4125 - [emscripten] Convert filter classes to C++ (Closed)
Patch Set: Fixed annotation for hash buffers Created Jan. 28, 2016, 5:07 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « compiled/RegExpFilter.cpp ('k') | compiled/StringMap.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: compiled/String.h
===================================================================
new file mode 100644
--- /dev/null
+++ b/compiled/String.h
@@ -0,0 +1,260 @@
+#ifndef ADBLOCK_PLUS_STRING_H
+#define ADBLOCK_PLUS_STRING_H
+
+#include <cstddef>
+#include <cstring>
+#include <algorithm>
+
+#include "debug.h"
+
+class String
+{
+public:
+ typedef char16_t value_type;
+ typedef size_t size_type;
+
+ // Type flags, stored in the top 2 bits of the mLen member
+ static constexpr size_type OWNBUFFER = 0xC0000000;
+ static constexpr size_type INVALID = 0x80000000;
+ static constexpr size_type DELETED = 0x40000000;
+ static constexpr size_type DEPENDENT = 0x00000000;
+ static constexpr size_type FLAGS_MASK = 0xC0000000;
+ static constexpr size_type LENGTH_MASK = 0x3FFFFFFF;
+
+ static constexpr size_type npos = -1;
+
+private:
+ value_type* mBuf;
+ size_type mLen;
+
+ value_type* allocate(size_type len)
+ {
+ if (len)
+ return new value_type[len];
+ else
+ return nullptr;
+ }
+
+ void resize(size_type newLength, bool copy)
+ {
+ bool owningOldBuffer = owns_buffer();
+ size_type oldLength = length();
+ value_type* oldBuffer = mBuf;
+
+ newLength &= LENGTH_MASK;
+ mBuf = allocate(newLength);
+ annotate_address(mBuf, "String");
+ mLen = OWNBUFFER | newLength;
+
+ if (copy && oldLength)
+ memcpy(mBuf, oldBuffer, sizeof(value_type) * std::min(oldLength, newLength));
+ if (owningOldBuffer)
+ delete[] oldBuffer;
+ }
+
+public:
+ String() : mBuf(nullptr), mLen(INVALID) {}
+
+ String(size_type len)
+ : mBuf(allocate(len & LENGTH_MASK)), mLen(OWNBUFFER | (len & LENGTH_MASK))
+ {
+ annotate_address(mBuf, "String");
+ }
+
+ String(value_type* buf, size_type len)
+ : mBuf(buf), mLen(DEPENDENT | (buf ? len & LENGTH_MASK: 0))
+ {
+ }
+
+ String(const String& str, size_type pos = 0, size_type len = npos)
+ : mBuf(str.mBuf + std::min(pos, str.length())),
+ mLen(DEPENDENT | std::min(len, str.length() - (mBuf - str.mBuf)))
+ {
+ }
+
+ String(String&& str)
+ {
+ *this = std::move(str);
+ }
+
+ String(const char* source, size_type len)
+ : String(len)
+ {
+ for (size_type i = 0; i < len; i++)
+ mBuf[i] = source[i];
+ }
+
+ void operator=(const String& str)
+ {
+ mBuf = str.mBuf;
+ mLen = DEPENDENT | str.length();
+ }
+
+ void operator=(String& str)
+ {
+ reset(str);
+ }
+
+ String& operator=(String&& str)
+ {
+ mBuf = str.mBuf;
+ mLen = str.mLen;
+ str.mBuf = nullptr;
+ str.mLen = INVALID;
+ ensure_own_buffer();
+ return *this;
+ }
+
+ ~String()
+ {
+ if (owns_buffer())
+ delete[] mBuf;
+ }
+
+ void reset(value_type* buf, size_type len)
+ {
+ mBuf = buf;
+ mLen = (DEPENDENT | (buf ? len & LENGTH_MASK: 0));
+ }
+
+ void reset(const String& str, size_type pos = 0, size_type len = npos)
+ {
+ pos = std::min(pos, str.length());
+ len = std::min(len, str.length() - pos);
+ reset(str.mBuf + pos, len);
+ }
+
+ size_type length() const
+ {
+ return mLen & LENGTH_MASK;
+ }
+
+ bool empty() const
+ {
+ return !(mLen & LENGTH_MASK);
+ }
+
+ const value_type* data() const
+ {
+ return mBuf;
+ }
+
+ value_type* data()
+ {
+ return mBuf;
+ }
+
+ const value_type& operator[](size_type pos) const
+ {
+ return mBuf[pos];
+ }
+
+ value_type& operator[](size_type pos)
+ {
+ return mBuf[pos];
+ }
+
+ bool equals(const String& other) const
+ {
+ if (mLen != other.mLen)
+ return false;
+
+ return memcmp(mBuf, other.mBuf, sizeof(value_type) * length()) == 0;
+ }
+
+ size_type find(value_type c, size_type pos = 0) const
+ {
+ for (size_type i = pos; i < length(); ++i)
+ if (mBuf[i] == c)
+ return i;
+ return npos;
+ }
+
+ size_type find(const String& str, size_type pos = 0) const
+ {
+ if (!str.length())
+ return pos;
+
+ if (length() - pos < str.length())
+ return npos;
+
+ for (; pos < length() - str.length(); ++pos)
+ {
+ if (mBuf[pos] == str[0] &&
+ memcmp(mBuf + pos, str.mBuf, sizeof(value_type) * str.length()) == 0)
+ {
+ return pos;
+ }
+ }
+
+ return npos;
+ }
+
+ size_type rfind(value_type c, size_type pos = npos) const
+ {
+ if (length() == 0)
+ return npos;
+
+ if (pos == npos)
+ pos = length() - 1;
+
+ for (int i = pos; i >= 0; --i)
+ if (mBuf[i] == c)
+ return i;
+ return npos;
+ }
+
+ void append(const value_type* source, size_type sourceLen)
+ {
+ if (!sourceLen)
+ return;
+
+ size_t oldLength = length();
+ resize(oldLength + sourceLen, true);
+ memcpy(mBuf + oldLength, source, sizeof(value_type) * sourceLen);
+ }
+
+ void append(const String& str)
+ {
+ append(str.mBuf, str.length());
+ }
+
+ void append(value_type c)
+ {
+ append(&c, 1);
+ }
+
+ bool owns_buffer() const
+ {
+ return mBuf && (mLen & FLAGS_MASK) == OWNBUFFER;
+ }
+
+ void ensure_own_buffer()
+ {
+ size_type len = length();
+ if (len && !owns_buffer())
+ resize(len, true);
+ }
+
+ bool is_dependent() const
+ {
+ return (mLen & FLAGS_MASK) == DEPENDENT;
+ }
+
+ bool is_invalid() const
+ {
+ return (mLen & FLAGS_MASK) == INVALID;
+ }
+
+ bool is_deleted() const
+ {
+ return (mLen & FLAGS_MASK) == DELETED;
+ }
+};
+
+inline String operator "" _str(const String::value_type* str,
+ String::size_type len)
+{
+ return String(const_cast<String::value_type*>(str), len);
+}
+#endif
« no previous file with comments | « compiled/RegExpFilter.cpp ('k') | compiled/StringMap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld