/src/freetype/src/cache/ftcmru.c

https://bitbucket.org/cabalistic/ogredeps/ · C · 357 lines · 252 code · 88 blank · 17 comment · 52 complexity · e55c0ad255d1a918d2dd91dae9deab1c MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* ftcmru.c */
  4. /* */
  5. /* FreeType MRU support (body). */
  6. /* */
  7. /* Copyright 2003, 2004, 2006, 2009 by */
  8. /* David Turner, Robert Wilhelm, and Werner Lemberg. */
  9. /* */
  10. /* This file is part of the FreeType project, and may only be used, */
  11. /* modified, and distributed under the terms of the FreeType project */
  12. /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
  13. /* this file you indicate that you have read the license and */
  14. /* understand and accept it fully. */
  15. /* */
  16. /***************************************************************************/
  17. #include <ft2build.h>
  18. #include FT_CACHE_H
  19. #include "ftcmru.h"
  20. #include FT_INTERNAL_OBJECTS_H
  21. #include FT_INTERNAL_DEBUG_H
  22. #include "ftcerror.h"
  23. FT_LOCAL_DEF( void )
  24. FTC_MruNode_Prepend( FTC_MruNode *plist,
  25. FTC_MruNode node )
  26. {
  27. FTC_MruNode first = *plist;
  28. if ( first )
  29. {
  30. FTC_MruNode last = first->prev;
  31. #ifdef FT_DEBUG_ERROR
  32. {
  33. FTC_MruNode cnode = first;
  34. do
  35. {
  36. if ( cnode == node )
  37. {
  38. fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" );
  39. exit( 2 );
  40. }
  41. cnode = cnode->next;
  42. } while ( cnode != first );
  43. }
  44. #endif
  45. first->prev = node;
  46. last->next = node;
  47. node->next = first;
  48. node->prev = last;
  49. }
  50. else
  51. {
  52. node->next = node;
  53. node->prev = node;
  54. }
  55. *plist = node;
  56. }
  57. FT_LOCAL_DEF( void )
  58. FTC_MruNode_Up( FTC_MruNode *plist,
  59. FTC_MruNode node )
  60. {
  61. FTC_MruNode first = *plist;
  62. FT_ASSERT( first != NULL );
  63. if ( first != node )
  64. {
  65. FTC_MruNode prev, next, last;
  66. #ifdef FT_DEBUG_ERROR
  67. {
  68. FTC_MruNode cnode = first;
  69. do
  70. {
  71. if ( cnode == node )
  72. goto Ok;
  73. cnode = cnode->next;
  74. } while ( cnode != first );
  75. fprintf( stderr, "FTC_MruNode_Up: invalid action\n" );
  76. exit( 2 );
  77. Ok:
  78. }
  79. #endif
  80. prev = node->prev;
  81. next = node->next;
  82. prev->next = next;
  83. next->prev = prev;
  84. last = first->prev;
  85. last->next = node;
  86. first->prev = node;
  87. node->next = first;
  88. node->prev = last;
  89. *plist = node;
  90. }
  91. }
  92. FT_LOCAL_DEF( void )
  93. FTC_MruNode_Remove( FTC_MruNode *plist,
  94. FTC_MruNode node )
  95. {
  96. FTC_MruNode first = *plist;
  97. FTC_MruNode prev, next;
  98. FT_ASSERT( first != NULL );
  99. #ifdef FT_DEBUG_ERROR
  100. {
  101. FTC_MruNode cnode = first;
  102. do
  103. {
  104. if ( cnode == node )
  105. goto Ok;
  106. cnode = cnode->next;
  107. } while ( cnode != first );
  108. fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" );
  109. exit( 2 );
  110. Ok:
  111. }
  112. #endif
  113. prev = node->prev;
  114. next = node->next;
  115. prev->next = next;
  116. next->prev = prev;
  117. if ( node == next )
  118. {
  119. FT_ASSERT( first == node );
  120. FT_ASSERT( prev == node );
  121. *plist = NULL;
  122. }
  123. else if ( node == first )
  124. *plist = next;
  125. }
  126. FT_LOCAL_DEF( void )
  127. FTC_MruList_Init( FTC_MruList list,
  128. FTC_MruListClass clazz,
  129. FT_UInt max_nodes,
  130. FT_Pointer data,
  131. FT_Memory memory )
  132. {
  133. list->num_nodes = 0;
  134. list->max_nodes = max_nodes;
  135. list->nodes = NULL;
  136. list->clazz = *clazz;
  137. list->data = data;
  138. list->memory = memory;
  139. }
  140. FT_LOCAL_DEF( void )
  141. FTC_MruList_Reset( FTC_MruList list )
  142. {
  143. while ( list->nodes )
  144. FTC_MruList_Remove( list, list->nodes );
  145. FT_ASSERT( list->num_nodes == 0 );
  146. }
  147. FT_LOCAL_DEF( void )
  148. FTC_MruList_Done( FTC_MruList list )
  149. {
  150. FTC_MruList_Reset( list );
  151. }
  152. #ifndef FTC_INLINE
  153. FT_LOCAL_DEF( FTC_MruNode )
  154. FTC_MruList_Find( FTC_MruList list,
  155. FT_Pointer key )
  156. {
  157. FTC_MruNode_CompareFunc compare = list->clazz.node_compare;
  158. FTC_MruNode first, node;
  159. first = list->nodes;
  160. node = NULL;
  161. if ( first )
  162. {
  163. node = first;
  164. do
  165. {
  166. if ( compare( node, key ) )
  167. {
  168. if ( node != first )
  169. FTC_MruNode_Up( &list->nodes, node );
  170. return node;
  171. }
  172. node = node->next;
  173. } while ( node != first);
  174. }
  175. return NULL;
  176. }
  177. #endif
  178. FT_LOCAL_DEF( FT_Error )
  179. FTC_MruList_New( FTC_MruList list,
  180. FT_Pointer key,
  181. FTC_MruNode *anode )
  182. {
  183. FT_Error error;
  184. FTC_MruNode node = NULL;
  185. FT_Memory memory = list->memory;
  186. if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 )
  187. {
  188. node = list->nodes->prev;
  189. FT_ASSERT( node );
  190. if ( list->clazz.node_reset )
  191. {
  192. FTC_MruNode_Up( &list->nodes, node );
  193. error = list->clazz.node_reset( node, key, list->data );
  194. if ( !error )
  195. goto Exit;
  196. }
  197. FTC_MruNode_Remove( &list->nodes, node );
  198. list->num_nodes--;
  199. if ( list->clazz.node_done )
  200. list->clazz.node_done( node, list->data );
  201. }
  202. else if ( FT_ALLOC( node, list->clazz.node_size ) )
  203. goto Exit;
  204. error = list->clazz.node_init( node, key, list->data );
  205. if ( error )
  206. goto Fail;
  207. FTC_MruNode_Prepend( &list->nodes, node );
  208. list->num_nodes++;
  209. Exit:
  210. *anode = node;
  211. return error;
  212. Fail:
  213. if ( list->clazz.node_done )
  214. list->clazz.node_done( node, list->data );
  215. FT_FREE( node );
  216. goto Exit;
  217. }
  218. #ifndef FTC_INLINE
  219. FT_LOCAL_DEF( FT_Error )
  220. FTC_MruList_Lookup( FTC_MruList list,
  221. FT_Pointer key,
  222. FTC_MruNode *anode )
  223. {
  224. FTC_MruNode node;
  225. node = FTC_MruList_Find( list, key );
  226. if ( node == NULL )
  227. return FTC_MruList_New( list, key, anode );
  228. *anode = node;
  229. return 0;
  230. }
  231. #endif /* FTC_INLINE */
  232. FT_LOCAL_DEF( void )
  233. FTC_MruList_Remove( FTC_MruList list,
  234. FTC_MruNode node )
  235. {
  236. FTC_MruNode_Remove( &list->nodes, node );
  237. list->num_nodes--;
  238. {
  239. FT_Memory memory = list->memory;
  240. if ( list->clazz.node_done )
  241. list->clazz.node_done( node, list->data );
  242. FT_FREE( node );
  243. }
  244. }
  245. FT_LOCAL_DEF( void )
  246. FTC_MruList_RemoveSelection( FTC_MruList list,
  247. FTC_MruNode_CompareFunc selection,
  248. FT_Pointer key )
  249. {
  250. FTC_MruNode first, node, next;
  251. first = list->nodes;
  252. while ( first && ( selection == NULL || selection( first, key ) ) )
  253. {
  254. FTC_MruList_Remove( list, first );
  255. first = list->nodes;
  256. }
  257. if ( first )
  258. {
  259. node = first->next;
  260. while ( node != first )
  261. {
  262. next = node->next;
  263. if ( selection( node, key ) )
  264. FTC_MruList_Remove( list, node );
  265. node = next;
  266. }
  267. }
  268. }
  269. /* END */