NeXus  4.4.3
 All Data Structures Files Functions Variables Typedefs Macros Pages
nxdataset.c
Go to the documentation of this file.
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 /*-----------------------------------------------------------------------*/
14 static 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 /*-----------------------------------------------------------------------*/
36 pNXDS 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((size_t)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,(size_t)length*getTypeSize(typecode)+1);
66  return pNew;
67 }
68 /*---------------------------------------------------------------------*/
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 /*-----------------------------------------------------------------------*/
89 void 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 /*-----------------------------------------------------------------------*/
108 int 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 /*-----------------------------------------------------------------------*/
118 int 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 (int)dataset->dim[which];
129 }
130 /*------------------------------------------------------------------------*/
131 int 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 /*--------------------------------------------------------------------*/
142  int length, i;
143 
144  if(dataset == NULL){
145  return 0;
146  }
147  if(dataset->magic != MAGIC){
148  return 0;
149  }
150  length = (int)dataset->dim[0];
151  for(i = 1; i < dataset->rank; i++){
152  length *= (int)dataset->dim[i];
153  }
154  return length;
155 }
156 /*---------------------------------------------------------------------*/
158  return getNXDatasetLength(dataset)*getTypeSize(dataset->type);
159 }
160 /*----------------------------------------------------------------------
161  This calculates an arbitray address in C storage order
162  -----------------------------------------------------------------------*/
163 static 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 /*-----------------------------------------------------------------------*/
180 double 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 /*----------------------------------------------------------------------*/
194 double 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 /*-----------------------------------------------------------------------*/
230 char *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(((size_t)dataset->dim[0]+10)*sizeof(char));
258  if(resultBuffer == NULL){
259  return strdup("NO Memory");
260  }
261  memset(resultBuffer,0,((size_t)dataset->dim[0]+10)*sizeof(char));
262  strncpy(resultBuffer,dataset->u.cPtr,(size_t)dataset->dim[0]);
263  }
264  return resultBuffer;
265 }
266 /*----------------------------------------------------------------------*/
267 int 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  /*---------------------------------------------------------------------*/
281 int 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 
float * fPtr
Definition: nxdataset.h:25
int getNXDatasetRank(pNXDS dataset)
Definition: nxdataset.c:108
int rank
Definition: nxdataset.h:19
int putNXDatasetValueAt(pNXDS dataset, int64_t address, double value)
Definition: nxdataset.c:281
int64_t * dim
Definition: nxdataset.h:21
int getNXDatasetType(pNXDS dataset)
Definition: nxdataset.c:131
void dropNXDataset(pNXDS dataset)
Definition: nxdataset.c:89
#define NX_INT64
Definition: nxdataset.h:47
pNXDS createNXDataset(int rank, int typecode, int64_t dim[])
Definition: nxdataset.c:36
int getNXDatasetDim(pNXDS dataset, int which)
Definition: nxdataset.c:118
int * iPtr
Definition: nxdataset.h:27
char * format
Definition: nxdataset.h:22
pNXDS createTextNXDataset(char *name)
Definition: nxdataset.c:69
#define NX_FLOAT64
Definition: nxdataset.h:40
void * ptr
Definition: nxdataset.h:24
double getNXDatasetValue(pNXDS dataset, int64_t pos[])
Definition: nxdataset.c:180
double getNXDatasetValueAt(pNXDS dataset, int64_t address)
Definition: nxdataset.c:194
#define NX_FLOAT32
Definition: nxdataset.h:39
int magic
Definition: nxdataset.h:18
union pNXDS::@0 u
int getNXDatasetByteLength(pNXDS dataset)
Definition: nxdataset.c:157
double * dPtr
Definition: nxdataset.h:26
short int * sPtr
Definition: nxdataset.h:28
char * cPtr
Definition: nxdataset.h:29
#define NX_UINT16
Definition: nxdataset.h:44
char * getNXDatasetText(pNXDS dataset)
Definition: nxdataset.c:230
int putNXDatasetValue(pNXDS dataset, int64_t pos[], double value)
Definition: nxdataset.c:267
int type
Definition: nxdataset.h:20
#define NX_CHAR
Definition: nxdataset.h:49
#define NX_UINT64
Definition: nxdataset.h:48
#define NX_UINT32
Definition: nxdataset.h:46
#define NX_INT32
Definition: nxdataset.h:45
int getNXDatasetLength(pNXDS dataset)
Definition: nxdataset.c:141
int64_t * lPtr
Definition: nxdataset.h:30
#define NX_INT16
Definition: nxdataset.h:43
#define MAGIC
Definition: nxdataset.h:13