Array.h
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:12k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: Array.h,v 1.1.1.1 2005/11/11 21:32:03 faxguy Exp $ */
  2. /*
  3.  * Copyright (c) 1990-1996 Sam Leffler
  4.  * Copyright (c) 1991-1996 Silicon Graphics, Inc.
  5.  * HylaFAX is a trademark of Silicon Graphics
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26. #ifndef _Array_
  27. #define _Array_
  28. #include <stdlib.h>
  29. #include "Obj.h"
  30. #include "Ptr.h"
  31. // Here's what the declaration of an array class looks like to the user:
  32. /*
  33. class ARRAY<ITEM> : public fxArray {
  34. public:
  35.     ARRAY();
  36.     ARRAY(u_int size);
  37.     ARRAY(ARRAY const &);
  38.     ARRAY& operator=(ARRAY const &);
  39.     ITEM & operator[](u_int index) const;
  40.     u_int length() const;
  41.     void append(ITEM const & item);
  42.     void append(ARRAY const & a);
  43.     void remove(u_int start, u_int leng=1);
  44.     ARRAY cut(u_int start, u_int leng=1);
  45.     void insert(ITEM const & item, u_int p);
  46.     void insert(ARRAY const & a, u_int posn);
  47.     void resize(u_int length);
  48.     ARRAY extract(u_int start, u_int len);
  49.     void head(u_int len);
  50.     void tail(u_int len);
  51.     u_int find(ITEM const & item) const;
  52.     void qsort(u_int start, u_int len);
  53.     void swap(u_int,u_int);
  54. protected:
  55.     virtual void getmem();
  56.     virtual void expand();
  57.     virtual void createElements(void*, u_int numbytes);
  58.     virtual void destroyElements(void*, u_int numbytes);
  59.     virtual void copyElements(void const *src, void *dst, u_int numbytes);
  60.     virtual int compareElements(void const *elem1, void const *elem2);
  61. };
  62. */
  63. //
  64. // There are three flavors of arrays:
  65. //   struct Arrays (in which the contents of the elements are not looked at)
  66. //   pointer Arrays (the elements are pointers to some memory)
  67. //   object Arrays (the elements are objects, which must be constructed and
  68. // destructed)
  69. //
  70. // Macros exist for each of these fxArray flavors:
  71. //   fxDECLARE_Array (same as fxDECLARE_StructArray)
  72. //   fxDECLARE_PtrArray
  73. //      (acts like fxDECLARE_Array, except that pointers are
  74. //       initialized to nil when new elements are added)
  75. //   fxDECLARE_ObjArray
  76. static const u_int fx_invalidArrayIndex = (u_int) -1;
  77. class fxArray : public fxObj {
  78. public:
  79.     u_int length() const;
  80.     u_int elementSize() const
  81. { return elementsize; }
  82.     void resize(u_int length);
  83.     void setMaxLength(u_int maxlength);
  84.     void qsort(u_int posn, u_int len);
  85.     void qsort();
  86.     void swap(u_int,u_int);
  87.     virtual char const *className() const = 0;
  88. protected:
  89.     class fxAddress {
  90.     public:
  91. fxAddress() { ptr = 0; }
  92. fxAddress(void* p) { ptr = (char*) p; }
  93. fxAddress operator+(u_long offset) const { return ptr + offset; }
  94. bool operator==(const fxAddress& r) const { return ptr == r.ptr; }
  95. bool operator!=(const fxAddress& r) const { return ptr != r.ptr; }
  96. // NB: operator const void*() const does not work
  97. operator void*() const { return ptr; }
  98.     protected:
  99. char* ptr;
  100.     };
  101.     fxArray(u_short esize, u_int initlength=0);
  102.     fxArray(u_int esize, u_int num, void *data);
  103.     fxArray(fxArray const &);
  104.     virtual ~fxArray();
  105.     void * operator[](u_int index) { return data + elementsize*index; }
  106.     fxArray& operator=(fxArray const &);
  107.     void append(void const *item);
  108.     void append(fxArray const &);
  109.     void remove(u_int start, u_int length=1);
  110.     void insert(fxArray const &, u_int posn);
  111.     void insert(void const *item, u_int posn);
  112.     u_int find(void const *, u_int start=0) const;
  113. // The objects in the array are stored sequentially at the
  114. // location pointed to by data. The length of the known
  115. // allocated segment is stored in maxi, in bytes. The
  116. // length of the array is stored in num, in *bytes*. The
  117. // size of an array element is stored in elementsize, in bytes.
  118. // data is allowed to be nil iff (maxi==0)
  119.     fxAddress data;
  120. // num <= maxi
  121.     u_int maxi,num;
  122.     u_short elementsize;
  123. // These two methods control how the array class goes to
  124. // fetch more memory.
  125.     virtual void getmem();
  126.     virtual void expand();
  127. // The raw methods are used to
  128. // implement methods which return an fxArray type.
  129.     void * raw_copy() const;
  130.     void * raw_extract(u_int start, u_int length) const;
  131.     void * raw_cut(u_int start, u_int length);
  132.     void * raw_head(u_int) const;
  133.     void * raw_tail(u_int) const;
  134.     void qsortInternal(u_int, u_int, void *);
  135.     void destroy();
  136. // These three methods can be overridden to properly copy, delete,
  137. // and create new array elements in the desired manner. By default
  138. // `create' and `destroy' do nothing, and `copy' is a simple bcopy.
  139. //
  140. // The job of create is to take an area of uninitialized memory and
  141. // create a series of valid objects in it. The job of destroy is to
  142. // take a series of valid objects and destroy any resources they
  143. // consume. The status of the memory after the destroy is irrelevant.
  144. // The job of copy is to take a source array of objects, and copy
  145. // them to an area of *uninitialized* memory. There will not be any
  146. // objects stored there previous to the copy.
  147.     virtual void createElements(void *, u_int numbytes);
  148.     virtual void destroyElements(void *, u_int numbytes);
  149.     virtual void copyElements(void const *src, void *dst, u_int numbytes)
  150. const;
  151.     virtual int compareElements(void const *, void const *) const;
  152. };
  153. #define fxArrayHeader(ARRAY,ITEM)
  154.     ARRAY();
  155.     ARRAY(u_int size);
  156.     ARRAY(ARRAY const&a);
  157.     ~ARRAY();
  158.     virtual const char* className() const;
  159.     ARRAY& operator=(ARRAY const& a) {
  160.         maxi = a.maxi; num = a.num; if (data) free(data);
  161.         data = memmove(malloc(num), a.data, num); return (*this);}
  162.     ITEM & operator[](u_int index) {
  163.       fxAssert(index*sizeof(ITEM) < num, "Invalid Array[] index");
  164.       return *(ITEM *)((char *)((void *)data) + index*sizeof(ITEM));
  165.     }
  166.     const ITEM & operator[](u_int index) const {
  167.       fxAssert(index*sizeof(ITEM) < num, "Invalid Array[] index");
  168.       return *(const ITEM *)((char *)((void *)data) + index*sizeof(ITEM));
  169.     }
  170.     void append(ITEM const & item) { fxArray::append(&item); }
  171.     void append(ARRAY const & a) { fxArray::append(a); }
  172.     void remove(u_int start, u_int length=1)
  173. { fxArray::remove(start,length); }
  174.     ARRAY cut(u_int start, u_int len = 1);
  175.     void insert(ARRAY const & a, u_int p)
  176. { fxArray::insert(a,p); }
  177.     void insert(ITEM const & item, u_int p)
  178. { fxArray::insert(&item,p);}
  179.     ARRAY extract(u_int start, u_int len);
  180.     ARRAY head(u_int len = 1);
  181.     ARRAY tail(u_int len = 1);
  182.     int find(ITEM const& x, u_int start=0) const {
  183. return fxArray::find(&x,start);
  184.     }
  185. protected:
  186.     ARRAY(u_int esize, u_int num, void *data);
  187. public:
  188. __enddef__
  189. #define fxArrayVirtuals
  190. protected:
  191.     virtual void createElements(void *,u_int);
  192.     virtual void destroyElements(void *,u_int);
  193.     virtual void copyElements(void const*,void*,u_int) const;
  194.     virtual int compareElements(void const *, void const *) const;  
  195. __enddef__
  196. //----------------------------------------------------------------------
  197. // Declare an array containing items of type ITEM.
  198. #define fxDECLARE_Array(ARRAY,ITEM)
  199. class ARRAY : public fxArray {
  200. public:
  201.     fxArrayHeader(ARRAY,ITEM)
  202. };
  203. fxDECLARE_Ptr(ARRAY);
  204. __enddef__
  205. #define fxDECLARE_StructArray(ARRAY,ITEM) fxDECLARE_Array(ARRAY,ITEM)
  206. #define fxDECLARE_PrimArray(ARRAY,ITEM) fxDECLARE_Array(ARRAY,ITEM)
  207. #define fxDECLARE_ObjArray(ARRAY,ITEM)
  208. class ARRAY : public fxArray {
  209. public:
  210.     fxArrayHeader(ARRAY,ITEM)
  211.     fxArrayVirtuals
  212. };
  213. fxDECLARE_Ptr(ARRAY);
  214. __enddef__
  215. #define fxDECLARE_PtrArray(ARRAY, POINTER)
  216. class ARRAY : public fxArray {
  217. public:
  218.     fxArrayHeader(ARRAY,POINTER)
  219. protected:
  220.     virtual void createElements(void *, u_int);
  221. };
  222. fxDECLARE_Ptr(ARRAY);
  223. __enddef__
  224. //----------------------------------------------------------------------
  225. // Various method implementations
  226. #define fxIMPLEMENT_ArrayMethods(ARRAY,ITEM)
  227.     ARRAY::ARRAY() : fxArray(sizeof(ITEM))
  228. { if (data) createElements(data,num); }
  229.     ARRAY::ARRAY(ARRAY const& a) : fxArray(a.elementsize) 
  230. { maxi = a.maxi; num = a.num; data = a.raw_copy(); }
  231.     ARRAY::ARRAY(u_int size) : fxArray(sizeof(ITEM),size)
  232. { createElements(data,num); }
  233.     ARRAY::~ARRAY() { destroy(); }
  234.     const char* ARRAY::className() const { return fxQUOTE(ARRAY); }
  235.     ARRAY ARRAY::cut(u_int start, u_int len)
  236. {return ARRAY(sizeof(ITEM), len*sizeof(ITEM),raw_cut(start,len));}
  237.     ARRAY ARRAY::extract(u_int start, u_int len)
  238. {return ARRAY(sizeof(ITEM), len*sizeof(ITEM),raw_extract(start,len));}
  239.     ARRAY ARRAY::head(u_int len)
  240. {return ARRAY(sizeof(ITEM), len*sizeof(ITEM),raw_head(len));}   
  241.     ARRAY ARRAY::tail(u_int len)
  242.         {return ARRAY(sizeof(ITEM),len*sizeof(ITEM),raw_tail(len));}    
  243.     ARRAY::ARRAY(u_int esize, u_int num, void * data)         
  244. : fxArray(esize,num,data) {}
  245. __enddef__
  246. #define fxIMPLEMENT_ObjArrayMethods(ARRAY,ITEM)
  247.     void ARRAY::createElements(void * start, u_int numbytes) {
  248. ITEM * ptr = (ITEM *)start;
  249. for (;;) {
  250.     if (numbytes == 0) break;
  251.     numbytes -= elementsize;
  252.     ITEM * obj = new(ptr) ITEM;
  253.     ptr++; 
  254.     (void) obj;
  255. }
  256.     }
  257.     void ARRAY::destroyElements(void * start, u_int numbytes) {
  258. ITEM * ptr = (ITEM *)start;
  259. while (numbytes) {
  260.     numbytes -= elementsize;
  261.     ptr->ITEM::~ITEM();
  262.     ptr++;
  263. }
  264.     }
  265.     void ARRAY::copyElements(void const * src, void * dst,
  266.     u_int numbytes) const {
  267. if (src<dst) {
  268.     src = (const char*)src + numbytes;
  269.     dst = (char*)dst + numbytes;
  270.     const ITEM * p = (const ITEM *)src - 1;
  271.     ITEM * q = (ITEM *)dst - 1;
  272.     while (numbytes > 0) {
  273. ITEM * obj = new(q) ITEM(*p);
  274. q--; p--;
  275. numbytes -= elementsize;
  276. (void) obj;
  277.     }
  278. } else {
  279.     const ITEM * p = (const ITEM *)src;
  280.     ITEM * q = (ITEM *)dst;
  281.     while (numbytes > 0) {
  282. ITEM * obj = new(q) ITEM(*p);
  283. q++; p++;
  284. numbytes -= elementsize;
  285. (void) obj;
  286.     }
  287. }
  288.     }
  289.     int ARRAY::compareElements(void const *o1, void const *o2) const
  290.     {
  291. return ((const ITEM *)o1)->compare((const ITEM *)o2);
  292.     }
  293. __enddef__
  294. #define fxIMPLEMENT_PtrArrayMethods(ARRAY,POINTER)
  295.     void ARRAY::createElements(void * start, u_int numbytes) {
  296. memset(start,0,numbytes);
  297.     }
  298. __enddef__
  299. //----------------------------------------------------------------------
  300. // Implement various types of arrays
  301. #define fxIMPLEMENT_Array(ARRAY,ITEM)
  302.     fxIMPLEMENT_ArrayMethods(ARRAY,ITEM)
  303. __enddef__
  304. #define fxIMPLEMENT_PrimArray(ARRAY,ITEM)
  305.     fxIMPLEMENT_ArrayMethods(ARRAY,ITEM)
  306. __enddef__
  307. #define fxIMPLEMENT_StructArray(ARRAY,ITEM) 
  308.     fxIMPLEMENT_ArrayMethods(ARRAY,ITEM)
  309. __enddef__
  310. #define fxIMPLEMENT_ObjArray(ARRAY,ITEM)
  311.     fxIMPLEMENT_ArrayMethods(ARRAY,ITEM)
  312.     fxIMPLEMENT_ObjArrayMethods(ARRAY,ITEM)
  313. __enddef__
  314. #define fxIMPLEMENT_PtrArray(ARRAY,POINTER)
  315.     fxIMPLEMENT_Array(ARRAY,POINTER)
  316.     fxIMPLEMENT_PtrArrayMethods(ARRAY,POINTER)
  317. __enddef__
  318. #endif /* _ARRAY_ */