aboutsummaryrefslogtreecommitdiff
#include "str.h"

#include <string.h>
#include <stdlib.h>

/* Note, we add always 1 to length for the \0 character */

static void string_check_for_expand( String *string_, unsigned int length )
{
    if(string_->length + length >= string_->allocated_length)
    {
        string_->allocated_length = string_->length + length + 1;
        string_->data = realloc(string_->data, string_->allocated_length * sizeof(char) );
    }
}

String *string_create( const char *init )
{
    String *str;

    if(init == NULL || *init == '\0')
    {
        str = string_create_by_size(1);
    }
    else
    {
        unsigned int len = strlen(init);
        str = string_create_by_size(len + 1);
        string_append(str, init);
    }

    return str;
}

String *string_create_by_size( unsigned int reserved_size)
{
    String *str = malloc( sizeof(String) );

    str->data = NULL;
    str->length = 0;
    str->allocated_length = 0;

    string_check_for_expand(str, reserved_size);

    str->data[0] = 0;
    return str;
}

void string_assign( String *string_, const char *val )
{

}

void string_append( String *string_, const char *val )
{
    string_insert(string_, string_->length, val);
}

void string_append_char( String *string_, char c )
{
    string_insert(string_, string_->length, &c);
}

void string_insert( String *string_, int index, const char *val)
{
    if(index > string_->length)
        return;

    unsigned int length = strlen(val);
    string_check_for_expand(string_, length);

    if(index == string_->length - 1)
    {
        strcpy(string_->data + string_->length, val);
    }
    else
    {
        memmove(string_->data + index + length,
                string_->data + index,
                (string_->length - index) * sizeof(char) );

        memcpy(string_->data + index, val, length * sizeof(char) );
    }

    string_->length += length;
    string_->data[string_->length] = '\0';
}

void string_insert_char( String *string_, int index, char val)
{
    string_insert(string_, index, &val);
}

void string_free( String *string_ )
{
    if(string_)
    {
        free(string_->data);
        free(string_);
    }
}

unsigned int string_hash( String *string_ )
{
    unsigned int hash, i;
    for(hash = i = 0; i < string_->length; ++i)
    {
        hash += string_->data[i];
        hash += (hash << 10);
        hash ^= (hash >> 6);
    }
    hash += (hash << 3);
    hash ^= (hash >> 11);
    hash += (hash << 15);
    return hash;
}

bool string_equal( String *a, String *b )
{
    return !strcmp(a->data, b->data);
}