2019-05-03 21:14:21 +00:00
|
|
|
// Copyright 2019 Google LLC.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
|
|
|
|
|
2019-05-14 19:01:39 +00:00
|
|
|
#include "experimental/editor/stringslice.h"
|
2019-05-03 21:14:21 +00:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
using namespace editor;
|
|
|
|
|
|
|
|
void StringSlice::FreeWrapper::operator()(void* t) { std::free(t); }
|
|
|
|
|
|
|
|
StringSlice::StringSlice(StringSlice&& that)
|
|
|
|
: fPtr(std::move(that.fPtr))
|
|
|
|
, fLength(that.fLength)
|
|
|
|
, fCapacity(that.fCapacity)
|
|
|
|
{
|
|
|
|
that.fLength = 0;
|
|
|
|
that.fCapacity = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
StringSlice& StringSlice::operator=(StringSlice&& that) {
|
|
|
|
if (this != &that) {
|
|
|
|
this->~StringSlice();
|
|
|
|
new (this)StringSlice(std::move(that));
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2019-06-20 15:29:10 +00:00
|
|
|
StringSlice& StringSlice::operator=(const StringSlice& that) {
|
|
|
|
if (this != &that) {
|
|
|
|
fLength = 0;
|
|
|
|
if (that.size() > 0) {
|
|
|
|
this->insert(0, that.begin(), that.size());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2019-05-03 21:14:21 +00:00
|
|
|
void StringSlice::insert(std::size_t offset, const char* text, std::size_t length) {
|
|
|
|
if (length) {
|
|
|
|
offset = std::min(fLength, offset);
|
2019-06-20 15:29:10 +00:00
|
|
|
this->reserve(fLength + length);
|
2019-05-03 21:14:21 +00:00
|
|
|
char* s = fPtr.get();
|
|
|
|
assert(s);
|
|
|
|
if (offset != fLength) {
|
|
|
|
std::memmove(s + offset + length, s + offset, fLength - offset);
|
|
|
|
}
|
|
|
|
if (text) {
|
|
|
|
std::memcpy(s + offset, text, length);
|
|
|
|
} else {
|
|
|
|
std::memset(s + offset, 0, length);
|
|
|
|
}
|
|
|
|
fLength += length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StringSlice::remove(std::size_t offset, std::size_t length) {
|
|
|
|
if (length && offset < fLength) {
|
|
|
|
length = std::min(length, fLength - offset);
|
|
|
|
assert(length > 0);
|
|
|
|
assert(length + offset <= fLength);
|
|
|
|
if (length + offset < fLength) {
|
|
|
|
char* s = fPtr.get();
|
|
|
|
assert(s);
|
|
|
|
std::memmove(s + offset, s + offset + length, fLength - (length + offset));
|
|
|
|
}
|
|
|
|
fLength -= length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-20 15:29:10 +00:00
|
|
|
void StringSlice::realloc(std::size_t size) {
|
|
|
|
// round up to multiple of (1 << kBits) bytes
|
|
|
|
static constexpr unsigned kBits = 4;
|
|
|
|
fCapacity = size ? (((size - 1) >> kBits) + 1) << kBits : 0;
|
|
|
|
assert(fCapacity % (1u << kBits) == 0);
|
|
|
|
assert(fCapacity >= size);
|
|
|
|
fPtr.reset((char*)std::realloc(fPtr.release(), fCapacity));
|
|
|
|
assert(fCapacity >= fLength);
|
2019-05-03 21:14:21 +00:00
|
|
|
}
|