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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user