2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-16 01:12:13 +00:00

Updated the Boost Jam OBJECT interface to allow creating OBJECT instances from a non-0 terminated string.

[SVN r79281]
This commit is contained in:
Jurko Gospodnetić
2012-07-05 12:57:25 +00:00
parent fa5ea2ec6d
commit 0cac694e35
2 changed files with 45 additions and 34 deletions

View File

@@ -9,11 +9,12 @@
* object.c - object manipulation routines
*
* External functions:
* object_new() - create an object from a string
* object_copy() - return a copy of an object
* object_free() - free an object
* object_str() - get the string value of an object
* object_done() - free string tables
* object_new() - create an object from a string
* object_new_range() - create an object from a string of given length
* object_copy() - return a copy of an object
* object_free() - free an object
* object_str() - get the string value of an object
* object_done() - free string tables
*
* This implementation builds a hash table of all strings, so that multiple
* calls of object_new() on the same string allocate memory for the string once.
@@ -128,28 +129,27 @@ static char * allocate( size_t n )
}
static unsigned int hash_keyval( char const * key )
static unsigned int hash_keyval( char const * key, int const size )
{
unsigned int const magic = 2147059363;
unsigned int hash = 0;
unsigned i;
unsigned int len = strlen( key );
for ( i = 0; i < len / sizeof( unsigned int ); ++i )
unsigned int i;
for ( i = 0; i < size / sizeof( unsigned int ); ++i )
{
unsigned int val;
memcpy( &val, key, sizeof( unsigned int ) );
hash = hash * 2147059363 + val;
hash = hash * magic + val;
key += sizeof( unsigned int );
}
{
unsigned int val = 0;
memcpy( &val, key, len % sizeof( unsigned int ) );
hash = hash * 2147059363 + val;
memcpy( &val, key, size % sizeof( unsigned int ) );
hash = hash * magic + val;
}
hash += (hash >> 17);
return hash;
return hash + ( hash >> 17 );
}
@@ -193,16 +193,16 @@ static void string_set_resize( string_set * set )
}
static char const * string_set_insert( string_set * set, char const * string )
static char const * string_set_insert( string_set * set, char const * string,
int const size )
{
unsigned hash = hash_keyval( string );
unsigned hash = hash_keyval( string, size );
unsigned pos = hash % set->num;
unsigned len;
struct hash_item * result;
for ( result = set->data[ pos ]; result; result = result->header.next )
if ( !strcmp( result->data, string ) )
if ( !result->data[ size ] && !memcmp( result->data, string, size ) )
return result->data;
if ( set->size >= set->num )
@@ -211,17 +211,18 @@ static char const * string_set_insert( string_set * set, char const * string )
pos = hash % set->num;
}
len = strlen( string ) + 1;
result = (struct hash_item *)allocate( sizeof( struct hash_header ) + len );
result = (struct hash_item *)allocate( sizeof( struct hash_header ) + size +
1 );
result->header.hash = hash;
result->header.next = set->data[ pos ];
#ifndef NDEBUG
result->header.magic = OBJECT_MAGIC;
#endif
memcpy( result->data, string, len );
assert( hash_keyval( result->data ) == result->header.hash );
memcpy( result->data, string, size );
result->data[ size ] = '\0';
assert( hash_keyval( result->data, size ) == result->header.hash );
set->data[ pos ] = result;
strtotal += len;
strtotal += size + 1;
++set->size;
return result->data;
@@ -243,32 +244,41 @@ static void object_validate( OBJECT * obj )
/*
* object_new() - create an object from a string.
* object_new_range() - create an object from a string of given length
*/
OBJECT * object_new( char const * string )
OBJECT * object_new_range( char const * const string, int const size )
{
++strcount_in;
#ifdef BJAM_NO_MEM_CACHE
{
int const len = strlen( string ) + 1;
struct hash_item * const m = (struct hash_item *)BJAM_MALLOC( sizeof(
struct hash_header ) + len );
strtotal += len;
memcpy( m->data, string, len );
struct hash_header ) + size + 1 );
strtotal += size + 1;
memcpy( m->data, string, size );
m->data[ size ] = '\0';
m->header.magic = OBJECT_MAGIC;
return (OBJECT *)m->data;
}
#else
if ( !strhash.data )
string_set_init( &strhash );
return (OBJECT *)string_set_insert( &strhash, string );
return (OBJECT *)string_set_insert( &strhash, string, size );
#endif
}
/*
* object_new() - create an object from a string
*/
OBJECT * object_new( char const * const string )
{
return object_new_range( string, strlen( string ) );
}
#ifndef object_copy
/*
@@ -337,7 +347,7 @@ unsigned int object_hash( OBJECT * obj )
{
object_validate( obj );
#ifdef BJAM_NO_MEM_CACHE
return hash_keyval( object_str( obj ) );
return hash_keyval( object_str( obj ), strlen( object_str( obj ) ) );
#else
return object_get_item( obj )->header.hash;
#endif

View File

@@ -13,8 +13,9 @@
typedef struct _object OBJECT;
OBJECT * object_new ( char const * );
void object_done( void );
OBJECT * object_new( char const * const );
OBJECT * object_new_range( char const * const, int const size );
void object_done( void );
#if defined(NDEBUG) && !defined(BJAM_NO_MEM_CACHE)