1// 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 "modules/skplaintexteditor/include/stringslice.h" 5 6#include <algorithm> 7#include <cassert> 8#include <cstdlib> 9#include <cstring> 10 11using namespace SkPlainTextEditor; 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 32StringSlice& 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 42void StringSlice::insert(std::size_t offset, const char* text, std::size_t length) { 43 if (length) { 44 offset = std::min(fLength, offset); 45 this->reserve(fLength + length); 46 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 74void 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); 82} 83