SkPlainTextEditor: from experimental to modules

Change-Id: I8896283ee3a57af926a43f6647e27059d52dd7a8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/237146
Reviewed-by: Hal Canary <halcanary@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
diff --git a/modules/skplaintexteditor/src/stringslice.cpp b/modules/skplaintexteditor/src/stringslice.cpp
new file mode 100644
index 0000000..3f7da00
--- /dev/null
+++ b/modules/skplaintexteditor/src/stringslice.cpp
@@ -0,0 +1,82 @@
+// Copyright 2019 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+
+#include "modules/skplaintexteditor/include/stringslice.h"
+
+#include <algorithm>
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+
+using namespace SkPlainTextEditor;
+
+void StringSlice::FreeWrapper::operator()(void* t) { std::free(t); }
+
+StringSlice::StringSlice(StringSlice&& that)
+    : fPtr(std::move(that.fPtr))
+    , fLength(that.fLength)
+    , fCapacity(that.fCapacity)
+{
+    that.fLength = 0;
+    that.fCapacity = 0;
+}
+
+StringSlice& StringSlice::operator=(StringSlice&& that) {
+    if (this != &that) {
+        this->~StringSlice();
+        new (this)StringSlice(std::move(that));
+    }
+    return *this;
+}
+
+StringSlice& StringSlice::operator=(const StringSlice& that) {
+    if (this != &that) {
+        fLength = 0;
+        if (that.size() > 0) {
+            this->insert(0, that.begin(), that.size());
+        }
+    }
+    return *this;
+}
+
+void StringSlice::insert(std::size_t offset, const char* text, std::size_t length) {
+    if (length) {
+        offset = std::min(fLength, offset);
+        this->reserve(fLength + length);
+        char* s = fPtr.get();
+        assert(s);
+        if (offset != fLength) {
+            std::memmove(s + offset + length, s + offset, fLength - offset);
+        }
+        if (text) {
+            std::memcpy(s + offset, text, length);
+        } else {
+            std::memset(s + offset, 0, length);
+        }
+        fLength += length;
+    }
+}
+
+void StringSlice::remove(std::size_t offset, std::size_t length) {
+    if (length && offset < fLength) {
+        length = std::min(length, fLength - offset);
+        assert(length > 0);
+        assert(length + offset <= fLength);
+        if (length + offset < fLength) {
+            char* s = fPtr.get();
+            assert(s);
+            std::memmove(s + offset, s + offset + length, fLength - (length + offset));
+        }
+        fLength -= length;
+    }
+}
+
+void StringSlice::realloc(std::size_t size) {
+    // round up to multiple of (1 << kBits) bytes
+    static constexpr unsigned kBits = 4;
+    fCapacity = size ? (((size - 1) >> kBits) + 1) << kBits : 0;
+    assert(fCapacity % (1u << kBits) == 0);
+    assert(fCapacity >= size);
+    fPtr.reset((char*)std::realloc(fPtr.release(), fCapacity));
+    assert(fCapacity >= fLength);
+}