source: trunk/src/nxdataset.c @ 1822

Revision 1649, 7.3 KB checked in by Freddie Akeroyd, 7 months ago (diff)

XML now working with int64 dimensions. Refs #258

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2  This is a module which implements the notion of a dataset. Its is
3  designed for the use with scripting languages.
4 
5  copyright: GPL
6
7  Mark Koennecke, October 2002
8*/
9#include <stdlib.h>
10#include <string.h>
11#include "nxdataset.h"
12
13/*-----------------------------------------------------------------------*/
14static int getTypeSize(int typecode){
15  switch(typecode){
16  case NX_FLOAT32:
17  case NX_INT32:
18  case NX_UINT32:
19    return 4;
20    break;
21  case NX_FLOAT64:
22  case NX_INT64:
23  case NX_UINT64:
24    return 8;
25    break;
26  case NX_INT16:
27  case NX_UINT16:
28    return 2;
29    break;
30  default:
31    return 1;
32    break;
33  }
34}
35/*-----------------------------------------------------------------------*/
36pNXDS createNXDataset(int rank, int typecode, int64_t dim[]){
37  pNXDS pNew = NULL;
38  int64_t length;
39  int i;
40
41  pNew = (pNXDS)malloc(sizeof(NXDS));
42  if(pNew == NULL){
43    return NULL;
44  }
45
46  pNew->dim = (int64_t *)malloc(rank*sizeof(int64_t));
47  for(i = 0, length = 1; i < rank; i++){
48    length *= dim[i];
49  }
50  /* add +1 in case of string NULL termination */
51  pNew->u.ptr = malloc(length*getTypeSize(typecode)+1);
52
53  if(pNew->dim == NULL || pNew->u.ptr == NULL){
54    free(pNew);
55    return NULL;
56  }
57  pNew->rank = rank;
58  pNew->type = typecode;
59  pNew->format = NULL;
60  for(i = 0; i < rank; i++){
61    pNew->dim[i] = dim[i];
62  }
63  pNew->magic = MAGIC;
64  /* add +1 in case of string NULL termination  - see above */
65  memset(pNew->u.ptr,0,length*getTypeSize(typecode)+1);
66  return pNew;
67}
68/*---------------------------------------------------------------------*/
69pNXDS createTextNXDataset(char *name){
70  pNXDS pNew = NULL;
71
72  pNew = (pNXDS)malloc(sizeof(NXDS));
73  if(pNew == NULL){
74    return NULL;
75  }
76  pNew->dim = (int64_t *)malloc(sizeof(int64_t));
77  pNew->u.cPtr = strdup(name);
78  if(pNew->dim == NULL || pNew->u.ptr == NULL){
79    free(pNew);
80    return NULL;
81  }
82  pNew->rank = 1;
83  pNew->type = NX_CHAR;
84  pNew->magic = MAGIC;
85  pNew->dim[0] = strlen(name);
86  return pNew;
87}
88/*-----------------------------------------------------------------------*/
89void  dropNXDataset(pNXDS dataset){
90  if(dataset == NULL){
91    return;
92  }
93  if(dataset->magic != MAGIC){
94    return;
95  }
96  if(dataset->dim != NULL){
97    free(dataset->dim);
98  }
99  if(dataset->u.ptr != NULL){
100    free(dataset->u.ptr);
101  }
102  if(dataset->format != NULL){
103    free(dataset->format);
104  }
105  free(dataset);
106}
107/*-----------------------------------------------------------------------*/
108int   getNXDatasetRank(pNXDS dataset){
109  if(dataset == NULL){
110    return 0;
111  }
112  if(dataset->magic != MAGIC){
113    return 0;
114  }
115  return dataset->rank;
116}
117/*-----------------------------------------------------------------------*/
118int   getNXDatasetDim(pNXDS dataset, int which){
119  if(dataset == NULL){
120    return 0;
121  }
122  if(dataset->magic != MAGIC){
123    return 0;
124  }
125  if(which < 0 || which >= dataset->rank){
126    return 0;
127  }
128  return dataset->dim[which];
129}
130/*------------------------------------------------------------------------*/
131int   getNXDatasetType(pNXDS dataset){
132  if(dataset == NULL){
133    return 0;
134  }
135  if(dataset->magic != MAGIC){
136    return 0;
137  }
138  return dataset->type;
139}
140/*--------------------------------------------------------------------*/
141int getNXDatasetLength(pNXDS dataset){
142  int length, i;
143
144  if(dataset == NULL){
145    return 0;
146  }
147  if(dataset->magic != MAGIC){
148    return 0;
149  }
150  length = dataset->dim[0];
151  for(i = 1; i < dataset->rank; i++){
152    length *= dataset->dim[i];
153  }
154  return length;
155}
156/*---------------------------------------------------------------------*/
157int getNXDatasetByteLength(pNXDS dataset){
158  return getNXDatasetLength(dataset)*getTypeSize(dataset->type);
159}
160/*----------------------------------------------------------------------
161  This calculates an arbitray address in C storage order
162  -----------------------------------------------------------------------*/
163static int64_t calculateAddress(pNXDS dataset, int64_t pos[]){
164  int64_t result, mult;
165  int i, j;
166
167  result = pos[dataset->rank - 1];
168  for(i = 0; i < dataset->rank -1; i++){
169    mult = 1;
170    for(j = dataset->rank -1; j > i; j--){
171      mult *= dataset->dim[j];
172    }
173    if(pos[i] < dataset->dim[i] && pos[i] > 0){
174      result += mult*pos[i];
175    }
176  }
177  return result;
178}
179/*-----------------------------------------------------------------------*/
180double getNXDatasetValue(pNXDS dataset, int64_t pos[]){
181  int64_t address;
182 
183  if(dataset == NULL){
184    return 0;
185  }
186  if(dataset->magic != MAGIC){
187    return 0;
188  }
189
190  address = calculateAddress(dataset,pos);
191  return getNXDatasetValueAt(dataset, address);
192}
193/*----------------------------------------------------------------------*/
194double getNXDatasetValueAt(pNXDS dataset, int64_t address){
195  double value;
196
197  if(dataset == NULL){
198    return 0;
199  }
200  if(dataset->magic != MAGIC){
201    return 0;
202  }
203
204  switch(dataset->type){
205  case NX_FLOAT64:
206    value = dataset->u.dPtr[address];
207    break;
208  case NX_FLOAT32:
209    value = (double)dataset->u.fPtr[address];
210    break;
211  case NX_INT32:
212  case NX_UINT32:
213    value = (double)dataset->u.iPtr[address];
214    break;
215  case NX_INT64:
216  case NX_UINT64:
217    value = (double)dataset->u.lPtr[address];
218    break;
219  case NX_INT16:
220  case NX_UINT16:
221    value = (double)dataset->u.sPtr[address];
222    break;
223  default:
224    value = (double)dataset->u.cPtr[address];
225    break;
226  }
227  return value;
228}
229/*-----------------------------------------------------------------------*/
230char  *getNXDatasetText(pNXDS dataset){
231  char *resultBuffer = NULL;
232  int status = 1;
233
234  if(dataset == NULL){
235    return strdup("NULL");
236  }
237  if(dataset->magic != MAGIC){
238    return strdup("NULL");
239  }
240  if(dataset->rank > 1){
241    status = 0;
242  } 
243  if(dataset->type == NX_FLOAT32 ||
244     dataset->type == NX_FLOAT64 ||
245     dataset->type == NX_INT32 ||
246     dataset->type == NX_UINT32 ||
247     dataset->type == NX_INT64 ||
248     dataset->type == NX_UINT64 ||
249     dataset->type == NX_INT16 ||
250     dataset->type == NX_UINT16 ) {
251    status = 0;
252  }
253
254  if(status == 0){
255    return strdup("NO type problem");
256  }else{
257    resultBuffer = (char *)malloc((dataset->dim[0]+10)*sizeof(char));
258    if(resultBuffer == NULL){
259      return strdup("NO Memory");
260    }
261    memset(resultBuffer,0,(dataset->dim[0]+10)*sizeof(char));
262    strncpy(resultBuffer,dataset->u.cPtr,dataset->dim[0]);
263  }
264  return resultBuffer;
265}
266/*----------------------------------------------------------------------*/
267int   putNXDatasetValue(pNXDS dataset, int64_t pos[], double value){
268  int64_t address;
269
270  if(dataset == NULL){
271    return 0;
272  }
273  if(dataset->magic != MAGIC){
274    return 0;
275  }
276
277  address = calculateAddress(dataset,pos);
278  return putNXDatasetValueAt(dataset,address,value);
279}
280  /*---------------------------------------------------------------------*/
281int putNXDatasetValueAt(pNXDS dataset, int64_t address, double value){
282  /*
283    this code is dangerous, it casts without checking the data range.
284    This may cause trouble in some cases
285  */
286  switch(dataset->type){
287  case NX_FLOAT64:
288    dataset->u.dPtr[address] = value;
289    break;
290  case NX_FLOAT32:
291    dataset->u.fPtr[address] = (float)value;
292    break;
293  case NX_INT32:
294  case NX_UINT32:
295    dataset->u.iPtr[address] = (int)value;
296    break;
297  case NX_INT64:
298  case NX_UINT64:
299    dataset->u.lPtr[address] = (int64_t)value;
300    break;
301  case NX_INT16:
302  case NX_UINT16:
303    dataset->u.sPtr[address] = (short int)value;
304    break;
305  default:
306    dataset->u.cPtr[address] = (char)value;
307    break;
308  }
309  return 1;
310}
311
312
313
Note: See TracBrowser for help on using the repository browser.