parent
7246d9d3af
commit
c12ec72c2f
7 changed files with 6 additions and 1217 deletions
@ -1,197 +0,0 @@ |
||||
#include <ft2build.h> |
||||
#include FT_EXCEPT_H |
||||
|
||||
|
||||
FT_BASE_DEF( void ) |
||||
ft_cleanup_stack_init( FT_CleanupStack stack, |
||||
FT_Memory memory ) |
||||
{ |
||||
stack->chunk = &stack->chunk_0; |
||||
stack->top = stack->chunk->items; |
||||
stack->limit = stack->top + FT_CLEANUP_CHUNK_SIZE; |
||||
stack->chunk_0.link = NULL; |
||||
|
||||
stack->memory = memory; |
||||
} |
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( void ) |
||||
ft_cleanup_stack_done( FT_CleanupStack stack ) |
||||
{ |
||||
FT_Memory memory = stack->memory; |
||||
FT_CleanupChunk chunk, next; |
||||
|
||||
for (;;) |
||||
{ |
||||
chunk = stack->chunk; |
||||
if ( chunk == &stack->chunk_0 ) |
||||
break; |
||||
|
||||
stack->chunk = chunk->link; |
||||
|
||||
FT_Free( chunk, memory ); |
||||
} |
||||
|
||||
stack->memory = NULL; |
||||
} |
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( void ) |
||||
ft_cleanup_stack_push( FT_CleanupStack stack, |
||||
FT_Pointer item, |
||||
FT_CleanupFunc item_func, |
||||
FT_Pointer item_data ) |
||||
{ |
||||
FT_CleanupItem top; |
||||
|
||||
|
||||
FT_ASSERT( stack && stack->chunk && stack->top ); |
||||
FT_ASSERT( item && item_func ); |
||||
|
||||
top = stack->top; |
||||
|
||||
top->item = item; |
||||
top->item_func = item_func; |
||||
top->item_data = item_data; |
||||
|
||||
top ++; |
||||
|
||||
if ( top == stack->limit ) |
||||
{ |
||||
FT_CleanupChunk chunk; |
||||
|
||||
chunk = FT_QAlloc( sizeof(*chunk), stack->memory ); |
||||
|
||||
chunk->link = stack->chunk; |
||||
stack->chunk = chunk; |
||||
stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE; |
||||
top = chunk->items; |
||||
} |
||||
|
||||
stack->top = top; |
||||
} |
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( void ) |
||||
ft_cleanup_stack_pop( FT_CleanupStack stack, |
||||
FT_Int destroy ) |
||||
{ |
||||
FT_CleanupItem top; |
||||
|
||||
|
||||
FT_ASSERT( stack && stack->chunk && stack->top ); |
||||
top = stack->top; |
||||
|
||||
if ( top == stack->chunk->items ) |
||||
{ |
||||
FT_CleanupChunk chunk; |
||||
|
||||
chunk = stack->chunk; |
||||
|
||||
if ( chunk == &stack->chunk_0 ) |
||||
{ |
||||
FT_ERROR(( "cleanup.pop: empty cleanup stack !!\n" )); |
||||
ft_cleanup_throw( stack, FT_Err_EmptyCleanupStack ); |
||||
} |
||||
|
||||
chunk = chunk->link; |
||||
FT_QFree( stack->chunk, stack->memory ); |
||||
|
||||
stack->chunk = chunk; |
||||
stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE; |
||||
top = stack->limit; |
||||
} |
||||
|
||||
top --; |
||||
|
||||
if ( destroy ) |
||||
top->item_func( top->item, top->item_data ); |
||||
|
||||
top->item = NULL; |
||||
top->item_func = NULL; |
||||
top->item_data = NULL; |
||||
|
||||
stack->top = top; |
||||
} |
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_CleanupItem ) |
||||
ft_cleanup_stack_peek( FT_CleanupStack stack ) |
||||
{ |
||||
FT_CleanupItem top; |
||||
FT_CleanupChunk chunk; |
||||
|
||||
|
||||
FT_ASSERT( stack && stack->chunk && stack->top ); |
||||
|
||||
top = stack->top; |
||||
chunk = stack->chunk; |
||||
|
||||
if ( top > chunk->items ) |
||||
top--; |
||||
else |
||||
{ |
||||
chunk = chunk->link; |
||||
top = NULL; |
||||
if ( chunk != NULL ) |
||||
top = chunk->items + FT_CLEANUP_CHUNK_SIZE - 1; |
||||
} |
||||
return top; |
||||
} |
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( void ) |
||||
ft_xhandler_enter( FT_XHandler xhandler, |
||||
FT_Memory memory ) |
||||
{ |
||||
FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory); |
||||
|
||||
xhandler->previous = stack->xhandler; |
||||
xhandler->cleanup = stack->top; |
||||
xhandler->error = 0; |
||||
stack->xhandler = xhandler; |
||||
} |
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( void ) |
||||
ft_xhandler_exit( FT_XHandler xhandler ) |
||||
{ |
||||
FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory); |
||||
|
||||
stack->xhandler = xhandler->previous; |
||||
xhandler->previous = NULL; |
||||
xhandler->error = error; |
||||
xhandler->cleanup = NULL; |
||||
} |
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( void ) |
||||
ft_cleanup_throw( FT_CleanupStack stack, |
||||
FT_Error error ) |
||||
{ |
||||
FT_XHandler xhandler = stack->xhandler; |
||||
|
||||
if ( xhandler == NULL ) |
||||
{ |
||||
/* no exception handler was registered. this */ |
||||
/* means that we have an un-handled exception */ |
||||
/* the only thing we can do is _PANIC_ and */ |
||||
/* halt the current program.. */ |
||||
/* */ |
||||
FT_ERROR(( "FREETYPE PANIC: An un-handled exception occured. Program aborted" )); |
||||
ft_exit(1); |
||||
} |
||||
|
||||
/* cleanup the stack until we reach the handler's */ |
||||
/* starting stack location.. */ |
||||
|
||||
xhandler->error = error; |
||||
longmp( xhandler->jump_buffer, 1 ); |
||||
}
|
@ -1,246 +0,0 @@ |
||||
#include <ft2build.h> |
||||
#include FT_TYPES_H |
||||
#include FT_INTERNAL_HASH_H |
||||
#include FT_INTERNAL_MEMORY_H |
||||
#include FT_INTERNAL_DEBUG_H |
||||
|
||||
#define FT_HASH_MAX_LOAD 2 |
||||
#define FT_HASH_MIN_LOAD 1 |
||||
#define FT_HASH_SUB_LOAD (FT_HASH_MAX_LOAD-FT_HASH_MIN_LOAD) |
||||
|
||||
/* this one _must_ be a power of 2 !! */ |
||||
#define FT_HASH_INITIAL_SIZE 8 |
||||
|
||||
|
||||
FT_BASE_DEF( void ) |
||||
ft_hash_done( FT_Hash table, |
||||
FT_Hash_ForeachFunc node_func, |
||||
const FT_Pointer node_data ) |
||||
{ |
||||
if ( table ) |
||||
{ |
||||
FT_Memory memory = table->memory; |
||||
|
||||
if ( node_func ) |
||||
ft_hash_foreach( table, node_func, node_data ); |
||||
|
||||
FT_FREE( table->buckets ); |
||||
table->p = 0; |
||||
table->mask = 0; |
||||
table->slack = 0; |
||||
|
||||
table->node_equal = NULL; |
||||
} |
||||
} |
||||
|
||||
|
||||
FT_BASE_DEF( FT_UInt ) |
||||
ft_hash_get_size( FT_Hash table ) |
||||
{ |
||||
FT_UInt result = 0; |
||||
|
||||
if ( table ) |
||||
result = (table->p + table->mask + 1)*FT_HASH_MAX_LOAD - table->slack; |
||||
|
||||
return result; |
||||
} |
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error ) |
||||
ft_hash_init( FT_Hash table, |
||||
FT_Hash_EqualFunc equal, |
||||
FT_Memory memory ) |
||||
{ |
||||
FT_Error error; |
||||
|
||||
table->memory = memory; |
||||
table->p = 0; |
||||
table->mask = FT_HASH_INITIAL_SIZE-1; |
||||
table->slack = FT_HASH_INITIAL_SIZE*FT_HASH_MAX_LOAD; |
||||
table->node_equal = equal; |
||||
|
||||
(void)FT_NEW_ARRAY( table->buckets, FT_HASH_INITIAL_SIZE*2 ); |
||||
|
||||
return error; |
||||
} |
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( void ) |
||||
ft_hash_foreach( FT_Hash table, |
||||
FT_Hash_ForeachFunc foreach_func, |
||||
const FT_Pointer foreach_data ) |
||||
{ |
||||
FT_UInt count = table->p + table->mask + 1; |
||||
FT_HashNode* pnode = table->buckets; |
||||
FT_HashNode node, next; |
||||
|
||||
for ( ; count > 0; count--, pnode++ ) |
||||
{ |
||||
node = *pnode; |
||||
while ( node ) |
||||
{ |
||||
next = node->link; |
||||
foreach_func( node, foreach_data ); |
||||
node = next; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_HashLookup ) |
||||
ft_hash_lookup( FT_Hash table, |
||||
FT_HashNode keynode ) |
||||
{ |
||||
FT_UInt index; |
||||
FT_UInt32 hash = keynode->hash; |
||||
FT_HashNode node, *pnode; |
||||
|
||||
index = (FT_UInt)(hash & table->mask); |
||||
if ( index < table->p ) |
||||
index = (FT_UInt)(hash & (2*table->mask+1)); |
||||
|
||||
pnode = &table->buckets[index]; |
||||
for (;;) |
||||
{ |
||||
node = *pnode; |
||||
if ( node == NULL ) |
||||
break; |
||||
|
||||
if ( node->hash == hash && table->node_equal( node, keynode ) ) |
||||
break; |
||||
|
||||
pnode = &node->link; |
||||
} |
||||
|
||||
return pnode; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error ) |
||||
ft_hash_add( FT_Hash table, |
||||
FT_HashLookup lookup, |
||||
FT_HashNode new_node ) |
||||
{ |
||||
FT_Error error = 0; |
||||
|
||||
/* add it to the hash table */ |
||||
new_node->link = *lookup; |
||||
*lookup = new_node; |
||||
|
||||
if ( --table->slack < 0 ) |
||||
{ |
||||
FT_UInt p = table->p; |
||||
FT_UInt mask = table->mask; |
||||
FT_HashNode new_list, node, *pnode; |
||||
|
||||
/* split a single bucket */ |
||||
new_list = NULL; |
||||
pnode = table->buckets + p; |
||||
for (;;) |
||||
{ |
||||
node = *pnode; |
||||
if ( node == NULL ) |
||||
break; |
||||
|
||||
if ( node->hash & mask ) |
||||
{ |
||||
*pnode = node->link; |
||||
node->link = new_list; |
||||
new_list = node; |
||||
} |
||||
else |
||||
pnode = &node->link; |
||||
} |
||||
|
||||
table->buckets[ p + mask + 1 ] = new_list; |
||||
|
||||
table->slack += FT_HASH_MAX_LOAD; |
||||
|
||||
if ( p >= mask ) |
||||
{ |
||||
FT_Memory memory = table->memory; |
||||
|
||||
|
||||
if (FT_RENEW_ARRAY( table->buckets, (mask+1)*2, (mask+1)*4 )) |
||||
goto Exit; |
||||
|
||||
table->mask = 2*mask + 1; |
||||
table->p = 0; |
||||
} |
||||
else |
||||
table->p = p + 1; |
||||
} |
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error ) |
||||
ft_hash_remove( FT_Hash table, |
||||
FT_HashLookup lookup ) |
||||
{ |
||||
FT_HashNode node; |
||||
FT_UInt num_buckets; |
||||
FT_Error error = 0; |
||||
|
||||
FT_ASSERT( pnode != NULL && node != NULL ); |
||||
|
||||
node = *lookup; |
||||
*lookup = node->link; |
||||
node->link = NULL; |
||||
|
||||
num_buckets = ( table->p + table->mask + 1) ; |
||||
|
||||
if ( ++ table->slack > (FT_Long)num_buckets*FT_HASH_SUB_LOAD ) |
||||
{ |
||||
FT_UInt p = table->p; |
||||
FT_UInt mask = table->mask; |
||||
FT_UInt old_index = p + mask; |
||||
FT_HashNode* pnode; |
||||
FT_HashNode* pold; |
||||
|
||||
if ( old_index < FT_HASH_INITIAL_SIZE ) |
||||
goto Exit; |
||||
|
||||
if ( p == 0 ) |
||||
{ |
||||
FT_Memory memory = table->memory; |
||||
|
||||
table->mask >>= 1; |
||||
p = table->mask; |
||||
|
||||
if ( FT_RENEW_ARRAY( table->buckets, (mask+1)*2, (mask+1) ) ) |
||||
{ |
||||
/* this should never happen normally, but who knows :-) */ |
||||
/* we need to re-inject the node in the hash table before */ |
||||
/* returning there, since it's safer */ |
||||
pnode = table->buckets; |
||||
node->link = *pnode; |
||||
*pnode = node; |
||||
|
||||
goto Exit; |
||||
} |
||||
} |
||||
else |
||||
p--; |
||||
|
||||
pnode = table->buckets + p; |
||||
while ( *pnode ) |
||||
pnode = &(*pnode)->link; |
||||
|
||||
pold = table->buckets + old_index; |
||||
*pnode = *pold; |
||||
*pold = NULL; |
||||
|
||||
table->slack -= FT_HASH_MAX_LOAD; |
||||
table->p = p; |
||||
} |
||||
Exit: |
||||
return error; |
||||
} |
@ -1,217 +0,0 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* ftlist.c */ |
||||
/* */ |
||||
/* Generic list support for FreeType (body). */ |
||||
/* */ |
||||
/* Copyright 1996-2001, 2002 by */ |
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||||
/* */ |
||||
/* This file is part of the FreeType project, and may only be used, */ |
||||
/* modified, and distributed under the terms of the FreeType project */ |
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||||
/* this file you indicate that you have read the license and */ |
||||
/* understand and accept it fully. */ |
||||
/* */ |
||||
/***************************************************************************/ |
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* This file implements functions relative to list processing. Its */ |
||||
/* data structures are defined in `freetype/internal/ftlist.h'. */ |
||||
/* */ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_LIST_H |
||||
#include FT_INTERNAL_DEBUG_H |
||||
#include FT_INTERNAL_OBJECTS_H |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/* */ |
||||
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
||||
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
||||
/* messages during execution. */ |
||||
/* */ |
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT trace_list |
||||
|
||||
|
||||
/* documentation is in ftlist.h */ |
||||
|
||||
FT_EXPORT_DEF( FT_ListNode ) |
||||
FT_List_Find( FT_List list, |
||||
void* data ) |
||||
{ |
||||
FT_ListNode cur; |
||||
|
||||
|
||||
cur = list->head; |
||||
while ( cur ) |
||||
{ |
||||
if ( cur->data == data ) |
||||
return cur; |
||||
|
||||
cur = cur->next; |
||||
} |
||||
|
||||
return (FT_ListNode)0; |
||||
} |
||||
|
||||
|
||||
/* documentation is in ftlist.h */ |
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FT_List_Add( FT_List list, |
||||
FT_ListNode node ) |
||||
{ |
||||
FT_ListNode before = list->tail; |
||||
|
||||
|
||||
node->next = 0; |
||||
node->prev = before; |
||||
|
||||
if ( before ) |
||||
before->next = node; |
||||
else |
||||
list->head = node; |
||||
|
||||
list->tail = node; |
||||
} |
||||
|
||||
|
||||
/* documentation is in ftlist.h */ |
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FT_List_Insert( FT_List list, |
||||
FT_ListNode node ) |
||||
{ |
||||
FT_ListNode after = list->head; |
||||
|
||||
|
||||
node->next = after; |
||||
node->prev = 0; |
||||
|
||||
if ( !after ) |
||||
list->tail = node; |
||||
else |
||||
after->prev = node; |
||||
|
||||
list->head = node; |
||||
} |
||||
|
||||
|
||||
/* documentation is in ftlist.h */ |
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FT_List_Remove( FT_List list, |
||||
FT_ListNode node ) |
||||
{ |
||||
FT_ListNode before, after; |
||||
|
||||
|
||||
before = node->prev; |
||||
after = node->next; |
||||
|
||||
if ( before ) |
||||
before->next = after; |
||||
else |
||||
list->head = after; |
||||
|
||||
if ( after ) |
||||
after->prev = before; |
||||
else |
||||
list->tail = before; |
||||
} |
||||
|
||||
|
||||
/* documentation is in ftlist.h */ |
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FT_List_Up( FT_List list, |
||||
FT_ListNode node ) |
||||
{ |
||||
FT_ListNode before, after; |
||||
|
||||
|
||||
before = node->prev; |
||||
after = node->next; |
||||
|
||||
/* check whether we are already on top of the list */ |
||||
if ( !before ) |
||||
return; |
||||
|
||||
before->next = after; |
||||
|
||||
if ( after ) |
||||
after->prev = before; |
||||
else |
||||
list->tail = before; |
||||
|
||||
node->prev = 0; |
||||
node->next = list->head; |
||||
list->head->prev = node; |
||||
list->head = node; |
||||
} |
||||
|
||||
|
||||
/* documentation is in ftlist.h */ |
||||
|
||||
FT_EXPORT_DEF( FT_Error ) |
||||
FT_List_Iterate( FT_List list, |
||||
FT_List_Iterator iterator, |
||||
void* user ) |
||||
{ |
||||
FT_ListNode cur = list->head; |
||||
FT_Error error = FT_Err_Ok; |
||||
|
||||
|
||||
while ( cur ) |
||||
{ |
||||
FT_ListNode next = cur->next; |
||||
|
||||
|
||||
error = iterator( cur, user ); |
||||
if ( error ) |
||||
break; |
||||
|
||||
cur = next; |
||||
} |
||||
|
||||
return error; |
||||
} |
||||
|
||||
|
||||
/* documentation is in ftlist.h */ |
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
FT_List_Finalize( FT_List list, |
||||
FT_List_Destructor destroy, |
||||
FT_Memory memory, |
||||
void* user ) |
||||
{ |
||||
FT_ListNode cur; |
||||
|
||||
|
||||
cur = list->head; |
||||
while ( cur ) |
||||
{ |
||||
FT_ListNode next = cur->next; |
||||
void* data = cur->data; |
||||
|
||||
|
||||
if ( destroy ) |
||||
destroy( memory, data, user ); |
||||
|
||||
FT_FREE( cur ); |
||||
cur = next; |
||||
} |
||||
|
||||
list->head = 0; |
||||
list->tail = 0; |
||||
} |
||||
|
||||
|
||||
/* END */ |
@ -1,396 +0,0 @@ |
||||
#include <ft2build.h> |
||||
#include FT_INTERNAL_OBJECT_H |
||||
#include FT_INTERNAL_DEBUG_H |
||||
#include FT_INTERNAL_OBJECTS_H |
||||
|
||||
#define FT_MAGIC_DEATH 0xDEADdead |
||||
#define FT_MAGIC_CLASS 0x12345678 |
||||
|
||||
#define FT_TYPE_HASH(x) (( (FT_UInt32)(x) >> 2 )^( (FT_UInt32)(x) >> 10 )) |
||||
|
||||
#define FT_OBJECT_CHECK(o) \ |
||||
( FT_OBJECT(o) != NULL && \
|
||||
FT_OBJECT(o)->clazz != NULL && \
|
||||
FT_OBJECT(o)->ref_count >= 1 && \
|
||||
FT_OBJECT(o)->clazz->magic == FT_MAGIC_CLASS ) |
||||
|
||||
#define FT_CLASS_CHECK(c) \ |
||||
( FT_CLASS(c) != NULL && FT_CLASS(c)->magic == FT_MAGIC_CLASS ) |
||||
|
||||
#define FT_ASSERT_IS_CLASS(c) FT_ASSERT( FT_CLASS_CHECK(c) ) |
||||
|
||||
/*******************************************************************/ |
||||
/*******************************************************************/ |
||||
/***** *****/ |
||||
/***** *****/ |
||||
/***** M E T A - C L A S S *****/ |
||||
/***** *****/ |
||||
/***** *****/ |
||||
/*******************************************************************/ |
||||
/*******************************************************************/ |
||||
|
||||
/* forward declaration */ |
||||
FT_BASE_DEF( FT_Error ) |
||||
ft_metaclass_init( FT_MetaClass meta, |
||||
FT_Library library ); |
||||
|
||||
/* forward declaration */ |
||||
FT_BASE_DEF( void ) |
||||
ft_metaclass_done( FT_MetaClass meta ); |
||||
|
||||
|
||||
/* class type for the meta-class itself */ |
||||
static const FT_TypeRec ft_meta_class_type = |
||||
{ |
||||
"FT2.MetaClass", |
||||
NULL, |
||||
|
||||
sizeof( FT_MetaClassRec ), |
||||
(FT_Object_InitFunc) ft_metaclass_init, |
||||
(FT_Object_DoneFunc) ft_metaclass_done, |
||||
|
||||
sizeof( FT_ClassRec ), |
||||
(FT_Object_InitFunc) NULL, |
||||
(FT_Object_DoneFunc) NULL |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
/* destroy a given class */ |
||||
static void |
||||
ft_class_hnode_destroy( FT_ClassHNode node ) |
||||
{ |
||||
FT_Class clazz = node->clazz; |
||||
FT_Memory memory = clazz->memory; |
||||
|
||||
if ( clazz->class_done ) |
||||
clazz->class_done( (FT_Object) clazz ); |
||||
|
||||
FT_FREE( clazz ); |
||||
|
||||
node->clazz = NULL; |
||||
node->type = NULL; |
||||
|
||||
FT_FREE( node ); |
||||
} |
||||
|
||||
|
||||
static FT_Int |
||||
ft_type_equal( FT_Type type1, |
||||
FT_Type type2 ) |
||||
{ |
||||
if ( type1 == type2 ) |
||||
goto Ok; |
||||
|
||||
if ( type1 == NULL || type2 == NULL ) |
||||
goto Fail; |
||||
|
||||
/* compare parent types */ |
||||
if ( type1->super != type2->super ) |
||||
{ |
||||
if ( type1->super == NULL || |
||||
type2->super == NULL || |
||||
!ft_type_equal( type1, type2 ) ) |
||||
goto Fail; |
||||
} |
||||
|
||||
/* compare type names */ |
||||
if ( type1->name != type2->name ) |
||||
{ |
||||
if ( type1->name == NULL || |
||||
type2->name == NULL || |
||||
ft_strcmp( type1->name, type2->name ) != 0 ) |
||||
goto Fail; |
||||
} |
||||
|
||||
/* compare the other type fields */ |
||||
if ( type1->class_size != type2->class_size || |
||||
type1->class_init != type2->class_init || |
||||
type1->class_done != type2->class_done || |
||||
type1->obj_size != type2->obj_size || |
||||
type1->obj_init != type2->obj_init || |
||||
type1->obj_done != type2->obj_done ) |
||||
goto Fail; |
||||
|
||||
Ok: |
||||
return 1; |
||||
|
||||
Fail: |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
static FT_Int |
||||
ft_class_hnode_equal( const FT_ClassHNode node1, |
||||
const FT_ClassHNode node2 ) |
||||
{ |
||||
FT_Type type1 = node1->type; |
||||
FT_Type type2 = node2->type; |
||||
|
||||
/* comparing the pointers should work in 99% of cases */ |
||||
return ( type1 == type2 ) ? 1 : ft_type_equal( type1, type2 ); |
||||
} |
||||
|
||||
|
||||
FT_BASE_DEF( void ) |
||||
ft_metaclass_done( FT_MetaClass meta ) |
||||
{ |
||||
/* clear all classes */ |
||||
ft_hash_done( &meta->type_to_class, |
||||
(FT_Hash_ForeachFunc) ft_class_hnode_destroy, |
||||
NULL ); |
||||
|
||||
meta->clazz.object.clazz = NULL; |
||||
meta->clazz.object.ref_count = 0; |
||||
meta->clazz.magic = FT_MAGIC_DEATH; |
||||
} |
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error ) |
||||
ft_metaclass_init( FT_MetaClass meta, |
||||
FT_Library library ) |
||||
{ |
||||
FT_ClassRec* clazz = (FT_ClassRec*) &meta->clazz; |
||||
|
||||
/* the meta-class is its OWN class !! */ |
||||
clazz->object.clazz = (FT_Class) clazz; |
||||
clazz->object.ref_count = 1; |
||||
clazz->magic = FT_MAGIC_CLASS; |
||||
clazz->library = library; |
||||
clazz->memory = library->memory; |
||||
clazz->type = &ft_meta_class_type; |
||||
clazz->info = NULL; |
||||
|
||||
clazz->class_done = (FT_Object_DoneFunc) ft_metaclass_done; |
||||
|
||||
clazz->obj_size = sizeof( FT_ClassRec ); |
||||
clazz->obj_init = NULL; |
||||
clazz->obj_done = NULL; |
||||
|
||||
return ft_hash_init( &meta->type_to_class, |
||||
(FT_Hash_EqualFunc) ft_class_hnode_equal, |
||||
library->memory ); |
||||
} |
||||
|
||||
|
||||
/* find or create the class corresponding to a given type */ |
||||
/* note that this function will retunr NULL in case of */ |
||||
/* memory overflow */ |
||||
/* */ |
||||
static FT_Class |
||||
ft_metaclass_get_class( FT_MetaClass meta, |
||||
FT_Type ctype ) |
||||
{ |
||||
FT_ClassHNodeRec keynode, *node, **pnode; |
||||
FT_Memory memory; |
||||
FT_ClassRec* clazz; |
||||
FT_Class parent; |
||||
FT_Error error; |
||||
|
||||
keynode.hnode.hash = FT_TYPE_HASH( ctype ); |
||||
keynode.type = ctype; |
||||
|
||||
pnode = (FT_ClassHNode*) ft_hash_lookup( &meta->type_to_class, |
||||
(FT_HashNode) &keynode ); |
||||
node = *pnode; |
||||
if ( node != NULL ) |
||||
{ |
||||
clazz = (FT_ClassRec*) node->clazz; |
||||
goto Exit; |
||||
} |
||||
|
||||
memory = FT_CLASS__MEMORY(meta); |
||||
clazz = NULL; |
||||
parent = NULL; |
||||
if ( ctype->super != NULL ) |
||||
{ |
||||
FT_ASSERT( ctype->super->class_size <= ctype->class_size ); |
||||
FT_ASSERT( ctype->super->obj_size <= ctype->obj_size ); |
||||
|
||||
parent = ft_metaclass_get_class( meta, ctype->super ); |
||||
} |
||||
|
||||
if ( !FT_NEW( node ) ) |
||||
{ |
||||
if ( !FT_ALLOC( clazz, ctype->class_size ) ) |
||||
{ |
||||
if ( parent ) |
||||
FT_MEM_COPY( (FT_ClassRec*)clazz, parent, parent->type->class_size ); |
||||
|
||||
clazz->object.clazz = (FT_Class) meta; |
||||
clazz->object.ref_count = 1; |
||||
|
||||
clazz->memory = memory; |
||||
clazz->library = FT_CLASS__LIBRARY(meta); |
||||
clazz->super = parent; |
||||
clazz->type = ctype; |
||||
clazz->info = NULL; |
||||
clazz->magic = FT_MAGIC_CLASS; |
||||
|
||||
clazz->class_done = ctype->class_done; |
||||
clazz->obj_size = ctype->obj_size; |
||||
clazz->obj_init = ctype->obj_init; |
||||
clazz->obj_done = ctype->obj_done; |
||||
|
||||
if ( parent ) |
||||
{ |
||||
if ( clazz->class_done == NULL ) |
||||
clazz->class_done = parent->class_done; |
||||
|
||||
if ( clazz->obj_init == NULL ) |
||||
clazz->obj_init = parent->obj_init; |
||||
|
||||
if ( clazz->obj_done == NULL ) |
||||
clazz->obj_done = parent->obj_done; |
||||
} |
||||
|
||||
/* find class initializer, if any */ |
||||
{ |
||||
FT_Type ztype = ctype; |
||||
FT_Object_InitFunc cinit = NULL; |
||||
|
||||
do |
||||
{ |
||||
cinit = ztype->class_init; |
||||
if ( cinit != NULL ) |
||||
break; |
||||
|
||||
ztype = ztype->super; |
||||
} |
||||
while ( ztype != NULL ); |
||||
|
||||
/* then call it when needed */ |
||||
if ( cinit != NULL ) |
||||
error = cinit( (FT_Object) clazz, NULL ); |
||||
} |
||||
} |
||||
|
||||
if (error) |
||||
{ |
||||
if ( clazz ) |
||||
{ |
||||
/* we always call the class destructor when */ |
||||
/* an error was detected in the constructor !! */ |
||||
if ( clazz->class_done ) |
||||
clazz->class_done( (FT_Object) clazz ); |
||||
|
||||
FT_FREE( clazz ); |
||||
} |
||||
FT_FREE( node ); |
||||
} |
||||
} |
||||
|
||||
Exit: |
||||
return (FT_Class) clazz; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Int ) |
||||
ft_object_check( FT_Pointer obj ) |
||||
{ |
||||
return FT_OBJECT_CHECK(obj); |
||||
} |
||||
|
||||
|
||||
FT_BASE_DEF( FT_Int ) |
||||
ft_object_is_a( FT_Pointer obj, |
||||
FT_Class clazz ) |
||||
{ |
||||
if ( FT_OBJECT_CHECK(obj) ) |
||||
{ |
||||
FT_Class c = FT_OBJECT__CLASS(obj); |
||||
|
||||
do |
||||
{ |
||||
if ( c == clazz ) |
||||
return 1; |
||||
|
||||
c = c->super; |
||||
} |
||||
while ( c == NULL ); |
||||
|
||||
return (clazz == NULL); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error ) |
||||
ft_object_create( FT_Object *pobject, |
||||
FT_Class clazz, |
||||
FT_Pointer init_data ) |
||||
{ |
||||
FT_Memory memory; |
||||
FT_Error error; |
||||
FT_Object obj; |
||||
|
||||
FT_ASSERT_IS_CLASS(clazz); |
||||
|
||||
memory = FT_CLASS__MEMORY(clazz); |
||||
if ( !FT_ALLOC( obj, clazz->obj_size ) ) |
||||
{ |
||||
obj->clazz = clazz; |
||||
obj->ref_count = 1; |
||||
|
||||
if ( clazz->obj_init ) |
||||
{ |
||||
error = clazz->obj_init( obj, init_data ); |
||||
if ( error ) |
||||
{ |
||||
/* IMPORTANT: call the destructor when an error */ |
||||
/* was detected in the constructor !! */ |
||||
if ( clazz->obj_done ) |
||||
clazz->obj_done( obj ); |
||||
|
||||
FT_FREE( obj ); |
||||
} |
||||
} |
||||
} |
||||
*pobject = obj; |
||||
return error; |
||||
} |
||||
|
||||
|
||||
FT_BASE_DEF( FT_Class ) |
||||
ft_class_find_by_type( FT_Type type, |
||||
FT_Library library ) |
||||
{ |
||||
FT_MetaClass meta = &library->meta_class; |
||||
|
||||
return ft_metaclass_get_class( meta, type ); |
||||
} |
||||
|
||||
|
||||
FT_BASE_DEF( FT_Error ) |
||||
ft_object_create_from_type( FT_Object *pobject, |
||||
FT_Type type, |
||||
FT_Pointer init_data, |
||||
FT_Library library ) |
||||
{ |
||||
FT_Class clazz; |
||||
FT_Error error; |
||||
|
||||
clazz = ft_class_find_by_type( type, library ); |
||||
if ( clazz ) |
||||
error = ft_object_create( pobject, clazz, init_data ); |
||||
else |
||||
{ |
||||
*pobject = NULL; |
||||
error = FT_Err_Out_Of_Memory; |
||||
} |
||||
|
||||
return error; |
||||
} |
@ -1,131 +0,0 @@ |
||||
#include <ft2build.h> |
||||
#include FT_SYSTEM_STREAM_H |
||||
|
||||
#include <stdio.h> |
||||
|
||||
/* the ISO/ANSI standard stream object */ |
||||
typedef struct FT_StdStreamRec_ |
||||
{ |
||||
FT_StreamRec stream; |
||||
FILE* file; |
||||
const char* pathname; |
||||
|
||||
} FT_StdStreamRec, *FT_StdStream; |
||||
|
||||
|
||||
|
||||
/* read bytes from a standard stream */ |
||||
static FT_ULong |
||||
ft_std_stream_read( FT_StdStream stream, |
||||
FT_Byte* buffer, |
||||
FT_ULong size ) |
||||
{ |
||||
long read_bytes; |
||||
|
||||
read_bytes = fread( buffer, 1, size, stream->file ); |
||||
if ( read_bytes < 0 ) |
||||
read_bytes = 0; |
||||
|
||||
return (FT_ULong) read_bytes; |
||||
} |
||||
|
||||
|
||||
/* seek the standard stream to a new position */ |
||||
static FT_Error |
||||
ft_std_stream_seek( FT_StdStream stream, |
||||
FT_ULong pos ) |
||||
{ |
||||
return ( fseek( stream->file, pos, SEEK_SET ) < 0 ) |
||||
? FT_Err_Stream_Seek |
||||
: FT_Err_Ok; |
||||
} |
||||
|
||||
|
||||
/* close a standard stream */
|
||||
static void |
||||
ft_std_stream_done( FT_StdStream stream ) |
||||
{ |
||||
fclose( stream->file ); |
||||
stream->file = NULL; |
||||
stream->pathname = NULL; |
||||
} |
||||
|
||||
|
||||
/* open a standard stream from a given pathname */ |
||||
static void |
||||
ft_std_stream_init( FT_StdStream stream, |
||||
const char* pathname ) |
||||
{ |
||||
FT_ASSERT( pathname != NULL ); |
||||
|
||||
stream->file = fopen( pathname, "rb" ); |
||||
if ( stream->file == NULL ) |
||||
{ |
||||
FT_ERROR(( "iso.stream.init: could not open '%s'\n", pathname )); |
||||
FT_XTHROW( FT_Err_Stream_Open ); |
||||
} |
||||
|
||||
/* compute total size in bytes */ |
||||
fseek( file, 0, SEEK_END ); |
||||
FT_STREAM__SIZE(stream) = ftell( file ); |
||||
fseek( file, 0, SEEK_SET ); |
||||
|
||||
stream->pathname = pathname; |
||||
stream->pos = 0; |
||||
|
||||
FT_TRACE1(( "iso.stream.init: opened '%s' (%ld bytes) succesfully\n", |
||||
pathname, FT_STREAM__SIZE(stream) )); |
||||
}
|
||||
|
||||
|
||||
static void |
||||
ft_std_stream_class_init( FT_ClassRec* _clazz ) |
||||
{ |
||||
FT_StreamClassRec* clazz = FT_STREAM_CLASS(_clazz); |
||||
|
||||
clazz->stream_read = (FT_Stream_ReadFunc) ft_std_stream_read; |
||||
clazz->stream_seek = (FT_Stream_SeekFunc) ft_std_stream_seek; |
||||
} |
||||
|
||||
|
||||
static const FT_TypeRec ft_std_stream_type; |
||||
{ |
||||
"StreamClass", |
||||
NULL, |
||||
|
||||
sizeof( FT_ClassRec ), |
||||
ft_stream_class_init, |
||||
NULL, |
||||
|
||||
sizeof( FT_StdStreamRec ), |
||||
ft_std_stream_init, |
||||
ft_std_stream_done, |
||||
NULL, |
||||
}; |
||||
|
||||
|
||||
|
||||
FT_EXPORT_DEF( FT_Stream ) |
||||
ft_std_stream_new( FT_Memory memory, |
||||
const char* pathname ) |
||||
{ |
||||
FT_Class clazz; |
||||
|
||||
clazz = ft_class_from_type( memory, &ft_std_stream_type ); |
||||
|
||||
return (FT_Stream) ft_object_new( clazz, pathname ); |
||||
}
|
||||
|
||||
|
||||
FT_EXPORT_DEF( void ) |
||||
ft_std_stream_create( FT_Memory memory, |
||||
const char* pathname, |
||||
FT_Stream* astream ) |
||||
{ |
||||
FT_Class clazz; |
||||
|
||||
clazz = ft_class_from_type( memory, &ft_std_stream_type ); |
||||
|
||||
ft_object_create( clazz, pathname, FT_OBJECT_P(astream) ); |
||||
}
|
||||
|
@ -1,30 +0,0 @@ |
||||
#include <ft2build.h> |
||||
#include FT_SYSTEM_MEMORY_H |
||||
|
||||
static FT_Memory |
||||
ft_memory_new_default( FT_ULong size ) |
||||
{ |
||||
return (FT_Memory) ft_malloc( size ); |
||||
} |
||||
|
||||
static void |
||||
ft_memory_destroy_default( FT_Memory memory ) |
||||
{ |
||||
ft_free( memory ); |
||||
} |
||||
|
||||
|
||||
/* notice that in normal builds, we use the ISO C library functions */ |
||||
/* 'malloc', 'free' and 'realloc' directly.. */ |
||||
/* */ |
||||
static const FT_Memory_FuncsRec ft_memory_funcs_default_rec =
|
||||
{ |
||||
(FT_Memory_CreateFunc) ft_memory_new_iso, |
||||
(FT_Memory_DestroyFunc) ft_memory_destroy_iso, |
||||
(FT_Memory_AllocFunc) ft_malloc, |
||||
(FT_Memory_FreeFunc) ft_free, |
||||
(FT_Memory_ReallocFunc) ft_realloc |
||||
}; |
||||
|
||||
FT_APIVAR_DEF( const FT_Memory_Funcs ) |
||||
ft_memory_funcs_default = &ft_memory_funcs_defaults_rec; |
Loading…
Reference in new issue