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