String & String::PrintF( const char *format, va_list args, size_t stack_buffer ) { size_t len; char buf[stack_buffer]; char *ptr = buf; D_ASSERT( format != NULL ); // TODO: check if va_copy is required here #ifdef __GNUC__ va_list ap2; va_copy( ap2, args ); len = direct_vsnprintf( buf, sizeof(buf), format, ap2 ); va_end( ap2 ); #else len = direct_vsnprintf( buf, sizeof(buf), format, args ); #endif if (len < 0) return *this; if (len >= sizeof(buf)) { ptr = (char*) direct_malloc( len+1 ); if (!ptr) { D_OOM(); return *this; } len = direct_vsnprintf( ptr, len+1, format, args ); if (len < 0) { direct_free( ptr ); return *this; } } str.append( ptr ); if (ptr != buf) direct_free( ptr ); return *this; }
void direct_dbg_free( const char *file, int line, const char *func, const char *what, void *mem ) { unsigned long *val; MemDesc *desc; if (!mem) { D_WARN( "%s (NULL) called", __FUNCTION__ ); return; } val = (unsigned long*)((char*) mem - DISABLED_OFFSET); if (val[0] == ~0) { D_DEBUG_AT( Direct_Mem, " - number of bytes of %s [%s:%d in %s()] -> %p\n", what, file, line, func, mem ); val[0] = 0; direct_free( val ); return; } /* Debug only. */ direct_mutex_lock( &alloc_lock ); desc = (MemDesc*)((char*) mem - sizeof(MemDesc)); D_ASSERT( desc->mem == mem ); if (direct_hash_remove( &alloc_hash, (unsigned long) mem )) { D_ERROR( "Direct/Mem: Not freeing unknown %p (%s) from [%s:%d in %s()] - corrupt/incomplete list?\n", mem, what, file, line, func ); } else { D_DEBUG_AT( Direct_Mem, " -"_ZUn(6)" bytes [%s:%d in %s()] -> %p '%s'\n", desc->bytes, file, line, func, mem, what ); if (desc->trace) direct_trace_free_buffer( desc->trace ); direct_free( desc ); } direct_mutex_unlock( &alloc_lock ); }
DirectResult direct_print( char *buf, size_t size, const char *format, va_list args, char **ret_ptr ) { int len = 1; *ret_ptr = buf; if (buf) { buf[0] = 0; #ifdef __GNUC__ va_list args_copy; va_copy( args_copy, args ); len = direct_vsnprintf( buf, size, format, args_copy ); va_end( args_copy ); #else len = direct_vsnprintf( buf, size, format, args ); #endif if (len < 0) return DR_FAILURE; } else size = 0; if (len >= (int) size) { char *ptr = buf; ptr = direct_malloc( len+1 ); if (!ptr) return DR_NOLOCALMEMORY; len = direct_vsnprintf( ptr, len+1, format, args ); if (len < 0) { direct_free( ptr ); return DR_FAILURE; } *ret_ptr = ptr; } return DR_OK; }
void direct_hash_deinit( DirectHash *hash ) { D_MAGIC_ASSERT( hash, DirectHash ); D_MAGIC_CLEAR( hash ); if (hash->Elements) { if (hash->disable_debugging_alloc) direct_free( hash->Elements ); else D_FREE( hash->Elements ); hash->Elements = NULL; } }
Strings String::GetTokens( const Direct::String &delimiter ) const { Strings tokens; char *buf = direct_strdup( buffer() ); char *str = buf; char *save, *token; while ((token = strtok_r( str, delimiter.buffer(), &save ))) { str = NULL; tokens.push_back( Direct::String::F( "%s", token ) ); } direct_free( buf ); return tokens; }
DirectResult direct_hash_insert( DirectHash *hash, unsigned long key, void *value ) { int pos; DirectHashElement *element; D_MAGIC_ASSERT( hash, DirectHash ); D_ASSERT( hash->size > 0 ); D_ASSERT( value != NULL ); if (!hash->Elements) { if (hash->disable_debugging_alloc) hash->Elements = direct_calloc( hash->size, sizeof(DirectHashElement) ); else hash->Elements = D_CALLOC( hash->size, sizeof(DirectHashElement) ); if (!hash->Elements) return D_OOM(); } /* Need to resize the hash table? */ if ((hash->count + hash->removed) > hash->size / 2) { int i, size; DirectHashElement *elements; size = spaced_primes_closest( hash->size ); if (size > DIRECT_HASH_MAX_SIZE) size = DIRECT_HASH_MAX_SIZE; if (size < DIRECT_HASH_MIN_SIZE) size = DIRECT_HASH_MIN_SIZE; D_DEBUG_AT( Direct_Hash, "Resizing from %d to %d... (count %d, removed %d)\n", hash->size, size, hash->count, hash->removed ); if (hash->disable_debugging_alloc) elements = direct_calloc( size, sizeof(DirectHashElement) ); else elements = D_CALLOC( size, sizeof(DirectHashElement) ); if (!elements) { D_WARN( "out of memory" ); return DR_NOLOCALMEMORY; } for (i=0; i<hash->size; i++) { DirectHashElement *element = &hash->Elements[i]; DirectHashElement *insertElement; if (element->value && element->value != DIRECT_HASH_ELEMENT_REMOVED) { pos = element->key % size; insertElement = &elements[pos]; while (insertElement->value && insertElement->value != DIRECT_HASH_ELEMENT_REMOVED) { if (++pos == size) pos = 0; insertElement = &elements[pos]; } elements[pos] = *element; } } if (hash->disable_debugging_alloc) direct_free( hash->Elements ); else D_FREE( hash->Elements ); hash->size = size; hash->Elements = elements; hash->removed = 0; } pos = key % hash->size; D_DEBUG_AT( Direct_Hash, "Attempting to insert key 0x%08lx at position %d...\n", key, pos ); element = &hash->Elements[pos]; while (element->value && element->value != DIRECT_HASH_ELEMENT_REMOVED) { if (element->key == key) { D_BUG( "key already exists" ); return DR_BUG; } if (++pos == hash->size) pos = 0; element = &hash->Elements[pos]; } if (element->value == DIRECT_HASH_ELEMENT_REMOVED) hash->removed--; element->key = key; element->value = value; hash->count++; D_DEBUG_AT( Direct_Hash, "...inserted at %d, new count = %d, removed = %d, size = %d, key = 0x%08lx.\n", pos, hash->count, hash->removed, hash->size, key ); return DR_OK; }