HOME
#ifndef _STRING_H
#define _STRING_H
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
typedef char* string;
#define STRING_INIT {0}
void string_reset(string* p);
void string_destructor(string* p);
size_t string_allocate(string* p, size_t size);
void string_erase_n(string* p, size_t index, size_t count);
size_t string_insert_n(string* p, size_t index, const char* pSource, size_t count);
void string_set(string* p, size_t index, char val);
size_t string_size(string* p);
void string_append(string* p, char v);
void string_append_n(string* p, const char* psz, size_t nelements);
char string_get(string* p, size_t index);
char string_back(string* p);
char string_front(string* p);
bool string_empty(string* p);
void string_clear(string* p);
void string_copy(string* p, const char* psz);
void string_copy_n(string* p, const char* psz, size_t nelements);
void string_erase(string* p, size_t index);
size_t string_push_back(string* p, char val);
void string_swap(string* a, string* b);
void string_move_to(string* from, string* to);
const char* string_data(string* p);
#ifdef _DEBUG
size_t get_string_instances();
#endif
#endif //_STRING_H
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <memory.h>
#include "string.h"
#define INVALID_ADDRESS ((char*)1)
#define _IS_VALID_(p) assert((p) && ((*p) != INVALID_ADDRESS))
#ifdef _DEBUG
static size_t s_string_instance_counter = 0;
size_t get_string_instances()
{
return s_string_instance_counter;
}
#endif
size_t string_allocate(string* p, size_t nelements)
{
_IS_VALID_(p);
size_t nelem = nelements + 1;
if (*p == 0)
{
*p = (char*) malloc(nelem * sizeof(char));
#ifdef _DEBUG
if (p)
{
s_string_instance_counter++;
}
#endif
}
else
{
*p = (char*) realloc(*p, nelem * sizeof(char));
}
return (*p != 0) ? nelements : 0;
}
const char* string_data(string* p)
{
_IS_VALID_(p);
if (p == 0)
return 0;
return *p;
}
void string_reset(string* p)
{
_IS_VALID_(p);
#ifdef _DEBUG
if (*p)
{
assert(s_string_instance_counter > 0);
s_string_instance_counter--;
}
#endif
string_clear(p);
*p = 0;
}
void string_destructor(string* p)
{
_IS_VALID_(p);
#ifdef _DEBUG
if (*p)
{
assert(s_string_instance_counter > 0);
s_string_instance_counter--;
}
#endif
string_clear(p);
*p = (char*)INVALID_ADDRESS;
}
size_t string_insert_n(string* p,
size_t index,
const char* pSource,
size_t nelements)
{
_IS_VALID_(p);
size_t oldsize = string_size(p);
size_t size = oldsize + nelements;
size_t result = string_allocate(p, size);
if (result == 0)
{
return 0;
}
if (index < oldsize)
{
memmove(&((*p)[index + nelements]),
&((*p)[index]),
(sizeof(char)) * (oldsize - index));
}
memmove(&((*p)[index]), pSource, nelements);
/*ensure zero ended*/
(*p)[size] = 0;
return nelements;
}
void string_erase_n(string* p,
size_t position,
size_t nelements)
{
_IS_VALID_(p);
size_t size = string_size(p);
assert(size >= nelements);
assert(size > position);
assert(nelements <= size - position);
memmove(*p + position,
*p + position + nelements,
sizeof(char) * (size - nelements + 1));
}
void string_set(string* p, size_t position, char value)
{
_IS_VALID_(p);
(*p)[position] = value;
}
size_t string_size(string* p)
{
_IS_VALID_(p);
if (*p == 0)
return 0;
return strlen(*p);
}
void string_append(string* p, char v)
{
_IS_VALID_(p);
string_insert_n(p, string_size(p), &v, 1);
}
void string_append_n(string* p, const char* psz, size_t nelements)
{
_IS_VALID_(p);
string_insert_n(p, string_size(p), psz, nelements);
}
char string_get(string* p, size_t index)
{
_IS_VALID_(p);
return (*p)[index];
}
char string_back(string* p)
{
_IS_VALID_(p);
return (*p)[string_size(p) - 1];
}
char string_front(string* p)
{
_IS_VALID_(p);
return (*p)[0];
}
bool string_empty(string* p)
{
_IS_VALID_(p);
return *p == 0;
}
void string_clear(string* p)
{
_IS_VALID_(p);
if (*p)
{
free(*p);
*p = 0;
}
}
void string_copy(string* p, const char* psz)
{
_IS_VALID_(p);
size_t sz = psz ? strlen(psz) : 0;
string_copy_n(p, psz, sz);
}
void string_copy_n(string* p, const char* psz, size_t nelements)
{
_IS_VALID_(p);
string_clear(p);
string_insert_n(p, 0, psz, nelements);
}
void string_erase(string* p, size_t index)
{
_IS_VALID_(p);
string_erase_n(p, index, 1);
}
size_t string_push_back(string* p, char val)
{
_IS_VALID_(p);
return string_insert_n(p, strlen(*p), &val, 1);
}
void string_swap(string* a, string* b)
{
_IS_VALID_(a);
_IS_VALID_(b);
string temp = *a;
*a = *b;
*b = temp;
}
void string_move_to(string* from, string* to)
{
_IS_VALID_(from);
_IS_VALID_(to);
string_swap(to, from);
string_destructor(from);
}