1 // Copyright 2019 Google LLC.
2 // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3 
4 #include "modules/skplaintexteditor/include/stringslice.h"
5 
6 #include <algorithm>
7 #include <cassert>
8 #include <cstdlib>
9 #include <cstring>
10 
11 using namespace SkPlainTextEditor;
12 
operator ()(void * t)13 void StringSlice::FreeWrapper::operator()(void* t) { std::free(t); }
14 
StringSlice(StringSlice && that)15 StringSlice::StringSlice(StringSlice&& that)
16     : fPtr(std::move(that.fPtr))
17     , fLength(that.fLength)
18     , fCapacity(that.fCapacity)
19 {
20     that.fLength = 0;
21     that.fCapacity = 0;
22 }
23 
operator =(StringSlice && that)24 StringSlice& StringSlice::operator=(StringSlice&& that) {
25     if (this != &that) {
26         this->~StringSlice();
27         new (this)StringSlice(std::move(that));
28     }
29     return *this;
30 }
31 
operator =(const StringSlice & that)32 StringSlice& StringSlice::operator=(const StringSlice& that) {
33     if (this != &that) {
34         fLength = 0;
35         if (that.size() > 0) {
36             this->insert(0, that.begin(), that.size());
37         }
38     }
39     return *this;
40 }
41 
insert(std::size_t offset,const char * text,std::size_t length)42 void StringSlice::insert(std::size_t offset, const char* text, std::size_t length) {
43     if (length) {
44         offset = std::min(fLength, offset);
45         this->reserve(fLength + length);
46         char* s = fPtr.get();
47         assert(s);
48         if (offset != fLength) {
49             std::memmove(s + offset + length, s + offset, fLength - offset);
50         }
51         if (text) {
52             std::memcpy(s + offset, text, length);
53         } else {
54             std::memset(s + offset, 0, length);
55         }
56         fLength += length;
57     }
58 }
59 
remove(std::size_t offset,std::size_t length)60 void StringSlice::remove(std::size_t offset, std::size_t length) {
61     if (length && offset < fLength) {
62         length = std::min(length, fLength - offset);
63         assert(length > 0);
64         assert(length + offset <= fLength);
65         if (length + offset < fLength) {
66             char* s = fPtr.get();
67             assert(s);
68             std::memmove(s + offset, s + offset + length, fLength - (length + offset));
69         }
70         fLength -= length;
71     }
72 }
73 
realloc(std::size_t size)74 void StringSlice::realloc(std::size_t size) {
75     // round up to multiple of (1 << kBits) bytes
76     static constexpr unsigned kBits = 4;
77     fCapacity = size ? (((size - 1) >> kBits) + 1) << kBits : 0;
78     assert(fCapacity % (1u << kBits) == 0);
79     assert(fCapacity >= size);
80     fPtr.reset((char*)std::realloc(fPtr.release(), fCapacity));
81     assert(fCapacity >= fLength);
82 }
83