NCEPLIBS-g2c 1.9.0
Loading...
Searching...
No Matches
g2cxml.c
Go to the documentation of this file.
1
7#include <libxml/tree.h>
8#include <libxml/parser.h>
9#include <grib2_int.h>
10
12xmlDocPtr doc;
13
16
21void
23{
25
26 for (t = g2c_table; t; t = t->next)
27 {
29
30 printf("%s\n", t->title);
31 for (e = t->entry; e; e = e->next)
32 printf("code %s desc %s status %s\n", e->code, e->desc, e->status);
33
34 }
35}
36
41void
43{
44 G2C_CODE_TABLE_T *t, *the_next = NULL;
45
46 /* If g2c_table is NULL, then tables have already been
47 * freed. */
48 if (!g2c_table)
49 return;
50
51 /* Free each table. */
52 for (t = g2c_table; t; t = the_next)
53 {
55 G2C_CODE_ENTRY_T *e_next;
56
57 /* Free each entry in the table. */
58 the_next = t->next;
59 for (e = t->entry; e; e = e_next)
60 {
61 e_next = e->next;
62 free(e);
63 }
64
65 free(t);
66 }
67
68 /* Set to NULL so we all know g2c_table has been freed. */
69 g2c_table = NULL;
70}
71
83int
84g2c_find_desc_str(char *title, char *code, char *desc)
85{
86 G2C_CODE_TABLE_T *t = NULL;
87 int found = 0;
88
89 /* Check inputs. */
90 if (!title || strlen(title) > G2C_MAX_GRIB_TITLE_LEN
91 || !code || strlen(code) > G2C_MAX_GRIB_CODE_LEN || !desc)
92 return G2C_EINVAL;
93
94 /* Find table. */
95 for (t = g2c_table; !found && t; t = t->next)
96 {
97 if (!strncmp(title, t->title, strlen(title)))
98 {
99 G2C_CODE_ENTRY_T *e = NULL;
100
101 /* Find entry. */
102 for (e = t->entry; e; e = e->next)
103 {
104 if (!strncmp(code, e->code, strlen(code)))
105 {
106 strcpy(desc, e->desc);
107 found++;
108 break;
109 }
110 }
111 }
112 }
113
114 if (!found)
115 return G2C_ENOTFOUND;
116
117 return G2C_NOERROR;
118}
119
131int
132g2c_find_desc(char *title, int code, char *desc)
133{
134 char str_code[G2C_MAX_GRIB_CODE_LEN + 1];
135
136 sprintf(str_code, "%d", code);
137 return g2c_find_desc_str(title, str_code, desc);
138}
139
150{
152
153 for (g = g2c_table; g; g = g->next)
154 if (!strncmp(key, g->title, G2C_MAX_GRIB_TITLE_LEN))
155 return g;
156
157 return NULL;
158}
159
171{
173
174 for (e = table->entry; e; e = e->next)
175 if (!strncmp(desc, e->desc, G2C_MAX_GRIB_DESC_LEN))
176 return e;
177
178 return NULL;
179}
180
189int
191{
192 xmlNode *cur;
193 xmlChar *key;
194 G2C_CODE_TABLE_T *my_table = NULL;
195 G2C_CODE_ENTRY_T *new_entry = NULL;
196
197 /* If g2c_table is not NULL, then tables have already been
198 * initialized. */
199 if (g2c_table)
200 return G2C_NOERROR;
201
202 /* Ingest the XML document. */
203 if (!(doc = xmlReadFile("CodeFlag.xml", NULL, 0)))
204 return G2C_EXML;
205
206 /* Go through the document and save table data. */
207 cur = xmlDocGetRootElement(doc)->xmlChildrenNode;
208 while (cur)
209 {
210 xmlNode *child = cur->xmlChildrenNode;
211
212 /* Each child at this level is a table of codes. */
213 while (child)
214 {
215 G2C_CODE_TABLE_T *new_table = NULL;
216
217 if ((!xmlStrcmp(child->name, (const xmlChar *)"Title_en")))
218 {
219 key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
220 if (strlen((char *)key) > G2C_MAX_GRIB_TITLE_LEN)
221 return G2C_ENAMETOOLONG;
222 if (!(my_table = g2c_find_table((char *)key)))
223 {
224 if (!(new_table = calloc(1, sizeof(G2C_CODE_TABLE_T))))
225 return G2C_ENOMEM;
226 strncpy(new_table->title, (char *)key, G2C_MAX_GRIB_TITLE_LEN);
227 /* printf("title: %s\n", key); */
228 my_table = new_table;
229 }
230 xmlFree(key);
231 }
232
233 if (my_table)
234 {
235 if ((!xmlStrcmp(child->name, (const xmlChar *)"CodeFlag")))
236 {
238
239 if (!(new_entry = calloc(1, sizeof(G2C_CODE_ENTRY_T))))
240 return G2C_ENOMEM;
241 if (child->xmlChildrenNode)
242 {
243 key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
244 if (strlen((char *)key) > G2C_MAX_GRIB_CODE_LEN)
245 return G2C_ENAMETOOLONG;
246 strncpy(new_entry->code, (char *)key, G2C_MAX_GRIB_CODE_LEN);
247 /* printf("code: %s\n", key); */
248 xmlFree(key);
249 }
250
251 /* Add entry at end of list. */
252 if (my_table->entry)
253 {
254 for (e = my_table->entry; e->next; e = e->next)
255 ;
256 e->next = new_entry;
257 }
258 else
259 my_table->entry = new_entry;
260 }
261 if ((!xmlStrcmp(child->name, (const xmlChar *)"MeaningParameterDescription_en")))
262 {
263 key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
264 if (strlen((char *)key) > G2C_MAX_GRIB_DESC_LEN)
265 return G2C_ENAMETOOLONG;
266 if (!new_entry)
267 return G2C_EXML;
268 strncpy(new_entry->desc, (char *)key, G2C_MAX_GRIB_DESC_LEN);
269 /* printf("description: %s\n", key); */
270 xmlFree(key);
271 }
272 if ((!xmlStrcmp(child->name, (const xmlChar *)"Status")))
273 {
274 key = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
275 if (strlen((char *)key) > G2C_MAX_GRIB_STATUS_LEN)
276 return G2C_ENAMETOOLONG;
277 if (!new_entry)
278 return G2C_EXML;
279 strncpy(new_entry->status, (char *)key, G2C_MAX_GRIB_STATUS_LEN);
280 /* printf("status: %s\n", key); */
281 xmlFree(key);
282 }
283 }
284
285 /* Move to next node of XML document. */
286 child = child->next;
287
288 /* Add this table to our list of GRIB tables. */
289 if (new_table)
290 {
291 if (!g2c_table)
292 g2c_table = new_table;
293 else
294 {
296
297 /* Go to end of list and add the table. */
298 if (g)
299 {
300 for (; g->next; g = g->next)
301 ;
302 g->next = new_table;
303 }
304 else
305 {
306 g2c_table = new_table;
307 }
308 }
309 new_table = NULL;
310 }
311 }
312
313 cur = cur->next;
314 }
315
316 /* g2c_print_tables(); */
317
318 xmlFreeDoc(doc);
319 xmlCleanupParser();
320
321 return G2C_NOERROR;
322}
int g2c_find_desc_str(char *title, char *code, char *desc)
Given a table title and a code, find a description.
Definition g2cxml.c:84
int g2c_find_desc(char *title, int code, char *desc)
Given a table title and an integer code, find a description.
Definition g2cxml.c:132
int g2c_xml_init()
Init.
Definition g2cxml.c:190
G2C_CODE_TABLE_T * g2c_find_table(char *key)
Find a table given a key.
Definition g2cxml.c:149
void g2c_free_tables()
Free table memory.
Definition g2cxml.c:42
xmlDocPtr doc
Contains the parsed XML document.
Definition g2cxml.c:12
G2C_CODE_ENTRY_T * g2c_find_entry(char *desc, G2C_CODE_TABLE_T *table)
Find an entry in a table given a description.
Definition g2cxml.c:170
G2C_CODE_TABLE_T * g2c_table
Pointer to the list of code tables.
Definition g2cxml.c:15
void g2c_print_tables()
Print the table data.
Definition g2cxml.c:22
#define G2C_MAX_GRIB_TITLE_LEN
Maximum length of code table title.
Definition grib2.h:428
#define G2C_MAX_GRIB_DESC_LEN
Maximum length of code description.
Definition grib2.h:424
#define G2C_ENAMETOOLONG
Name too long.
Definition grib2.h:495
#define G2C_ENOMEM
Out of memory.
Definition grib2.h:500
#define G2C_ENOTFOUND
Table or entry not found.
Definition grib2.h:504
#define G2C_MAX_GRIB_STATUS_LEN
Maximum length of code status.
Definition grib2.h:425
#define G2C_EINVAL
Invalid input.
Definition grib2.h:496
#define G2C_MAX_GRIB_CODE_LEN
Maximum length of code.
Definition grib2.h:427
#define G2C_EXML
XML error.
Definition grib2.h:503
#define G2C_NOERROR
No error.
Definition grib2.h:491
Header file with internal function prototypes NCEPLIBS-g2c library.
A GRIB2 code table.
Definition grib2_int.h:255
An entry in a GRIB2 code table.
Definition grib2_int.h:246