@ -35,12 +35,10 @@
// returned value is always at least 1 greater than argument
# define ROUND_ALLOC(a) (((a) & ((~0) - 7)) + 8)
// Init the vstr so it allocs exactly given number of bytes.
// Length is set to zero, and null byte written in first position.
// Init the vstr so it allocs exactly given number of bytes. Set length to zero.
void vstr_init ( vstr_t * vstr , size_t alloc ) {
if ( alloc < 2 ) {
// need at least 1 byte for the null byte at the end
alloc = 2 ;
if ( alloc < 1 ) {
alloc = 1 ;
}
vstr - > alloc = alloc ;
vstr - > len = 0 ;
@ -49,24 +47,20 @@ void vstr_init(vstr_t *vstr, size_t alloc) {
vstr - > had_error = true ;
return ;
}
vstr - > buf [ 0 ] = 0 ;
vstr - > had_error = false ;
vstr - > fixed_buf = false ;
}
// Init the vstr so it allocs exactly enough ram to hold given length (plus the
// null terminating byte), set the length, and write the null byte at the end.
// Init the vstr so it allocs exactly enough ram to hold given length, and set the length.
void vstr_init_len ( vstr_t * vstr , size_t len ) {
vstr_init ( vstr , len + 1 ) ;
vstr_add_len ( vstr , len ) ;
vstr_init ( vstr , len ) ;
vstr - > len = len ;
}
void vstr_init_fixed_buf ( vstr_t * vstr , size_t alloc , char * buf ) {
assert ( alloc > 0 ) ; // need at least room for the null byte
vstr - > alloc = alloc ;
vstr - > len = 0 ;
vstr - > buf = buf ;
vstr - > buf [ 0 ] = 0 ;
vstr - > had_error = false ;
vstr - > fixed_buf = true ;
}
@ -79,16 +73,16 @@ void vstr_clear(vstr_t *vstr) {
}
vstr_t * vstr_new ( void ) {
vstr_t * vstr = m_new ( vstr_t , 1 ) ;
vstr_t * vstr = m_new_obj ( vstr_t ) ;
if ( vstr = = NULL ) {
return NULL ;
}
vstr_init ( vstr , 32 ) ;
vstr_init ( vstr , 16 ) ;
return vstr ;
}
vstr_t * vstr_new_size ( size_t alloc ) {
vstr_t * vstr = m_new ( vstr_t , 1 ) ;
vstr_t * vstr = m_new_obj ( vstr_t ) ;
if ( vstr = = NULL ) {
return NULL ;
}
@ -107,7 +101,6 @@ void vstr_free(vstr_t *vstr) {
void vstr_reset ( vstr_t * vstr ) {
vstr - > len = 0 ;
vstr - > buf [ 0 ] = 0 ;
vstr - > had_error = false ;
}
@ -129,7 +122,7 @@ size_t vstr_len(vstr_t *vstr) {
return vstr - > len ;
}
// Extend vstr strictly by requested size, return pointer to newly added chunk
// Extend vstr strictly by requested size, return pointer to newly added chunk.
char * vstr_extend ( vstr_t * vstr , size_t size ) {
if ( vstr - > fixed_buf ) {
return NULL ;
@ -146,11 +139,11 @@ char *vstr_extend(vstr_t *vstr, size_t size) {
}
STATIC bool vstr_ensure_extra ( vstr_t * vstr , size_t size ) {
if ( vstr - > len + size + 1 > vstr - > alloc ) {
if ( vstr - > len + size > vstr - > alloc ) {
if ( vstr - > fixed_buf ) {
return false ;
}
size_t new_alloc = ROUND_ALLOC ( ( vstr - > len + size + 1 ) * 2 ) ;
size_t new_alloc = ROUND_ALLOC ( ( vstr - > len + size ) * 2 ) ;
char * new_buf = m_renew ( char , vstr - > buf , vstr - > alloc , new_alloc ) ;
if ( new_buf = = NULL ) {
vstr - > had_error = true ;
@ -175,10 +168,17 @@ char *vstr_add_len(vstr_t *vstr, size_t len) {
}
char * buf = vstr - > buf + vstr - > len ;
vstr - > len + = len ;
vstr - > buf [ vstr - > len ] = 0 ;
return buf ;
}
// Doesn't increase len, just makes sure there is a null byte at the end
void vstr_null_terminate ( vstr_t * vstr ) {
if ( vstr - > had_error | | ! vstr_ensure_extra ( vstr , 1 ) ) {
return ;
}
vstr - > buf [ vstr - > len ] = ' \0 ' ;
}
void vstr_add_byte ( vstr_t * vstr , byte b ) {
byte * buf = ( byte * ) vstr_add_len ( vstr , 1 ) ;
if ( buf = = NULL ) {
@ -224,11 +224,7 @@ void vstr_add_char(vstr_t *vstr, unichar c) {
buf [ 3 ] = ( c & 0x3F ) | 0x80 ;
}
# else
byte * buf = ( byte * ) vstr_add_len ( vstr , 1 ) ;
if ( buf = = NULL ) {
return ;
}
buf [ 0 ] = c ;
vstr_add_byte ( vstr , c ) ;
# endif
}
@ -239,7 +235,7 @@ void vstr_add_str(vstr_t *vstr, const char *str) {
void vstr_add_strn ( vstr_t * vstr , const char * str , size_t len ) {
if ( vstr - > had_error | | ! vstr_ensure_extra ( vstr , len ) ) {
// if buf is fixed, we got here because there isn't enough room left
// so just try to copy as much as we can, with room for null byte
// so just try to copy as much as we can, with room for a possible null byte
if ( vstr - > fixed_buf & & vstr - > len + 1 < vstr - > alloc ) {
len = vstr - > alloc - vstr - > len - 1 ;
goto copy ;
@ -249,7 +245,6 @@ void vstr_add_strn(vstr_t *vstr, const char *str, size_t len) {
copy :
memmove ( vstr - > buf + vstr - > len , str , len ) ;
vstr - > len + = len ;
vstr - > buf [ vstr - > len ] = 0 ;
}
STATIC char * vstr_ins_blank_bytes ( vstr_t * vstr , size_t byte_pos , size_t byte_len ) {
@ -265,8 +260,8 @@ STATIC char *vstr_ins_blank_bytes(vstr_t *vstr, size_t byte_pos, size_t byte_len
if ( ! vstr_ensure_extra ( vstr , byte_len ) ) {
return NULL ;
}
// copy up the string to make room for the new bytes; +1 for the null byte
memmove ( vstr - > buf + byte_pos + byte_len , vstr - > buf + byte_pos , l - byte_pos + 1 ) ;
// copy up the string to make room for the new bytes
memmove ( vstr - > buf + byte_pos + byte_len , vstr - > buf + byte_pos , l - byte_pos ) ;
// increase the length
vstr - > len + = byte_len ;
}
@ -301,7 +296,6 @@ void vstr_cut_tail_bytes(vstr_t *vstr, size_t len) {
} else {
vstr - > len - = len ;
}
vstr - > buf [ vstr - > len ] = 0 ;
}
void vstr_cut_out_bytes ( vstr_t * vstr , size_t byte_pos , size_t bytes_to_cut ) {
@ -309,10 +303,8 @@ void vstr_cut_out_bytes(vstr_t *vstr, size_t byte_pos, size_t bytes_to_cut) {
return ;
} else if ( byte_pos + bytes_to_cut > = vstr - > len ) {
vstr - > len = byte_pos ;
vstr - > buf [ vstr - > len ] = 0 ;
} else {
// move includes +1 for null byte at the end
memmove ( vstr - > buf + byte_pos , vstr - > buf + byte_pos + bytes_to_cut , vstr - > len - byte_pos - bytes_to_cut + 1 ) ;
memmove ( vstr - > buf + byte_pos , vstr - > buf + byte_pos + bytes_to_cut , vstr - > len - byte_pos - bytes_to_cut ) ;
vstr - > len - = bytes_to_cut ;
}
}