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 #include <stdarg.h>
12 #include <string.h>
13 #include "arrayClass.h"
14 
15 /*
16  * size multipliers for type, category
17  */
18 
19 /* XXX */
20 int
DXTypeSize(Type t)21 DXTypeSize(Type t)
22 {
23     switch (t) {
24         case TYPE_BYTE:   return sizeof(byte);
25         case TYPE_UBYTE:  return sizeof(ubyte);
26         case TYPE_SHORT:  return sizeof(short);
27         case TYPE_USHORT: return sizeof(ushort);
28         case TYPE_INT:    return sizeof(int);
29         case TYPE_UINT:   return sizeof(uint);
30         case TYPE_HYPER:  return 8;
31         case TYPE_FLOAT:  return sizeof(float);
32         case TYPE_DOUBLE: return sizeof(double);
33         case TYPE_STRING: return sizeof(char);
34         default:
35 	    return DXSetError(ERROR_BAD_PARAMETER, "unknown Type %d", t);
36     }
37 }
38 
39 int
DXCategorySize(Category category)40 DXCategorySize(Category category)
41 {
42     switch(category) {
43         case CATEGORY_REAL:       return 1;
44         case CATEGORY_COMPLEX:    return 2;
45         case CATEGORY_QUATERNION: return 4;
46         default:
47 	    return DXSetError(ERROR_BAD_PARAMETER,
48 			    "unknown Category %d", category);
49     }
50 }
51 
52 
53 /*
54  * new array, shape specified as a vector
55  */
56 
57 Array
_dxf_NewArrayV(Type type,Category category,int rank,int * shape,struct array_class * class)58 _dxf_NewArrayV(Type type, Category category, int rank, int *shape,
59 	   struct array_class *class)
60 {
61     int i;
62     Array a = (Array) _dxf_NewObject((struct object_class *)class);
63     if (!a)
64 	return NULL;
65 
66     /* specified info */
67     a->type = type;
68     a->category = category;
69     a->rank = rank;
70     if (shape && rank!=0) {
71 	a->shape = rank>NLSHAPE?
72 	    (int*)DXAllocate(rank*sizeof(*shape)) : a->lshape;
73 	if (!a->shape)
74 	    return NULL;
75 	for (i=0; i<rank; i++)
76 	    a->shape[i] = shape[i];
77     } else if (rank != 0) {
78 	DXSetError(ERROR_BAD_PARAMETER,
79 		 "rank=%d but shape was not specified in DXNewArray", rank);
80 	return NULL;
81     } else
82 	a->shape = NULL;
83 
84     /* size is derived */
85     a->size = DXTypeSize(type) * DXCategorySize(category);
86     if (!a->size)
87 	return NULL;
88     for (i=0; i<rank; i++)
89 	a->size *= shape[i];
90     if (!a->size)
91 	DXErrorReturn(ERROR_BAD_PARAMETER, "extent specified as 0 in DXNewArray");
92     a->items = 0;
93     a->data = NULL;
94     DXcreate_lock(&a->inprogress, "in progress");
95 
96     return a;
97 }
98 
99 
100 Array
DXNewArrayV(Type type,Category category,int rank,int * shape)101 DXNewArrayV(Type type, Category category, int rank, int *shape)
102 {
103     return _dxf_NewArrayV(type, category, rank, shape, &_dxdarray_class);
104 }
105 
106 
107 Array
DXNewArray(Type type,Category category,int rank,...)108 DXNewArray(Type type, Category category, int rank, ...)
109 {
110     int shape[100];
111     int i;
112     va_list arg;
113 
114     ASSERT(rank<100);
115 
116     /* collect args */
117     va_start(arg,rank);
118     for (i=0; i<rank; i++)
119 	shape[i] = va_arg(arg, int);
120     va_end(arg);
121 
122     /* call V version */
123     return DXNewArrayV(type, category, rank, shape);
124 }
125 
126 
127 Array
DXGetArrayInfo(Array a,int * items,Type * type,Category * category,int * rank,int * shape)128 DXGetArrayInfo(Array a, int *items, Type *type, Category *category,
129 	     int *rank, int *shape)
130 {
131     int i;
132 
133     CHECK(a, CLASS_ARRAY);
134 
135     if (items)
136 	*items = a->items;
137     if (type)
138 	*type = a->type;
139     if (category)
140 	*category = a->category;
141     if (rank)
142 	*rank = a->rank;
143     if (shape)
144 	for (i=0; i<a->rank; i++)
145 	    shape[i] = a->shape[i];
146 
147     return a;
148 }
149 
150 
151 Object
_dxfArray_GetType(Array a,Type * t,Category * c,int * rank,int * shape)152 _dxfArray_GetType(Array a, Type *t, Category *c, int *rank, int *shape)
153 {
154     int i;
155 
156     if (t)
157 	*t = a->type;
158     if (c)
159 	*c = a->category;
160     if (rank)
161 	*rank = a->rank;
162     if (shape)
163 	for (i=0; i<a->rank; i++)
164 	    shape[i] = a->shape[i];
165 
166     return (Object) a;
167 }
168 
169 
DXGetItemSize(Array a)170 int DXGetItemSize(Array a)
171 {
172     CHECK(a, CLASS_ARRAY);
173     return a->size;
174 }
175 
176 
177 Array
DXTypeCheckV(Array a,Type type,Category category,int rank,int * shape)178 DXTypeCheckV(Array a, Type type, Category category, int rank, int *shape)
179 {
180     Type t;
181     Category c;
182     int i, r, s[100];
183 
184     ASSERT(rank<100);
185 
186     if (!DXGetArrayInfo(a, NULL, &t, &c, &r, NULL))
187 	return NULL;
188     if (t!=type || c!=category || r!=rank)
189 	return NULL;
190 
191     if (!DXGetArrayInfo(a, NULL, NULL, NULL, NULL, s))
192 	return NULL;
193     if (shape)
194 	for (i=0; i<rank; i++)
195 	    if (s[i]!=shape[i])
196 		return NULL;
197 
198     return a;
199 }
200 
201 
202 Array
DXTypeCheck(Array a,Type type,Category category,int rank,...)203 DXTypeCheck(Array a, Type type, Category category, int rank, ...)
204 {
205     int shape[100];
206     int i;
207     va_list arg;
208 
209     ASSERT(rank<100);
210 
211     /* collect args */
212     va_start(arg,rank);
213     for (i=0; i<rank; i++)
214 	shape[i] = va_arg(arg, int);
215     va_end(arg);
216 
217     /* call V version */
218     return DXTypeCheckV(a, type, category, rank, shape);
219 }
220 
221 
222 Pointer
_dxfArray_GetArrayData(Array a)223 _dxfArray_GetArrayData(Array a)
224 {
225     CHECK(a, CLASS_ARRAY);
226 
227     /* always return something */
228     if (!a->data)
229 	DXAllocateArray(a, 0);
230 
231     return a->data;
232 }
233 
234 
235 
236 Pointer
DXGetArrayDataLocal(Array a)237 DXGetArrayDataLocal(Array a)
238 {
239 	Pointer data;
240 
241 	CHECK(a, CLASS_ARRAY);
242 	data = DXGetArrayData(a);
243 #if DXD_HAS_LOCAL_MEMORY
244 	{
245 		int n;
246 		Pointer local;
247 		if (!data)
248 			return NULL;
249 		/* XXX - copy, record local reference */
250 		n = a->size * a->items;
251 		local = DXAllocateLocal(n);
252 		if (!local) {
253 			DXResetError();
254 			DXWarning("no room for array of %d bytes in local memory", n);
255 			return data;
256 		}
257 		memcpy(local, data, n);
258 		return local;
259 	}
260 #else
261 	return data;
262 #endif
263 }
264 
265 
266 
267 Array
DXFreeArrayDataLocal(Array a,Pointer data)268 DXFreeArrayDataLocal(Array a, Pointer data)
269 {
270     CHECK(a, CLASS_ARRAY);
271 #if DXD_HAS_LOCAL_MEMORY
272     if (data!=a->data)
273 	DXFree(data);
274 #endif
275     return a;
276 }
277 
278 
279 Error
_dxfArray_Delete(Array a)280 _dxfArray_Delete(Array a)
281 {
282     if (a->shape != a->lshape)
283 	DXFree((Pointer)(a->shape));
284     if (a->data != (Pointer)a->ldata)
285 	DXFree((Pointer)(a->data));
286     return OK;
287 }
288 
289 
290 Object
_dxfArray_Copy(Array old,enum _dxd_copy copy)291 _dxfArray_Copy(Array old, enum _dxd_copy copy)
292 {
293     if (copy==COPY_DATA)
294 	DXErrorReturn(ERROR_BAD_PARAMETER, "copying data is not implemented");
295     return (Object)old;
296 }
297 
298 
299 Array
DXAddArrayData(Array a,int start,int n,Pointer data)300 DXAddArrayData(Array a, int start, int n, Pointer data)
301 {
302     CHECKARRAY(a, CLASS_ARRAY);   /* only valid for irregular arrays */
303 
304     /* expand if necessary */
305     /* second test guarantees that we allocate a buffer */
306     if (start+n > a->allocated || a->allocated==0) {
307 	/* allocate 25% extra iff this is a realloc */
308         int alloc = (a->allocated? (start+n)*5/4 : start+n);
309 	if (!DXAllocateArray(a, alloc))
310 	    return NULL;
311     }
312 
313     /* copy the data */
314     if (data)
315 	memcpy((char *)(a->data)+start*a->size, data, n*a->size);
316 
317     /* record the new number of items */
318     if (start+n > a->items)
319 	a->items = start+n;
320 
321     return a;
322 }
323 
324 
325 Array
DXAllocateArray(Array a,int n)326 DXAllocateArray(Array a, int n)
327 {
328     CHECKARRAY(a, CLASS_ARRAY);    /* only valid for irregular arrays */
329 
330     /* second test guarantees something will be allocated even if 0 length */
331     if (n > a->allocated || a->allocated==0) {
332 	int bytes = n * a->size;
333 	Pointer d;
334 	if (bytes > sizeof(a->ldata)) {
335 	    if (a->data == (Pointer)a->ldata) {
336 		d = DXAllocate(bytes);
337 		if (!d)
338 		    return NULL;
339 		memcpy(d, a->ldata, sizeof(a->ldata));
340 	    } else {
341 		d = DXReAllocate(a->data, bytes);
342 		if (!d)
343 		    return NULL;
344 	    }
345 	    a->data = d;
346 	} else
347 	    a->data = (Pointer)a->ldata;
348 	a->allocated = n;
349     }
350     return a;
351 }
352 
353 
354 Array
DXTrim(Array a)355 DXTrim(Array a)
356 {
357 #if 0  /* EndField() calls this on all arrays regardless of type */
358     CHECKARRAY(a, CLASS_ARRAY);   /* only valid for irregular arrays */
359 #else
360     CHECK(a, CLASS_ARRAY);
361 #endif
362 
363     if (a->allocated > a->items) {
364 	if (a->data != (Pointer)a->ldata) {
365 	    Pointer d = DXReAllocate(a->data, a->items*a->size);
366 	    if (!d)   /* realloc shouldn't fail, but just in case ... */
367 		DXErrorReturn(ERROR_UNEXPECTED, "re-alloc failed!");
368 	    a->data = d;
369 	}
370 	a->allocated = a->items;
371     }
372     return a;
373 }
374 
375 /* this might be a useful function to add sometime */
376 Array
DXTrimItems(Array a,int nitems)377 DXTrimItems(Array a, int nitems)
378 {
379     CHECKARRAY(a, CLASS_ARRAY);   /* only valid for irregular arrays */
380 
381     /* reset the item count only if smaller,
382      * and release any extra space in either case.
383      */
384     if (a->items > nitems)
385 	a->items = nitems;
386 
387     return DXTrim(a);
388 }
389 
390 Pointer
DXGetArrayData(Array a)391 DXGetArrayData(Array a)
392 {
393     return _dxfGetArrayData(a);
394 }
395 
396 ArrayHandle
DXCreateArrayHandle(Array array)397 DXCreateArrayHandle(Array array)
398 {
399     ArrayHandle handle = NULL;
400     Array *terms = NULL;
401 
402     handle = (ArrayHandle)DXAllocateZero(sizeof(struct arrayHandle));
403     if (! handle)
404 	goto error;
405 
406     handle->class    = DXGetArrayClass(array);
407     handle->itemSize = DXGetItemSize(array);
408 
409     DXGetArrayInfo(array, &handle->nElements,
410 		&handle->type, &handle->cat, NULL, NULL);
411 
412     handle->nValues = handle->itemSize / DXTypeSize(handle->type);
413 
414     if (array->data)
415     {
416 	handle->data = array->data;
417     }
418     else if (DXQueryConstantArray(array, NULL, NULL))
419     {
420 	handle->cdata = DXAllocate(handle->itemSize);
421 	if (! handle->cdata)
422 	    goto error;
423 
424 	DXQueryConstantArray(array, NULL, handle->cdata);
425     }
426     else
427 	switch(handle->class)
428 	{
429 	    case CLASS_REGULARARRAY:
430 		handle->origin = DXAllocate(handle->itemSize);
431 		handle->delta  = DXAllocate(handle->itemSize);
432 		if (! handle->origin || ! handle->delta)
433 		    goto error;
434 		DXGetRegularArrayInfo((RegularArray)array, NULL,
435 					handle->origin, handle->delta);
436 	    break;
437 
438 	    case CLASS_PATHARRAY:
439 	    break;
440 
441 	    case CLASS_PRODUCTARRAY:
442 	    {
443 		int i;
444 
445 		DXGetProductArrayInfo((ProductArray)array,
446 						&handle->nTerms, NULL);
447 
448 		terms = (Array *)DXAllocate(handle->nTerms * sizeof(Array));
449 
450 		handle->scratch1 = (int *)DXAllocate(handle->itemSize);
451 		handle->scratch2 = (int *)DXAllocate(handle->itemSize);
452 
453 		handle->strides = (int *)
454 			DXAllocateZero(handle->nTerms * sizeof(int));
455 		handle->counts = (int *)
456 			DXAllocateZero(handle->nTerms * sizeof(int));
457 		handle->scratch = (Pointer *)
458 			DXAllocateZero(handle->nTerms * sizeof(Pointer));
459 		handle->handles = (ArrayHandle *)
460 			DXAllocateZero(handle->nTerms * sizeof(ArrayHandle));
461 		handle->indices = (int *)
462 			DXAllocateZero(handle->nTerms * sizeof(int));
463 
464 		if (! handle->strides || ! handle->counts  ||
465 		    ! terms           || ! handle->indices ||
466 		    ! handle->scratch1    || ! handle->scratch2    ||
467 		    ! handle->scratch || ! handle->handles) goto error;
468 
469 		DXGetProductArrayInfo((ProductArray)array, NULL, terms);
470 
471 		for (i = 0; i < handle->nTerms; i++)
472 		{
473 		    handle->handles[i] = DXCreateArrayHandle(terms[i]);
474 		    if (NULL == handle->handles[i])
475 			goto error;
476 
477 		    handle->scratch[i]=DXAllocate(DXGetItemSize(terms[i]));
478 		    if (NULL == handle->scratch)
479 			goto error;
480 
481 		    DXGetArrayInfo(terms[i], &handle->counts[i],
482 						NULL, NULL, NULL, NULL);
483 		}
484 
485 		DXFree((Pointer)terms);
486 
487 		handle->strides[handle->nTerms-1] = 1;
488 		for (i = handle->nTerms-2; i >= 0; i--)
489 		    handle->strides[i] =
490 			    handle->strides[i+1]*handle->counts[i+1];
491 
492 	    }
493 	    break;
494 
495 	    case CLASS_MESHARRAY:
496 	    {
497 		int i;
498 
499 		DXGetMeshArrayInfo((MeshArray)array, &handle->nTerms, NULL);
500 
501 		terms = (Array *)DXAllocate(handle->nTerms * sizeof(Array));
502 
503 		handle->scratch1 = (int *)DXAllocate(handle->itemSize);
504 		handle->scratch2 = (int *)DXAllocate(handle->itemSize);
505 
506 		handle->strides = (int *)
507 			DXAllocateZero(handle->nTerms * sizeof(int));
508 		handle->counts = (int *)
509 			DXAllocateZero(handle->nTerms * sizeof(int));
510 		handle->scratch = (Pointer *)
511 			DXAllocateZero(handle->nTerms * sizeof(Pointer));
512 		handle->handles = (ArrayHandle *)
513 			DXAllocateZero(handle->nTerms * sizeof(ArrayHandle));
514 		handle->indices = (int *)
515 			DXAllocateZero(handle->nTerms * sizeof(int));
516 
517 		if (! handle->strides || ! handle->counts || ! terms ||
518 		    ! handle->scratch1    || ! handle->scratch2   ||
519 		    ! handle->indices ||
520 		    ! handle->scratch || ! handle->handles) goto error;
521 
522 		DXGetMeshArrayInfo((MeshArray)array, NULL, terms);
523 
524 		for (i = 0; i < handle->nTerms; i++)
525 		{
526 		    handle->handles[i] = DXCreateArrayHandle(terms[i]);
527 		    if (NULL == handle->handles[i])
528 			goto error;
529 
530 		    handle->scratch[i]=DXAllocate(DXGetItemSize(terms[i]));
531 		    if (NULL == handle->scratch)
532 			goto error;
533 
534 		    DXGetArrayInfo(terms[i], &handle->counts[i],
535 						NULL, NULL, NULL, NULL);
536 		    handle->counts[i] += 1;
537 		}
538 
539 		DXFree((Pointer)terms);
540 
541 		handle->strides[handle->nTerms-1] = 1;
542 		for (i = handle->nTerms-2; i >= 0; i--)
543 		    handle->strides[i] =
544 			    handle->strides[i+1]*(handle->counts[i+1]-1);
545 
546 	    }
547 	    break;
548 
549 	    default:
550 		handle->data = DXGetArrayData(array);
551 		break;
552 	}
553 
554     return handle;
555 
556 error:
557     DXFreeArrayHandle(handle);
558     DXFree((Pointer)terms);
559     return NULL;
560 }
561 
562 Error
DXFreeArrayHandle(ArrayHandle handle)563 DXFreeArrayHandle(ArrayHandle handle)
564 {
565     int i;
566 
567     if (handle)
568     {
569 	for (i = 0; i < handle->nTerms; i++)
570 	{
571 	    DXFreeArrayHandle(handle->handles[i]);
572 	    DXFree(handle->scratch[i]);
573 	}
574 
575 	DXFree((Pointer)handle->strides);
576 	DXFree((Pointer)handle->counts);
577 	DXFree((Pointer)handle->handles);
578 	DXFree((Pointer)handle->indices);
579 	DXFree((Pointer)handle->scratch);
580 	DXFree((Pointer)handle->scratch1);
581 	DXFree((Pointer)handle->scratch2);
582 	DXFree((Pointer)handle->cdata);
583 	DXFree((Pointer)handle->origin);
584 	DXFree((Pointer)handle->delta);
585 	DXFree((Pointer)handle);
586     }
587 
588     return OK;
589 }
590 
591 #define REGULAR_GETELEMENT(type)					\
592 {									\
593     type *dst = (type *)scratch;					\
594     type *org = (type *)handle->origin;					\
595     type *del = (type *)handle->delta;					\
596     int i;								\
597     for (i = 0; i < handle->nValues; i++)				\
598 	*dst++ = *org++ + offset*(*del++);				\
599 }
600 
601 #define MESHARRAY_ADDTERM(type)						\
602 {									\
603     type *dst = (type *)scratch;					\
604     type *right;							\
605     int i, j;								\
606 									\
607     for (i = 1; i < handle->nTerms; i++)				\
608     {									\
609 	right = (type *)DXGetArrayEntry(handle->handles[i],		\
610 		    handle->indices[i], handle->scratch[i]);		\
611 	for (j = 0; j < handle->nValues; j++)				\
612 	    dst[j] += right[j];						\
613     }									\
614 }
615 
616 static void
_dxfTermIndices(ArrayHandle handle,int offset,int * indices)617 _dxfTermIndices(ArrayHandle handle, int offset, int *indices)
618 {
619     int i;
620     for (i = 0; i < handle->nTerms-1; i++)
621     {
622 	indices[i] = offset / handle->strides[i];
623 	offset = offset % handle->strides[i];
624     }
625 
626     indices[handle->nTerms-1] = offset;
627 }
628 
629 Pointer
DXCalculateArrayEntry(ArrayHandle handle,int offset,Pointer scratch)630 DXCalculateArrayEntry(ArrayHandle handle, int offset, Pointer scratch)
631 {
632     if (handle->data)
633         return (Pointer)(((char *)handle->data) + offset*handle->itemSize);
634     else if (handle->cdata)
635 	return handle->cdata;
636     else
637     {
638 	switch (handle->class)
639 	{
640 	    case CLASS_REGULARARRAY:
641 		switch(handle->type)
642 		{
643 		    case TYPE_DOUBLE: REGULAR_GETELEMENT(double);  break;
644 		    case TYPE_FLOAT:  REGULAR_GETELEMENT(float);   break;
645 		    case TYPE_INT:    REGULAR_GETELEMENT(int);     break;
646 		    case TYPE_UINT:   REGULAR_GETELEMENT(uint);    break;
647 		    case TYPE_SHORT:  REGULAR_GETELEMENT(short);   break;
648 		    case TYPE_USHORT: REGULAR_GETELEMENT(ushort);  break;
649 		    case TYPE_BYTE:   REGULAR_GETELEMENT(byte);    break;
650 		    case TYPE_UBYTE:  REGULAR_GETELEMENT(ubyte);   break;
651 		    case TYPE_HYPER: case TYPE_STRING: break;
652 		}
653 	    break;
654 
655 	    case CLASS_PATHARRAY:
656 		((int *)scratch)[0] = offset;
657 		((int *)scratch)[1] = offset+1;
658 	    break;
659 
660 	    case CLASS_MESHARRAY:
661 	    {
662 		_dxfTermIndices(handle, offset, handle->indices);
663 
664 		if (handle->nTerms == 1)
665 		{
666 		    memcpy(scratch, DXGetArrayEntry(handle->handles[0],
667 			handle->indices[0], handle->scratch[0]),
668 			handle->handles[0]->itemSize);
669 		}
670 		else
671 		{
672 		    int *left, *right, *dst, *ptr, i, j, k, nItems;
673 
674 		    memcpy(handle->scratch1, DXGetArrayEntry(handle->handles[0],
675 			handle->indices[0], handle->scratch[0]),
676 			handle->handles[0]->itemSize);
677 
678 		    nItems = handle->handles[0]->nValues;
679 		    left = handle->scratch1; dst = handle->scratch2;
680 		    for (i = 1; i < handle->nTerms; i++)
681 		    {
682 			if (i == handle->nTerms-1)
683 			    dst = (int *)scratch;
684 
685 			right = (int *)DXGetArrayEntry(handle->handles[i],
686 					handle->indices[i], handle->scratch[i]);
687 
688 			ptr = dst;
689 			for (j = 0; j < nItems; j++)
690 			{
691 			    int tmp = left[j] * handle->counts[i];
692 
693 			    for (k = 0; k < handle->handles[i]->nValues; k++)
694 				*ptr++ = tmp + right[k];
695 			}
696 
697 			nItems *= handle->handles[i]->nValues;
698 
699 			ptr = dst;
700 			dst = left;
701 			left = ptr;
702 		    }
703 		}
704 	    }
705 	    break;
706 
707 	    case CLASS_PRODUCTARRAY:
708 	    {
709 		_dxfTermIndices(handle, offset, handle->indices);
710 
711 		if (handle->nTerms == 1)
712 		{
713 		    memcpy(scratch, DXGetArrayEntry(handle->handles[0],
714 			handle->indices[0], handle->scratch[0]),
715 			handle->handles[0]->itemSize);
716 		}
717 		else
718 		{
719 		    memcpy(scratch, DXGetArrayEntry(handle->handles[0],
720 			handle->indices[0], handle->scratch[0]),
721 			handle->handles[0]->itemSize);
722 
723 		    switch(handle->type)
724 		    {
725 			case TYPE_DOUBLE: MESHARRAY_ADDTERM(double);  break;
726 			case TYPE_FLOAT:  MESHARRAY_ADDTERM(float);   break;
727 			case TYPE_INT:    MESHARRAY_ADDTERM(int);     break;
728 			case TYPE_UINT:   MESHARRAY_ADDTERM(uint);    break;
729 			case TYPE_SHORT:  MESHARRAY_ADDTERM(short);   break;
730 			case TYPE_USHORT: MESHARRAY_ADDTERM(ushort);  break;
731 			case TYPE_BYTE:   MESHARRAY_ADDTERM(byte);    break;
732 			case TYPE_UBYTE:  MESHARRAY_ADDTERM(ubyte);   break;
733 		    case TYPE_HYPER: case TYPE_STRING: break;
734 		    }
735 		}
736 	    }
737 	    break;
738 	    default: /* All other TYPEs and CLASSes  */
739 	    break;
740 	}
741 
742     }
743     return scratch;
744 
745 }
746 
747 
748 /* make string arrays */
749 Array
DXMakeStringList(int n,char * s,...)750 DXMakeStringList(int n, char *s, ...)
751 {
752     int i;
753     char **c;
754     va_list arg;
755     Array a;
756 
757     if (n == 0)
758 	return NULL;
759 
760     if (n < 0) {
761 	DXSetError(ERROR_BAD_PARAMETER, "#10020", "stringlist count");
762 	return NULL;
763     }
764 
765     c = (char **)DXAllocate(n * sizeof(char *));
766     if (!c)
767 	return NULL;
768 
769     c[0] = s;
770 
771     /* collect args */
772     va_start(arg,s);
773     for (i=1; i<n; i++)
774 	c[i] = va_arg(arg, char *);
775     va_end(arg);
776 
777     /* call V version */
778     a = DXMakeStringListV(n, c);
779 
780     DXFree(c);
781     return a;
782 }
783 
784 /* count plus string list */
785 Array
DXMakeStringListV(int n,char ** s)786 DXMakeStringListV(int n, char **s)
787 {
788     Array a;
789     int i;
790     int count, l, maxlen = 0;
791     char *p;
792 
793     if (n == 0 || !s)
794 	return NULL;
795 
796     if (n < 0) {
797 	DXSetError(ERROR_BAD_PARAMETER, "#10020", "stringlist count");
798 	return NULL;
799     }
800 
801     for (count=0; count < n; count++) {
802 	if (!s[count])
803 	    continue;
804 
805 	if ((l=strlen(s[count])) > maxlen)
806 	    maxlen = l;
807     }
808 
809     a = DXNewArray(TYPE_STRING, CATEGORY_REAL, 1, maxlen+1);
810     if (!a)
811 	return NULL;
812 
813     if (!DXAddArrayData(a, 0, n, NULL))
814 	goto error;
815 
816     p = (char *)DXGetArrayData(a);
817     if (!p)
818 	goto error;
819 
820     for (i=0; i<n; i++, p += maxlen+1)
821 	s[i] ? strncpy(p, s[i], maxlen+1) : memset(p, '\0', maxlen+1);
822 
823     return a;
824 
825   error:
826     DXDelete((Object)a);
827     return NULL;
828 }
829 
830 static Array
packit(int n,Type t,Category c,int rank,int * shape,Pointer p)831 packit(int n, Type t, Category c, int rank, int *shape, Pointer p)
832 {
833     Array a = NULL;
834 
835     a = DXNewArrayV(t, c, rank, shape);
836     if (!a)
837 	return NULL;
838 
839     if (!DXAddArrayData(a, 0, n, p)) {
840 	DXDelete((Object)a);
841 	return NULL;
842     }
843 
844     return a;
845 }
846 
DXMakeInteger(int n)847 Array DXMakeInteger(int n)
848 {
849     return packit(1, TYPE_INT, CATEGORY_REAL, 0, NULL, (Pointer)&n);
850 }
851 
DXMakeFloat(float f)852 Array DXMakeFloat(float f)
853 {
854     return packit(1, TYPE_FLOAT, CATEGORY_REAL, 0, NULL, (Pointer)&f);
855 }
856