SecString
From C
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 %
