mirror of https://gitlab.com/rnger/amath
256 lines
5.5 KiB
C++
256 lines
5.5 KiB
C++
/*
|
|
* Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#include "clib.h"
|
|
#include "lib/charbuf.h"
|
|
|
|
// -----------------------------------------------------
|
|
// -------------------- CharBuffer ---------------------
|
|
// -----------------------------------------------------
|
|
|
|
/**
|
|
* @brief Initialize without allocating memory.
|
|
*
|
|
*/
|
|
CharBuffer::CharBuffer()
|
|
{
|
|
buf = NOMEM;
|
|
ptr = buf;
|
|
cursize = 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Initialize while allocating specified amount of memory.
|
|
*
|
|
*/
|
|
CharBuffer::CharBuffer(unsigned int size)
|
|
{
|
|
cursize = (size < minimumSize ? minimumSize : size);
|
|
buf = new char[cursize];
|
|
ptr = buf;
|
|
}
|
|
|
|
CharBuffer::~CharBuffer()
|
|
{
|
|
ClearBuffer();
|
|
}
|
|
|
|
/**
|
|
* @brief Release memory in buffer.
|
|
*
|
|
*/
|
|
void CharBuffer::ClearBuffer()
|
|
{
|
|
if (buf != NOMEM) {
|
|
delete [] buf;
|
|
}
|
|
|
|
buf = NOMEM;
|
|
ptr = buf;
|
|
cursize = 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Release memory, allocate and copy source.
|
|
*
|
|
*/
|
|
void CharBuffer::ClearAndCopy(const char* source)
|
|
{
|
|
ClearBuffer();
|
|
cursize = AllocAndCopy(&buf, source);
|
|
ptr = buf + cursize - sizeof(char);
|
|
}
|
|
|
|
/**
|
|
* @brief Release memory and allocate new size.
|
|
*
|
|
*/
|
|
void CharBuffer::ClearAndAlloc(unsigned int size)
|
|
{
|
|
ClearBuffer();
|
|
cursize = (size < minimumSize ? minimumSize : size);
|
|
buf = new char[cursize];
|
|
ptr = buf;
|
|
}
|
|
|
|
void CharBuffer::EnsureMinimumSize()
|
|
{
|
|
if (buf == NOMEM) {
|
|
unsigned int size = minimumSize;
|
|
buf = new char[size];
|
|
ptr = buf;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Ensure a memory block of speficied size is allocated.
|
|
*
|
|
*/
|
|
void CharBuffer::EnsureSize(unsigned int size)
|
|
{
|
|
if (cursize < size) {
|
|
|
|
unsigned int tempsize = cursize;
|
|
cursize = (size < minimumSize ? minimumSize : size);
|
|
|
|
if (buf == NOMEM) { // Nothing allocated yet. Just allocate requested size.
|
|
buf = new char[cursize];
|
|
ptr = buf;
|
|
} else if (buf == ptr) { // Already allocated but buffer is empty.
|
|
delete [] buf;
|
|
buf = new char[cursize];
|
|
ptr = buf;
|
|
} else { // Buffer already in use.
|
|
// Make at least double size
|
|
cursize = cursize < tempsize * 2 ? tempsize * 2 : cursize;
|
|
unsigned int offset = ptr - buf;
|
|
char *temp = new char[cursize];
|
|
MemCopy(temp, buf, tempsize);
|
|
delete [] buf;
|
|
buf = temp;
|
|
ptr = buf + offset;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CharBuffer::EnsureSize(unsigned int blocksize, unsigned int blocks)
|
|
{
|
|
if (cursize < blocksize * blocks) {
|
|
if (buf == NOMEM) {
|
|
cursize = blocksize * blocks;
|
|
buf = new char[cursize];
|
|
ptr = buf;
|
|
} else {
|
|
unsigned int tptr = ptr - buf;
|
|
char *temp = new char[blocksize * blocks];
|
|
MemCopy(temp, buf, cursize);
|
|
delete [] buf;
|
|
cursize = blocksize * blocks;
|
|
buf = temp;
|
|
ptr = buf + tptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CharBuffer::EnsureGrowth(unsigned int size)
|
|
{
|
|
EnsureSize((ptr - buf) + size);
|
|
}
|
|
|
|
bool CharBuffer::Is(const char* string)
|
|
{
|
|
return StrIsEqual(GetString(), string);
|
|
}
|
|
|
|
void CharBuffer::Empty()
|
|
{
|
|
if (buf == NOMEM) {
|
|
EnsureMinimumSize();
|
|
}
|
|
|
|
ptr = buf;
|
|
}
|
|
|
|
void CharBuffer::DeleteLastChar()
|
|
{
|
|
ptr--;
|
|
|
|
}
|
|
|
|
void CharBuffer::Copy(CharBuffer* source)
|
|
{
|
|
EnsureSize(source->cursize);
|
|
const char *s = source->GetString();
|
|
|
|
ptr = buf;
|
|
while ((*ptr++ = *s++))
|
|
;
|
|
|
|
ptr--;
|
|
}
|
|
|
|
void CharBuffer::Append(const char c)
|
|
{
|
|
*ptr++ = c;
|
|
}
|
|
|
|
void CharBuffer::Append(const char c, unsigned int count)
|
|
{
|
|
if (count == 0) {
|
|
return;
|
|
}
|
|
|
|
unsigned int n = count;
|
|
while (n--)
|
|
*ptr++ = c;
|
|
}
|
|
|
|
void CharBuffer::Append(const char* source)
|
|
{
|
|
while ((*ptr++ = *source++));
|
|
|
|
ptr--;
|
|
}
|
|
|
|
bool CharBuffer::RemoveTrailing(const char c)
|
|
{
|
|
if (ptr == buf) {
|
|
return false;
|
|
}
|
|
|
|
if (*(--ptr) == c) {
|
|
return true;
|
|
}
|
|
|
|
ptr++;
|
|
return false;
|
|
}
|
|
|
|
bool CharBuffer::RemoveTrailing(const char *string)
|
|
{
|
|
int len = StrLen(string) * sizeof(char);
|
|
char* s = ptr - len;
|
|
if (s < buf) {
|
|
return false;
|
|
}
|
|
|
|
*ptr = '\0';
|
|
|
|
if (StrIsEqual(s, string)) {
|
|
ptr = s;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
char* CharBuffer::GetString()
|
|
{
|
|
*ptr = '\0';
|
|
return buf;
|
|
}
|
|
|