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