SecString

From C

Jump to: navigation, search

Contents

Introduction

I created secstring a while ago when working on some random application where I didn't need the complexity nor features of most available string libraries. So I wrote my own. It's contained in a bunch of macros, which is absolutely disgusting, but these could simply be moved into functions (and I've in fact done this before). The code is made available under a condensed new-style BSD license.

Don't yell at me about the formatting. I like tabs, but this is a Wiki, and it doesn't.

License

Copyright (c) 2003 - 2005 Devon H. O'Dell
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, 
      this list of conditions and the following disclaimer.
    * 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.

No warranties whatsoever. I'm not responsible. I'm not responsible for what you
do with this code either ;).

That said, here's the code:

secstring.h

#include <stdlib.h>

typedef struct secstring {
        char *__contents;
        unsigned long int __pointer;
        unsigned long int __size;
} secstring;

enum {
        _secstring_AllocSize = 1024,
};

secstring     *ss_init(void);
void           ss_deinit(secstring *);
void           ss_rewind(secstring *);
void          *ss_resize(secstring *);
void           ss_push(secstring *, int);
void           ss_pushstr(secstring *, const char *);
void           ss_finalize(secstring *);
char          *ss_contents(secstring *);

unsigned long  ss_size(secstring *);
unsigned long  ss_position(secstring *);
unsigned long  ss_strlen(secstring *);

unsigned long  ss_tokenize(secstring *, secstring *, secstring *, int);

unsigned long  ss_substr(secstring *, long, unsigned long, secstring *);

secstring.c

#include <stdlib.h>
#include <err.h>

#include "secstring.h"

secstring *
ss_init(void)
{
        secstring *ss = malloc(sizeof(secstring));
        if (ss == NULL)
                return NULL;
        ss->__contents = (char *) ss->__pointer = ss->__size = 0;

        return ss;
}

void
ss_deinit(secstring *ss)
{
        if (ss->__contents)
                free(ss->__contents);

        ss->__pointer = ss->__size = 0;

        free(ss);
}

void
ss_rewind(secstring *ss)
{
        ss->__pointer = 0;
}

void *
ss_resize(secstring *ss)
{
        char *tmps;

        /* Realloc is slow. Double allocation */
        if (ss->__size == 0) {
                ss->__contents = malloc(_secstring_AllocSize);
                if (ss->__contents != NULL)
                        ss->__size = _secstring_AllocSize;
                else
                        return (NULL);
        } else {
                tmps = realloc(ss->__contents, ss->__size * 2);
                if (tmps != NULL) {
                        ss->__contents = tmps;
                        ss->__size *= 2;
                } else
                        return (NULL);
        }

        return (ss->__contents);
}

void
ss_push(secstring *ss, int ch)
{
        if (ss->__pointer >= ss->__size)
                if (ss_resize(ss) == NULL) {
                        warn("Could not allocate memory!");
                        return;
                }
        ss->__contents[ss->__pointer++] = ch;
}

void
ss_pushstr(secstring *ss, const char *st)
{
        char *_secstring___tmp = (char *)st;

        while (*_secstring___tmp)
                ss_push(ss, *_secstring___tmp++);
}

void
ss_finalize(secstring *ss)
{
        ss_push(ss, '\0');
}

char *
ss_contents(secstring *ss)
{
        return ss->__contents;
}

unsigned long
ss_size(secstring *ss)
{
        return ss->__size;
}

unsigned long
ss_position(secstring *ss)
{
        return ss->__pointer;
}

unsigned long
ss_strlen(secstring *ss)
{
        return strlen(ss->__contents);
}

unsigned long
ss_tokenize(secstring *ss, secstring *tokens, secstring *retstring, int start) {
        unsigned long spointer = start, tpointer = 0;

        retstring = ss_init();
        if (retstring == NULL)
                return -1;

        ss_rewind(ss);
        ss_rewind(tokens);

        do {
                do {
                        if (ss_contents(ss)[spointer] == ss_contents(tokens)[tpointer]) {
                                ss_finalize(retstring);
                                return ss_position(ss) + 1;
                        }
                } while (ss_contents(tokens)[++tpointer] != '\0');

                ss_push(retstring, ss_contents(ss)[spointer]);
                ss_rewind(tokens);
        } while (ss_contents(ss)[++spointer] != '\0');
        return spointer;
}

unsigned long
ss_substr(secstring *ss, long start, unsigned long length, secstring *retstring) {
        unsigned int i, len = ss_strlen(ss);


        retstring = ss_init();
        if (retstring == NULL)
                return -1;

        if (start > len || start + length > len)
                return -1;

        if (start < 0)
                start = len + start;

        for (i = length; i < len + start + length; i++)
                ss_push(retstring, ss_contents(ss)[i]);

        ss_finalize(retstring);

        return i;
}

test_secstring.c

/* This will be more useful when I'm finished with the above file */
#include <stdio.h>

#include "secstring.h"

int 
main(void) {
   int retval = 0;
   secstring *str = ss_init();

   if (str == NULL) {
      printf("No memory.");
      retval = -1;
   } else {
      ss_pushstr(str, "test123test123");
      ss_finalize(str);

      printf("string: %s", ss_contents(str));

      ss_deinit(str);
   }

   return retval;
}

Building

Simple:

% cc secstring.c test_secstring.c -o test_secstring
%

Category Snippets

Personal tools