/*
-** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
int
psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
{ char new_str [128] ;
- size_t len_remaining, str_len ;
+ size_t str_len ;
int k, str_flags ;
if (str == NULL)
/* A few extra checks for write mode. */
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
- { if ((psf->str_flags & SF_STR_ALLOW_START) == 0)
+ { if ((psf->strings.flags & SF_STR_ALLOW_START) == 0)
return SFE_STR_NO_SUPPORT ;
- if (psf->have_written && (psf->str_flags & SF_STR_ALLOW_END) == 0)
+ if (psf->have_written && (psf->strings.flags & SF_STR_ALLOW_END) == 0)
return SFE_STR_NO_SUPPORT ;
/* Only allow zero length strings for software. */
if (str_type != SF_STR_SOFTWARE && str_len == 0)
/* Find the next free slot in table. */
for (k = 0 ; k < SF_MAX_STRINGS ; k++)
{ /* If we find a matching entry clear it. */
- if (psf->strings [k].type == str_type)
- psf->strings [k].type = -1 ;
+ if (psf->strings.data [k].type == str_type)
+ psf->strings.data [k].type = -1 ;
- if (psf->strings [k].type == 0)
+ if (psf->strings.data [k].type == 0)
break ;
} ;
/* Determine flags */
str_flags = SF_STR_LOCATE_START ;
if (psf->file.mode == SFM_RDWR || psf->have_written)
- { if ((psf->str_flags & SF_STR_ALLOW_END) == 0)
+ { if ((psf->strings.flags & SF_STR_ALLOW_END) == 0)
return SFE_STR_NO_ADD_END ;
str_flags = SF_STR_LOCATE_END ;
} ;
if (k >= SF_MAX_STRINGS)
return SFE_STR_MAX_COUNT ;
- if (k == 0 && psf->str_end != NULL)
- { psf_log_printf (psf, "SFE_STR_WEIRD : k == 0 && psf->str_end != NULL\n") ;
+ if (k == 0 && psf->strings.storage_used != 0)
+ { psf_log_printf (psf, "SFE_STR_WEIRD : k == 0 && psf->strings.storage_used != 0\n") ;
return SFE_STR_WEIRD ;
} ;
- if (k != 0 && psf->str_end == NULL)
- { psf_log_printf (psf, "SFE_STR_WEIRD : k != 0 && psf->str_end == NULL\n") ;
+ if (k != 0 && psf->strings.storage_used == 0)
+ { psf_log_printf (psf, "SFE_STR_WEIRD : k != 0 && psf->strings.storage_used == 0\n") ;
return SFE_STR_WEIRD ;
} ;
/* Special case for the first string. */
if (k == 0)
- psf->str_end = psf->str_storage ;
+ psf->strings.storage_used = 0 ;
switch (str_type)
{ case SF_STR_SOFTWARE :
return SFE_STR_BAD_TYPE ;
} ;
- str_len = strlen (str) ;
+ /* Plus one to catch string terminator. */
+ str_len = strlen (str) + 1 ;
- len_remaining = SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage) ;
+ if (psf->strings.storage_used + str_len + 1 > psf->strings.storage_len)
+ { char * temp = psf->strings.storage ;
+ size_t newlen = 2 * psf->strings.storage_len + str_len + 1 ;
- if (len_remaining < str_len + 2)
- return SFE_STR_MAX_DATA ;
+ newlen = newlen < 256 ? 256 : newlen ;
- psf->strings [k].type = str_type ;
- psf->strings [k].str = psf->str_end ;
- psf->strings [k].flags = str_flags ;
+ if ((psf->strings.storage = realloc (temp, newlen)) == NULL)
+ { psf->strings.storage = temp ;
+ return SFE_MALLOC_FAILED ;
+ } ;
- memcpy (psf->str_end, str, str_len + 1) ;
- /* Plus one to catch string terminator. */
- psf->str_end += str_len + 1 ;
+ psf->strings.storage_len = newlen ;
+ } ;
+
+ psf->strings.data [k].type = str_type ;
+ psf->strings.data [k].offset = psf->strings.storage_used ;
+ psf->strings.data [k].flags = str_flags ;
+
+ memcpy (psf->strings.storage + psf->strings.storage_used, str, str_len) ;
+ psf->strings.storage_used += str_len ;
- psf->str_flags |= str_flags ;
+ psf->strings.flags |= str_flags ;
#if STRINGS_DEBUG
- psf_log_printf (psf, "str_storage : %X\n", (int) psf->str_storage) ;
- psf_log_printf (psf, "str_end : %X\n", (int) psf->str_end) ;
- psf_log_printf (psf, "sizeof (str_storage) : %d\n", SIGNED_SIZEOF (psf->str_storage)) ;
- psf_log_printf (psf, "used : %d\n", (int ) (psf->str_end - psf->str_storage)) ;
- psf_log_printf (psf, "remaining : %d\n", SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage)) ;
+ psf_log_printf (psf, "str_storage : %p\n", psf->strings.storage) ;
+ psf_log_printf (psf, "storage_used : %u\n", psf->strings.storage_used) ;
+ psf_log_printf (psf, "used : %d\n", psf->strings.storage_used) ;
+ psf_log_printf (psf, "remaining : %d\n", psf->strings.storage_len - psf->strings.storage_used ;
- hexdump (psf->str_storage, 300) ;
+ hexdump (psf->strings.storage, 300) ;
#endif
return 0 ;
{ int k ;
for (k = 0 ; k < SF_MAX_STRINGS ; k++)
- if (str_type == psf->strings [k].type)
- return psf->strings [k].str ;
+ if (str_type == psf->strings.data [k].type)
+ return psf->strings.storage + psf->strings.data [k].offset ;
return NULL ;
} /* psf_get_string */
{ int k, count = 0 ;
for (k = 0 ; k < SF_MAX_STRINGS ; k++)
- if (psf->strings [k].type > 0 && psf->strings [k].flags & location)
+ if (psf->strings.data [k].type > 0 && psf->strings.data [k].flags & location)
count ++ ;
return count ;