blob: 3f7da00b38e7638f291cfb1165ee1b1be30cf037 [file] [log] [blame]
Hal Canary05694472019-05-03 17:14:21 -04001// 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
Hal Canarya0b66fc2019-08-23 10:16:51 -04004#include "modules/skplaintexteditor/include/stringslice.h"
Hal Canary05694472019-05-03 17:14:21 -04005
6#include <algorithm>
7#include <cassert>
8#include <cstdlib>
9#include <cstring>
10
Hal Canarya0b66fc2019-08-23 10:16:51 -040011using namespace SkPlainTextEditor;
Hal Canary05694472019-05-03 17:14:21 -040012
13void StringSlice::FreeWrapper::operator()(void* t) { std::free(t); }
14
15StringSlice::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
24StringSlice& StringSlice::operator=(StringSlice&& that) {
25 if (this != &that) {
26 this->~StringSlice();
27 new (this)StringSlice(std::move(that));
28 }
29 return *this;
30}
31
Hal Canary66bf2cf2019-06-20 11:29:10 -040032StringSlice& 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
Hal Canary05694472019-05-03 17:14:21 -040042void StringSlice::insert(std::size_t offset, const char* text, std::size_t length) {
43 if (length) {
44 offset = std::min(fLength, offset);
Hal Canary66bf2cf2019-06-20 11:29:10 -040045 this->reserve(fLength + length);
Hal Canary05694472019-05-03 17:14:21 -040046 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
60void 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
Hal Canary66bf2cf2019-06-20 11:29:10 -040074void 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);
Hal Canary05694472019-05-03 17:14:21 -040082}