Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

255 lines
9.9 KiB

  1. /* @(#)CM_VerSion xcf_da.h atm08 1.3 16343.eco sum= 37189 atm08.005 */
  2. /***********************************************************************/
  3. /* */
  4. /* Copyright 1990-1994 Adobe Systems Incorporated. */
  5. /* All rights reserved. */
  6. /* */
  7. /* Patents Pending */
  8. /* */
  9. /* NOTICE: All information contained herein is the property of Adobe */
  10. /* Systems Incorporated. Many of the intellectual and technical */
  11. /* concepts contained herein are proprietary to Adobe, are protected */
  12. /* as trade secrets, and are made available only to Adobe licensees */
  13. /* for their internal use. Any reproduction or dissemination of this */
  14. /* software is strictly forbidden unless prior written permission is */
  15. /* obtained from Adobe. */
  16. /* */
  17. /* PostScript and Display PostScript are trademarks of Adobe Systems */
  18. /* Incorporated or its subsidiaries and may be registered in certain */
  19. /* jurisdictions. */
  20. /* */
  21. /***********************************************************************
  22. * SCCS Id: %W%
  23. * Changed: %G% %U%
  24. ***********************************************************************/
  25. /* This code was taken from Jerry Hall by John Felton on 3/26/96 */
  26. #ifndef XCF_DA_H
  27. #define XCF_DA_H
  28. #include "xcf_base.h"
  29. #include "xcf_pub.h"
  30. /* Dynamic array support.
  31. Overview
  32. ========
  33. The da (dynamic array) library provides simple and flexible support for
  34. homogeneous arrays that automatically grow to accomodate new elements. da's are
  35. particularly useful in situations where the size of the array isn't known at
  36. compile or run time until the last element has been stored and no suitable
  37. default size can be determined. Such situations occur, for example, when data
  38. is being read from a file and loaded into an array. In order to use a da object
  39. a client program must perform 4 steps:
  40. 1. Initialize the da module.
  41. 2. Declare and initialize a da object.
  42. 3. Add data to the da object via one of the access macros.
  43. 4. Use the data in the da object.
  44. Each of these steps is described in more detail in the following sections.
  45. The da object
  46. =============
  47. A da is implemented as a C stucture that contains a pointer to a dynamically
  48. allocated array and a few fields to control (re)allocation, and optional
  49. initialization, of elements of that array.
  50. struct
  51. {
  52. <type> *array;
  53. long cnt;
  54. unsigned long size;
  55. unsigned long incr;
  56. int (*init)(<type> *element);
  57. } <name>;
  58. Field Description
  59. ----- -----------
  60. <type> *array This is a pointer to the first element of a
  61. dynamically allocated array. Each element has
  62. type <type> which may be any C data type.
  63. long cnt This is a count of the number of elements of
  64. the array that are in use which is also the
  65. index of the next free element of the array.
  66. unsigned long size This is the total number of elements available
  67. in the array.
  68. unsigned long incr This is the number of elements by which the
  69. array grows in order to accomodate a new index.
  70. int (*init)(<type> *element) This is the address of a client-supplied
  71. function that initializes new elements of the
  72. array.
  73. [Note: <name> and <type> are supplied by the client program via declaration
  74. macros.]
  75. Library Initialization
  76. ======================
  77. The da library must be initialized with the addresses of the client's memory
  78. memory management functions before any da is accessed. Initialization is simply
  79. achieved by calling da_SetMemFuncs() before the first use of the da library.
  80. The client functions must have the following prototypes:
  81. void *(*alloc)(size_t size);
  82. void *(*resize)(void *old, size_t size);
  83. void (*dealloc)(void *ptr));
  84. The prototypes of these functions are identical to the standard C library
  85. functions: malloc, realloc, and free. The client-provided functions must handle
  86. out-of-memory errors either by exiting the program or longjumping to a special
  87. handler. Failure to take these precautions will cause a fatal error to occur in
  88. the da access functions after memory is exhausted. If the standard C library
  89. functions are used they should be wrapped with code that handles the
  90. out-of-memory errors.
  91. Declaration
  92. ===========
  93. A da may be declared with one of 2 declaration macros:
  94. da_DCL(<type>, <name>);
  95. da_DCLI(<type>, <name>, <initial>, <increment>);
  96. where:
  97. <type> is the array element type.
  98. <name> is the da object name.
  99. <initial> is the number of array elements initially allocated.
  100. <increment> is the number of elements by which the array subsequently
  101. grows.
  102. The first form simply declares the da object without initialization (which
  103. must be performed subsequently). The second form declares the da object and
  104. initializes it using an agregate initializer. The first form is used when the
  105. da object is a field in another structure and can't be initialized with an
  106. agregate initializer. The second form is used when the da object is a global or
  107. automatic variable and is preferred over the other form when circumstances
  108. permit.
  109. Object Initialization
  110. =====================
  111. As mentioned above it is preferable to use the da_DCLI macro to initialize the
  112. da object where permitted. When circumstances force the use of the da_DCL macro
  113. you must explicitly initialize the da object before it's used. This is achieved
  114. by calling either of the following macros:
  115. da_INIT(<name>, <initial>, <increment>);
  116. da_INIT_ONCE(<name>, <initial>, <increment>);
  117. where:
  118. <name> is the da object name.
  119. <initial> is the number of array elements initially allocated.
  120. <increment> is the number of elements by which the array subsequently
  121. grows.
  122. The first form is used in situations where the macro is only executed once. The
  123. second form is used in situations where the macro may be executed more than
  124. once but initization is performed during the first call only. Such situations
  125. occur when clients may be reusing a da but don't want to separate the
  126. initialization from the reuse.
  127. cnt initialization, init initialization
  128. Access
  129. ======
  130. Once a da has be declared and initialized it may be accessed so that elements
  131. of the underlying array can be loaded. This is accomplished by using the
  132. following macros:
  133. da_GROW(<name>, <index>);
  134. da_INDEX(<name>, <index>);
  135. da_NEXT(<name>);
  136. da_EXTEND(<name>, <length>);
  137. The first two forms specify access to an explict <index>. The last two forms
  138. specify access to an implicit index which is the next free element of the array
  139. given by the da object's cnt field. In all cases if the index is greater than
  140. or equal to the size of the array the da_Grow() function is called to grow the
  141. array enough to accomodate the new index.
  142. [This needs finishing--JH]
  143. */
  144. /* Functions:
  145. *
  146. * da_Init Only call via da_INIT or da_INIT_ONCE
  147. * da_Grow Only call via da_GROW, da_INDEX, or da_NEXT
  148. * da_Free Only call via da_FREE
  149. * da_SetMemFuncs Set memory management functions (initializes da module)
  150. */
  151. typedef unsigned long int (*AllocFunc) (void PTR_PREFIX * PTR_PREFIX *ppBlock,
  152. unsigned long int size, void PTR_PREFIX
  153. *clientHook);
  154. #ifdef __cplusplus
  155. extern "C" {
  156. #endif
  157. extern void xcf_da_Init (void PTR_PREFIX *object, ULONG_PTR intl, unsigned long incr, AllocFunc alloc, void PTR_PREFIX *clientHook);
  158. extern void xcf_da_Grow(void PTR_PREFIX *object, size_t element, unsigned long index);
  159. extern void xcf_da_Free(void PTR_PREFIX *object);
  160. #ifdef __cplusplus
  161. }
  162. #endif
  163. /* Creation/destruction:
  164. *
  165. * da_DCL Declare da object (initialize with da_INIT or da_INIT_ONCE)
  166. * da_DCLI Declare and initialize da object
  167. * da_FREE Free array
  168. */
  169. #define da_DCL(type,da) \
  170. struct \
  171. { \
  172. type PTR_PREFIX *array; \
  173. unsigned long cnt; \
  174. unsigned long size; \
  175. unsigned long incr; \
  176. int (* init)(type PTR_PREFIX *element); \
  177. AllocFunc alloc; \
  178. void PTR_PREFIX *hook; \
  179. } da
  180. #define da_DCLI(type,da,intl,incr) da_DCL(type,da)={(type PTR_PREFIX *)intl,0,0,incr,NULL}
  181. #define da_FREE(da) xcf_da_Free(&(da))
  182. /* Initialization:
  183. *
  184. * da_INIT Unconditional initialization
  185. * da_INIT_ONCE Conditional initialization
  186. */
  187. #define da_INIT(da,intl,incr,alloc,hook) xcf_da_Init((void PTR_PREFIX *)(&(da)),intl,incr,alloc,hook)
  188. #define da_INIT_ONCE(da,intl,incr,alloc,hook) \
  189. do{if((da).size==0)xcf_da_Init((void PTR_PREFIX *)(&(da)),intl,incr,alloc,hook);}while(0)
  190. /* Access:
  191. *
  192. * da_GROW Grow da enough to accommodate index and return array
  193. * da_INDEX Grow da, return pointer to indexed element
  194. * da_NEXT Grow da, return pointer to next element and bump count
  195. * da_EXTEND Grow da, return pointer to next element and extend count
  196. */
  197. #define da_GROW(da,inx) ((inx)>=(da).size? \
  198. (xcf_da_Grow((void PTR_PREFIX *)(&(da)),sizeof((da).array[0]),inx), \
  199. (da).array):(da).array)
  200. #define da_INDEX(da,inx) (&da_GROW(da,inx)[inx])
  201. #define da_INDEXI(da,inx) \
  202. (&da_GROW(da,inx)[((da).cnt=(((inx)>(da).cnt)?(inx):(da).cnt),(inx))])
  203. #define da_NEXT(da) (((da).cnt)>=(da).size? \
  204. (xcf_da_Grow((void PTR_PREFIX *)(&(da)),sizeof((da).array[0]),(da).cnt),\
  205. &(da).array[(da).cnt++]):&(da).array[(da).cnt++])
  206. #define da_EXTEND(da,len) (((da).cnt+(len)-1)>=(da).size? \
  207. (xcf_da_Grow((void PTR_PREFIX *)(&(da)),sizeof((da).array[0]),(da).cnt+(len)-1), \
  208. &(da).array[(da).cnt+=(len),(da).cnt-(len)]): \
  209. &(da).array[(da).cnt+=(len),(da).cnt-(len)])
  210. #endif /* XCF_DA_H */