1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 #include <dxconfig.h>
10 
11 
12 
13 #include <string.h>
14 #include "arrayClass.h"
15 
16 static int IsConstantArray(Array a);
17 
18 static ConstantArray
_NewConstantArray(int n,Pointer d,Type t,Category c,int r,int * s,struct constantarray_class * class)19 _NewConstantArray(int n, Pointer d, Type t, Category c, int r, int *s,
20 		 struct constantarray_class *class)
21 {
22     ConstantArray a = (ConstantArray) _dxf_NewArrayV(t, c, r, s,
23 				      (struct array_class *)class);
24     if (!a)
25 	return NULL;
26 
27     /* copy info */
28     a->array.items = n;
29     if (a->array.size <= sizeof(a->array.ldata)) {
30 	a->data = (Pointer)a->array.ldata;
31     } else {
32 	a->data = DXAllocate(a->array.size);
33 	if (!a->data)
34 	    return NULL;
35     }
36     memcpy(a->data, d, a->array.size);
37 
38     return a;
39 }
40 
41 ConstantArray
DXNewConstantArray(int n,Pointer d,Type t,Category c,int r,...)42 DXNewConstantArray(int n, Pointer d, Type t, Category c, int r, ...)
43 {
44     int shape[100];
45     int i;
46     va_list arg;
47 
48     ASSERT(r < 100);
49 
50     /* collect args */
51     va_start(arg,r);
52     for (i=0; i<r; i++)
53 	shape[i] = va_arg(arg, int);
54     va_end(arg);
55 
56     return _NewConstantArray(n, d, t, c, r, shape, &_dxdconstantarray_class);
57 }
58 
59 ConstantArray
DXNewConstantArrayV(int n,Pointer d,Type t,Category c,int r,int * s)60 DXNewConstantArrayV(int n, Pointer d, Type t, Category c, int r, int *s)
61 {
62     return _NewConstantArray(n, d, t, c, r, s, &_dxdconstantarray_class);
63 }
64 
65 Array
DXQueryConstantArray(Array a,int * n,Pointer d)66 DXQueryConstantArray(Array a, int *n, Pointer d)
67 {
68     CHECK(a, CLASS_ARRAY);   /* can be either REGULAR or CONSTANT */
69 
70     if (! IsConstantArray(a))
71         return NULL;
72 
73     if (d)
74     {
75 	if (DXGetArrayClass((Array)a) == CLASS_CONSTANTARRAY)
76 	    memcpy(d, ((ConstantArray)a)->data, a->size);
77 	else
78 	    memcpy(d, ((RegularArray)a)->origin, a->size);
79     }
80 
81     if (n)
82 	*n = a->items;
83 
84     return a;
85 }
86 
87 Pointer
DXGetConstantArrayData(Array a)88 DXGetConstantArrayData(Array a)
89 {
90     CHECK(a, CLASS_ARRAY);   /* can be either REGULAR or CONSTANT */
91 
92     if (! IsConstantArray(a))
93     {
94 	DXSetError(ERROR_BAD_PARAMETER, "object not constant array");
95         return NULL;
96     }
97 
98     if (DXGetArrayClass(a) == CLASS_CONSTANTARRAY)
99 	return ((ConstantArray)a)->data;
100     else
101 	return ((RegularArray)a)->origin;
102 }
103 
104 
105 Pointer
_dxfConstantArray_GetArrayData(ConstantArray a)106 _dxfConstantArray_GetArrayData(ConstantArray a)
107 {
108     int size = a->array.size;
109     int items = a->array.items;
110     int i;
111     byte *src = NULL, *dst = NULL, *d;
112 
113     /* DXlock array */
114     EXPAND_LOCK(a);
115 
116     dst = (byte *)DXAllocate(size*items);
117     src = (byte *)DXAllocate(size);
118     if (! dst || ! src)
119 	goto error;
120 
121     memcpy(src, a->data, size);
122 
123     for (i = 0, d = dst; i < items; i++, d += size)
124 	memcpy(d, src, size);
125 
126     DXFree((Pointer)src);
127 
128     EXPAND_RETURN(a, dst);
129 
130 error:
131     DXFree((Pointer)dst);
132     DXFree((Pointer)src);
133     EXPAND_ERROR(a);
134 }
135 
136 
137 #define CONSTANT_REGULAR(t, cst)				\
138 {								\
139     t *ptr = (t *)((RegularArray)a)->delta;			\
140     int  i, knt = a->size / DXTypeSize(a->type);			\
141     for (i = 0, cst = 1; i < knt && cst; i++, ptr++)		\
142 	if (*ptr != 0) cst = 0;					\
143 }
144 
145 static int
IsConstantArray(Array a)146 IsConstantArray(Array a)
147 {
148     if (DXGetArrayClass(a) == CLASS_CONSTANTARRAY)
149 	return 1;
150     else if (DXGetArrayClass(a) == CLASS_REGULARARRAY)
151     {
152 	int cst=0;
153 	switch(a->type)
154 	{
155 	    case TYPE_DOUBLE: CONSTANT_REGULAR(double, cst); break;
156 	    case TYPE_FLOAT:  CONSTANT_REGULAR(float,  cst); break;
157 	    case TYPE_INT:    CONSTANT_REGULAR(int,    cst); break;
158 	    case TYPE_UINT:   CONSTANT_REGULAR(uint,   cst); break;
159 	    case TYPE_SHORT:  CONSTANT_REGULAR(short,  cst); break;
160 	    case TYPE_USHORT: CONSTANT_REGULAR(ushort, cst); break;
161 	    case TYPE_BYTE:   CONSTANT_REGULAR(byte,   cst); break;
162 	    case TYPE_UBYTE:  CONSTANT_REGULAR(ubyte,  cst); break;
163 		case TYPE_HYPER: case TYPE_STRING: break;
164 	}
165 	return cst;
166     }
167     else
168 	return 0;
169 }
170