OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
epr_record.c
Go to the documentation of this file.
1 /*
2  * $Id: epr_record.c,v 1.1.1.1 2004-10-28 19:22:23 norman Exp $
3  *
4  * Copyright (C) 2002 by Brockmann Consult (info@brockmann-consult.de)
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation. This program is distributed in the hope it will
9  * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
10  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16  */
17 
18 #include <assert.h>
19 #include <errno.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "epr_api.h"
25 #include "epr_core.h"
26 #include "epr_string.h"
27 #include "epr_ptrarray.h"
28 #include "epr_swap.h"
29 #include "epr_field.h"
30 #include "epr_record.h"
31 #include "epr_param.h"
32 #include "epr_dsd.h"
33 #include "epr_msph.h"
34 #include "epr_band.h"
35 #include "epr_bitmask.h"
36 
37 #include "epr_dddb.h"
38 
39 /*
40  * ===================== Record Info Access ==============================
41  */
42 
43 
44 /*
45  Function: epr_create_record_info
46  Access: public API
47  Changelog: 2002/01/16 mp initial version
48  */
61 EPR_SRecordInfo* epr_create_record_info(const char* dataset_name, EPR_SPtrArray* field_infos)
62 {
63 
64  EPR_SRecordInfo* record_info = NULL;
65  EPR_SFieldInfo* field_info = NULL;
66  int field_infos_index;
67  int field_infos_length;
68  epr_uint tot_record_size = 0;
69 
70  record_info = (EPR_SRecordInfo*) calloc(1, sizeof (EPR_SRecordInfo));
71  if (record_info == NULL)
72  {
74  "epr_create_record_info: out of memory");
75  return NULL;
76  }
77  epr_assign_string(&record_info->dataset_name, dataset_name);
78  if (record_info->dataset_name == NULL)
79  {
81  "epr_create_record_info: out of memory");
82  return NULL;
83  }
84 
85  record_info->field_infos = field_infos;
86 
87  field_infos_length = (int)epr_get_ptr_array_length(field_infos);
88  for (field_infos_index = 0; field_infos_index < field_infos_length; field_infos_index++)
89  {
90  field_info = (EPR_SFieldInfo*)epr_get_ptr_array_elem_at(field_infos, field_infos_index);
91  tot_record_size += field_info->tot_size;
92  }
93 
94  record_info->tot_size = tot_record_size;
95 
96  return record_info;
97 }
98 
99 
109 void epr_free_record_info(EPR_SRecordInfo* record_info)
110 {
111  EPR_SFieldInfo* field_info = NULL;
112  epr_uint field_info_index = 0;
113 
114  if (record_info == NULL)
115  return;
116 
117  if (record_info->field_infos != NULL)
118  {
119  for (field_info_index = 0; field_info_index < record_info->field_infos->length; field_info_index++)
120  {
121  field_info = (EPR_SFieldInfo*)epr_get_ptr_array_elem_at(record_info->field_infos, field_info_index);
122  epr_free_field_info(field_info);
123  }
124  epr_free_ptr_array(record_info->field_infos);
125  record_info->field_infos = NULL;
126  }
127 
128  epr_free_string(record_info->dataset_name);
129  record_info->dataset_name = NULL;
130 
131  record_info->field_infos = NULL;
132  record_info->tot_size = 0;
133 
134  free(record_info);
135 }
136 
137 
138 /*
139  Function: epr_get_record_info
140  Access: private API implementation helper
141  Changelog: 2002/01/05 mp initial version
142  */
151 EPR_SRecordInfo* epr_get_record_info(EPR_SDatasetId* dataset_id)
152 {
153  EPR_SProductId* product_id;
154  EPR_SRecordInfo* record_info;
155  epr_uint num_record_infos;
156  epr_uint record_index = 0;
157 
158  assert(dataset_id != NULL);
159 
160  product_id = dataset_id->product_id;
161  assert(product_id != NULL);
162  assert(product_id->record_info_cache != NULL);
163 
164  /*
165  * checks, if 'record_info_cache' is not empty, then returns this cache,
166  * not making moreover
167  */
168  num_record_infos = product_id->record_info_cache->length;
169  for (record_index = 0; record_index < num_record_infos; record_index++)
170  {
171  record_info = (EPR_SRecordInfo*) product_id->record_info_cache->elems[record_index];
172  if (epr_equal_names(record_info->dataset_name, dataset_id->dataset_name))
173  return record_info;
174  }
175 
176  record_info = epr_read_record_info(product_id, dataset_id);
177  if (record_info == NULL) {
179  "epr_get_record_info: invalid DDDB resource path: missing any 'ASAR' files");
180  return NULL;
181  }
182 
183  epr_add_ptr_array_elem(product_id->record_info_cache, record_info);
184 
185  return record_info;
186 }
187 
188 
189 
190 EPR_SRecordInfo* epr_read_record_info(EPR_SProductId* product_id, EPR_SDatasetId* dataset_id)
191 {
192  EPR_SRecordInfo* record_info = NULL;
193  EPR_SFieldInfo* field_info = NULL;
194  EPR_SPtrArray* field_infos = NULL;
195  EPR_EDataTypeId data_type_id = e_tid_unknown;
196  epr_uint num_elems = 0;
197  epr_uint num_bytes = 0;
198  epr_uint more_count = 0;
199  char* field_name = NULL;
200  char* data_type = NULL;
201  char* unit = NULL;
202  char* description = NULL;
203  int i;
204  int rt_index;
205  const struct RecordDescriptorTable* r_tables;
206  int num_descr;
207  int num_r_tables;
208 
209  if (product_id == NULL) {
211  "epr_read_record_info: product_id must not be NULL");
212  return NULL;
213  }
214 
215  /* @DDDB */
216 
217  if (strncmp(product_id->id_string, "MER", 3) == 0) {
218  r_tables = dddb_meris_rec_tables;
219  num_r_tables = EPR_NUM_MERIS_REC_TABLES;
220  } else if (strncmp(product_id->id_string, "ATS", 3) == 0) {
221  r_tables = dddb_aatsr_rec_tables;
222  num_r_tables = EPR_NUM_AATSR_REC_TABLES;
223  } else if (strncmp(product_id->id_string, "ASA", 3) == 0) {
224  r_tables = dddb_asar_rec_tables;
225  num_r_tables = EPR_NUM_ASAR_REC_TABLES;
226  } else if (strncmp(product_id->id_string, "SAR", 3) == 0) {
227  r_tables = dddb_asar_rec_tables;
228  num_r_tables = EPR_NUM_ASAR_REC_TABLES;
229  } else {
231  "epr_read_record_info: invalid product identifier");
232  return NULL;
233  }
234 
235  rt_index = -1;
236  for (i = 0; i < num_r_tables; i++) {
237  if (dataset_id->record_descriptor == r_tables[i].descriptors) {
238  rt_index = i;
239  break;
240  }
241  }
242  if (rt_index == -1) {
244  "epr_read_record_info: unknown record");
245  return NULL;
246  }
247 
248  field_infos = epr_create_ptr_array(16);
249  num_descr = r_tables[rt_index].num_descriptors;
250  for (i = 0; i < num_descr; i++) {
251  /* 1: field_name */
252  field_name = epr_clone_string(r_tables[rt_index].descriptors[i].id);
253  /* 2: data_type_id */
254  data_type_id = r_tables[rt_index].descriptors[i].type;
255  /* 3: unit */
256  unit = epr_clone_string(r_tables[rt_index].descriptors[i].unit);
257  /* 4: num_elems */
258  num_bytes = r_tables[rt_index].descriptors[i].elem_size;
259  /* 5: num_elems and more_count*/
260  /* @todo: check return value! and check epr_parse_value_count */
261  num_elems = epr_parse_value_count(product_id, r_tables[rt_index].descriptors[i].num_elem);
262  more_count = 1;
263  /* 6: description*/
264  description = epr_clone_string(r_tables[rt_index].descriptors[i].description);
265 
266  field_info = epr_create_field_info(data_type_id, description, field_name, num_elems, num_bytes, more_count, unit);
267  epr_add_ptr_array_elem(field_infos, field_info);
268 
269  epr_free_string(field_name);
270  epr_free_string(data_type);
271  epr_free_string(unit);
273  }
274  record_info = epr_create_record_info(dataset_id->dataset_name, field_infos);
275 
276  return record_info;
277 }
278 
279 
280 /*
281  Function: epr_read_record_info
282  Access: private API implementation helper
283  Changelog: 2002/01/05 mp initial version
284  */
295  /*
296 EPR_SRecordInfo* epr_read_record_info(EPR_SProductId* product_id, EPR_SDatasetId* dataset_id, FILE* db_file_istream)
297 
298 }
299 */
300 
301 /*
302  Function: epr_create_record
303  Access: public API
304  Changelog: 2002/01/23 mp initial version
305  */
315 EPR_SRecord* epr_create_record_from_info(EPR_SRecordInfo* record_info)
316 {
317  EPR_SRecord* record = NULL;
318  EPR_SFieldInfo* field_info = NULL;
319  epr_uint field_infos_index = 0;
320  //int field_infos_length;
321 
322  if (record_info == NULL)
323  {
325  "epr_create_record_from_info: out of memory");
326  return NULL;
327  }
328 
329  record = (EPR_SRecord*) calloc(1, sizeof(EPR_SRecord));
330  if (record == NULL)
331  {
333  "epr_create_record: out of memory");
334  return NULL;
335  }
336 
337  record->magic = EPR_MAGIC_RECORD;
338  record->info = record_info;
339  record->num_fields = record_info->field_infos->length;
340 
341  record->fields = (EPR_SField**) calloc(record->num_fields, sizeof(EPR_SField*));
342  if (record->fields == NULL)
343  {
345  "epr_create_record: out of memory");
346  return NULL;
347  }
348 
349  epr_get_ptr_array_length(record_info->field_infos);
350 
351  for (field_infos_index = 0; field_infos_index < record_info->field_infos->length; field_infos_index++)
352  {
353  field_info = (EPR_SFieldInfo*)epr_get_ptr_array_elem_at(record_info->field_infos, field_infos_index);
354  record->fields[field_infos_index] = epr_create_field(field_info);
355  }
356  return record;
357 }
358 
359 
360 const EPR_SField* epr_get_field_at(const EPR_SRecord* record, epr_uint field_index){
361 
362  EPR_SField* field = NULL;
363 
364  epr_clear_err();
365 
366  if (record == NULL) {
368  "epr_get_field_at: record-identifier must not be NULL");
369  return NULL;
370  }
371 
372  if ((field_index < 0) || (field_index >= record->num_fields))
373  {
375  "epr_get_field_at: field_index out of range");
376  return NULL;
377  }
378  field = record->fields[field_index];
379  return field;
380 }
381 
382 
383 epr_uint epr_get_num_fields(const EPR_SRecord* record)
384 {
385  epr_clear_err();
386 
387  if (record == NULL) {
389  "epr_get_field_at: record-identifier must not be NULL");
390  return (epr_uint)-1;
391  }
392  return record->num_fields;
393 }
394 
395 
405 void epr_free_record(EPR_SRecord* record)
406 {
407  EPR_SField* field = NULL;
408  epr_uint fields_index = 0;
409 
410  epr_clear_err();
411 
412  if (record == NULL)
413  return;
414 
415  if (record->fields != NULL)
416  {
417  for (fields_index = 0; fields_index < record->num_fields; fields_index++)
418  {
419  field = (EPR_SField*)record->fields[fields_index];
420  epr_free_field(field);
421  }
422  free(record->fields);
423  record->fields = NULL;
424  }
425 
426  /* Do NOT free record->info since many records can
427  share the same record->info! */
428  record->info = NULL;
429 
430  record->num_fields = 0;
431 
432  free(record);
433 }
EPR_SField * epr_create_field(EPR_SFieldInfo *field_info)
Definition: epr_field.c:147
void epr_free_field(EPR_SField *field)
Definition: epr_field.c:218
@ e_err_out_of_memory
Definition: epr_api.h:83
unsigned int epr_get_ptr_array_length(const EPR_SPtrArray *ptr_array)
Definition: epr_ptrarray.c:115
void epr_free_field_info(EPR_SFieldInfo *field_info)
Definition: epr_field.c:111
const struct RecordDescriptorTable dddb_meris_rec_tables[23]
Definition: epr_dddb.c:4286
unsigned int epr_uint
Definition: epr_api.h:188
void epr_free_ptr_array(EPR_SPtrArray *ptr_array)
Definition: epr_ptrarray.c:51
void epr_free_record(EPR_SRecord *record)
Definition: epr_record.c:405
const EPR_EDataTypeId type
Definition: epr_dddb.h:12
#define NULL
Definition: decode_rs.h:63
#define EPR_NUM_ASAR_REC_TABLES
Definition: epr_dddb.h:88
EPR_SRecord * epr_create_record_from_info(EPR_SRecordInfo *record_info)
Definition: epr_record.c:315
char * epr_assign_string(char **str_clone, const char *str)
Definition: epr_string.c:29
@ e_err_file_access_denied
Definition: epr_api.h:90
epr_uint epr_get_num_fields(const EPR_SRecord *record)
Definition: epr_record.c:383
character(len=1000) if
Definition: names.f90:13
@ e_err_invalid_product_id
Definition: epr_api.h:98
const int elem_size
Definition: epr_dddb.h:14
epr_boolean epr_equal_names(const char *name1, const char *name2)
Definition: epr_string.c:91
const struct RecordDescriptorTable dddb_asar_rec_tables[20]
Definition: epr_dddb.c:4335
@ e_err_null_pointer
Definition: epr_api.h:80
EPR_SRecordInfo * epr_create_record_info(const char *dataset_name, EPR_SPtrArray *field_infos)
Definition: epr_record.c:61
void epr_free_record_info(EPR_SRecordInfo *record_info)
Definition: epr_record.c:109
char * epr_clone_string(const char *str)
Definition: epr_string.c:43
@ e_err_index_out_of_range
Definition: epr_api.h:84
#define EPR_NUM_AATSR_REC_TABLES
Definition: epr_dddb.h:87
What value is used by your function when the data value is bad Default is BAD_FLT l2prod product_id[0]
void * epr_get_ptr_array_elem_at(const EPR_SPtrArray *ptr_array, unsigned int index)
Definition: epr_ptrarray.c:122
EPR_SFieldInfo * epr_create_field_info(EPR_EDataTypeId data_type_id, char *description, char *field_name, epr_uint num_elems, epr_uint num_bytes, epr_uint more_count, char *unit)
Definition: epr_field.c:52
const struct RecordDescriptor * descriptors
Definition: epr_dddb.h:73
int epr_add_ptr_array_elem(EPR_SPtrArray *ptr_array, void *elem)
Definition: epr_ptrarray.c:75
void epr_clear_err()
Definition: epr_core.c:247
const struct RecordDescriptorTable dddb_aatsr_rec_tables[20]
Definition: epr_dddb.c:4312
void epr_set_err(EPR_EErrCode err_code, const char *err_message)
Definition: epr_core.c:221
description
Definition: setup.py:16
EPR_SRecordInfo * epr_read_record_info(EPR_SProductId *product_id, EPR_SDatasetId *dataset_id)
Definition: epr_record.c:190
epr_uint epr_parse_value_count(EPR_SProductId *product_id, const char *count)
Definition: epr_core.c:373
enum EPR_DataTypeId EPR_EDataTypeId
Definition: epr_api.h:161
@ e_tid_unknown
Definition: epr_api.h:46
#define EPR_MAGIC_RECORD
Definition: epr_api.h:197
#define EPR_NUM_MERIS_REC_TABLES
Definition: epr_dddb.h:86
EPR_SRecordInfo * epr_get_record_info(EPR_SDatasetId *dataset_id)
Definition: epr_record.c:151
int i
Definition: decode_rs.h:71
void epr_free_string(char *str)
Definition: epr_string.c:100
const EPR_SField * epr_get_field_at(const EPR_SRecord *record, epr_uint field_index)
Definition: epr_record.c:360
EPR_SPtrArray * epr_create_ptr_array(unsigned int capacity)
Definition: epr_ptrarray.c:29