blob: 5581ab912ef47f3b36eaaeab9c6ca26c66de8562 [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
4#include "stringslice.h"
5
6#include <algorithm>
7#include <cassert>
8#include <cstdlib>
9#include <cstring>
10
11using namespace editor;
12
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
32void StringSlice::insert(std::size_t offset, const char* text, std::size_t length) {
33 if (length) {
34 offset = std::min(fLength, offset);
35 this->reserve(fLength + length); // TODO: reserve extra???
36 char* s = fPtr.get();
37 assert(s);
38 if (offset != fLength) {
39 std::memmove(s + offset + length, s + offset, fLength - offset);
40 }
41 if (text) {
42 std::memcpy(s + offset, text, length);
43 } else {
44 std::memset(s + offset, 0, length);
45 }
46 fLength += length;
47 }
48}
49
50void StringSlice::remove(std::size_t offset, std::size_t length) {
51 if (length && offset < fLength) {
52 length = std::min(length, fLength - offset);
53 assert(length > 0);
54 assert(length + offset <= fLength);
55 if (length + offset < fLength) {
56 char* s = fPtr.get();
57 assert(s);
58 std::memmove(s + offset, s + offset + length, fLength - (length + offset));
59 }
60 fLength -= length;
61 }
62}
63
64void StringSlice::reserve(std::size_t length) {
65 if (length && length > fCapacity) {
66 fPtr.reset((char*)std::realloc(fPtr.release(), length));
67 fCapacity = length;
68 }
69}
70
71void StringSlice::shrink() {
72 fPtr.reset((char*)std::realloc(fPtr.release(), fLength));
73 fCapacity = fLength;
74}