1 | /* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. |
---|
2 | See the COPYRIGHT dap for more information. */ |
---|
3 | |
---|
4 | /* |
---|
5 | Draft OC External Interface |
---|
6 | Created: 4/4/2009 |
---|
7 | Last Revised: 4/14/2009 |
---|
8 | */ |
---|
9 | |
---|
10 | #ifndef OC_H |
---|
11 | #define OC_H |
---|
12 | |
---|
13 | #include <stdlib.h> |
---|
14 | #include <stdio.h> |
---|
15 | |
---|
16 | /* if defined, use magic numbers for consistency]) */ |
---|
17 | #define OC_FASTCONSISTENCY |
---|
18 | |
---|
19 | /* OC_MAX_DIMS should be greater or equal to max allowed by dap or netcdf*/ |
---|
20 | #define OC_MAX_DIMS 1024 |
---|
21 | |
---|
22 | /* Specifies the OCtype.*/ |
---|
23 | /* Primitives = Duplicate of the NODE_Byte..Node_URL union nc_type*/ |
---|
24 | |
---|
25 | typedef unsigned long OCtype; |
---|
26 | |
---|
27 | /* Note: use #define rather than enum so we can extend if needed |
---|
28 | more easily */ |
---|
29 | /* Primitives*/ |
---|
30 | /* OC_Ubyte, OC_Char, OC_Int64 and OC_UInt64 are defined for future extension*/ |
---|
31 | #define OC_NAT ((OCtype)0) |
---|
32 | #define OC_Char ((OCtype)1) |
---|
33 | #define OC_Byte ((OCtype)2) |
---|
34 | #define OC_UByte ((OCtype)3) |
---|
35 | #define OC_Int16 ((OCtype)4) |
---|
36 | #define OC_UInt16 ((OCtype)5) |
---|
37 | #define OC_Int32 ((OCtype)6) |
---|
38 | #define OC_UInt32 ((OCtype)7) |
---|
39 | #define OC_Int64 ((OCtype)8) |
---|
40 | #define OC_UInt64 ((OCtype)9) |
---|
41 | #define OC_Float32 ((OCtype)10) |
---|
42 | #define OC_Float64 ((OCtype)11) |
---|
43 | #define OC_String ((OCtype)12) |
---|
44 | #define OC_URL ((OCtype)13) |
---|
45 | |
---|
46 | /* Non-primitives*/ |
---|
47 | #define OC_Dataset ((OCtype)100) |
---|
48 | #define OC_Sequence ((OCtype)101) |
---|
49 | #define OC_Grid ((OCtype)102) |
---|
50 | #define OC_Structure ((OCtype)103) |
---|
51 | #define OC_Dimension ((OCtype)104) |
---|
52 | #define OC_Attribute ((OCtype)105) |
---|
53 | #define OC_Attributeset ((OCtype)106) |
---|
54 | #define OC_Primitive ((OCtype)107) |
---|
55 | #define OC_Group ((OCtype)108) |
---|
56 | #define OC_Type ((OCtype)109) |
---|
57 | |
---|
58 | /* Define a set of error |
---|
59 | positive are system errors |
---|
60 | (needs work) |
---|
61 | */ |
---|
62 | |
---|
63 | typedef int OCerror; |
---|
64 | #define OC_NOERR (0) |
---|
65 | #define OC_EBADID (-1) |
---|
66 | #define OC_ECHAR (-2) |
---|
67 | #define OC_EDIMSIZE (-3) |
---|
68 | #define OC_EEDGE (-4) |
---|
69 | #define OC_EINVAL (-5) |
---|
70 | #define OC_EINVALCOORDS (-6) |
---|
71 | #define OC_ENOMEM (-7) |
---|
72 | #define OC_ENOTVAR (-8) |
---|
73 | #define OC_EPERM (-9) |
---|
74 | #define OC_ESTRIDE (-10) |
---|
75 | #define OC_EDAP (-11) |
---|
76 | #define OC_EXDR (-12) |
---|
77 | #define OC_ECURL (-13) |
---|
78 | #define OC_EBADURL (-14) |
---|
79 | #define OC_EBADVAR (-15) |
---|
80 | #define OC_EOPEN (-16) |
---|
81 | #define OC_EIO (-17) |
---|
82 | #define OC_ENODATA (-18) |
---|
83 | #define OC_EDAPSVC (-19) |
---|
84 | #define OC_ENAMEINUSE (-20) |
---|
85 | #define OC_EDAS (-21) |
---|
86 | #define OC_EDDS (-22) |
---|
87 | #define OC_EDATADDS (-23) |
---|
88 | #define OC_ERCFILE (-24) |
---|
89 | #define OC_ENOFILE (-25) |
---|
90 | |
---|
91 | /* Define the classes of DAP DXD objects */ |
---|
92 | typedef int OCdxd; |
---|
93 | #define OCDDS 0 |
---|
94 | #define OCDAS 1 |
---|
95 | #define OCDATADDS 2 |
---|
96 | #define OCDATA OCDATADDS |
---|
97 | |
---|
98 | /* Define flags */ |
---|
99 | typedef int OCflags; |
---|
100 | #define OCONDISK 1 |
---|
101 | |
---|
102 | typedef enum OCmode { |
---|
103 | OCNULLMODE = 0, |
---|
104 | OCFIELDMODE = 1, |
---|
105 | OCSEQUENCEMODE = 2, |
---|
106 | OCARRAYMODE = 3, |
---|
107 | OCPRIMITIVEMODE = 4, |
---|
108 | OCEMPTYMODE = 0x8000000 /* internal use only */ |
---|
109 | } OCmode; |
---|
110 | |
---|
111 | |
---|
112 | /* Define an unsigned alternative to off(64)_t*/ |
---|
113 | typedef unsigned long long ocoffset_t; |
---|
114 | |
---|
115 | /* Define a wrapper for dimension sizes */ |
---|
116 | typedef size_t ocindex_t; |
---|
117 | |
---|
118 | /* Define the effective API */ |
---|
119 | |
---|
120 | #ifndef OCINTERNAL_H |
---|
121 | |
---|
122 | /* The OCobject type references a component of a DAS or DDS |
---|
123 | (e.g. Sequence, Grid, Dataset, etc). These objects |
---|
124 | are nested, so most objects reference a container object |
---|
125 | and subnode objects. |
---|
126 | */ |
---|
127 | |
---|
128 | |
---|
129 | #ifdef OC_FASTCONSISTENCY |
---|
130 | /* Use unsigned int * so we can dereference to get magic number */ |
---|
131 | typedef unsigned int* OCobject; |
---|
132 | #define OCNULL NULL |
---|
133 | #else |
---|
134 | typedef unsigned long OCobject; |
---|
135 | #define OCNULL ((OCobject)0) |
---|
136 | #endif |
---|
137 | |
---|
138 | /* These are the two critical types*/ |
---|
139 | /* Think of OClink as analogous to the C stdio FILE structure; |
---|
140 | it "holds" all the other state info about |
---|
141 | a connection to the server, the url request, and the DAS/DDS/DATADDSinfo. |
---|
142 | */ |
---|
143 | /* Renamed from OCconnection because of confusion about term "connection" |
---|
144 | 3/24/2010 by dmh |
---|
145 | */ |
---|
146 | typedef OCobject OClink; |
---|
147 | |
---|
148 | /* Keep old name for back compatibility */ |
---|
149 | typedef OClink OCconnection; /*Deprecated*/ |
---|
150 | |
---|
151 | /* Tag kind of log entry*/ |
---|
152 | #define OCLOGNOTE 0 |
---|
153 | #define OCLOGWARN 1 |
---|
154 | #define OCLOGERR 2 |
---|
155 | #define OCLOGDBG 3 |
---|
156 | |
---|
157 | /**************************************************/ |
---|
158 | |
---|
159 | #ifdef __cplusplus |
---|
160 | extern "C" { |
---|
161 | #endif |
---|
162 | |
---|
163 | extern int oc_dumpnode(OClink conn, OCobject root0); |
---|
164 | |
---|
165 | /**************************************************/ |
---|
166 | /* Link management */ |
---|
167 | |
---|
168 | extern OCerror oc_open(const char* url, OClink*); |
---|
169 | extern OCerror oc_close(OClink); |
---|
170 | |
---|
171 | /**************************************************/ |
---|
172 | /* Root management */ |
---|
173 | /* Fetch and parse a given class of DXD the server specified |
---|
174 | at open time, and using a specified set of constraints |
---|
175 | and flags. |
---|
176 | Return the root node of the parsed tree of objects. |
---|
177 | */ |
---|
178 | extern OCerror oc_fetchf(OClink, |
---|
179 | const char* constraints, |
---|
180 | OCdxd, |
---|
181 | OCflags, |
---|
182 | OCobject* rootp); |
---|
183 | |
---|
184 | |
---|
185 | /* |
---|
186 | Equivalent to oc_fetchf with zero flag parameter |
---|
187 | */ |
---|
188 | extern OCerror oc_fetch(OClink, |
---|
189 | const char* constraints, |
---|
190 | OCdxd, |
---|
191 | OCobject* rootp); |
---|
192 | |
---|
193 | /* Release/reclaim the tree of objects associated with a given root */ |
---|
194 | extern OCerror oc_root_free(OClink, OCobject root); |
---|
195 | |
---|
196 | /* Return the # of OCobjects associated with a tree with specified root */ |
---|
197 | extern unsigned int oc_inq_nobjects(OClink, OCobject root); |
---|
198 | |
---|
199 | /* Return all the OCobjects associated with a tree with specified root */ |
---|
200 | extern OCobject* oc_inq_objects(OClink, OCobject root); |
---|
201 | |
---|
202 | /* Return the text of the DDS or DAS as received from the server */ |
---|
203 | extern const char* oc_inq_text(OClink, OCobject root); |
---|
204 | |
---|
205 | /**************************************************/ |
---|
206 | /* Object Management */ |
---|
207 | |
---|
208 | /* Any of the pointers may be NULL in the following procedure call; |
---|
209 | If the object is of type Dataset, then return # of global attributes |
---|
210 | If the object is of type Attribute, then return the # of values in nattrp. |
---|
211 | The caller must free the resulting name string. |
---|
212 | */ |
---|
213 | extern OCerror oc_inq_object(OClink, OCobject, |
---|
214 | char** namep, |
---|
215 | OCtype* typep, |
---|
216 | OCtype* primitivetypep, /* if objecttype == OC_Primitive */ |
---|
217 | OCobject* parentp, |
---|
218 | unsigned int* rankp, |
---|
219 | unsigned int* nsubnodesp, |
---|
220 | unsigned int* nattrp); |
---|
221 | |
---|
222 | /* Also define some more individual accessors */ |
---|
223 | |
---|
224 | extern OCerror oc_inq_name(OClink,OCobject,char**); |
---|
225 | extern OCerror oc_inq_class(OClink,OCobject,OCtype*); |
---|
226 | extern OCerror oc_inq_type(OClink,OCobject,OCtype*); /*alias for oc_inq_class*/ |
---|
227 | extern OCerror oc_inq_primtype(OClink,OCobject,OCtype*); |
---|
228 | extern OCerror oc_inq_nsubnodes(OClink,OCobject,unsigned int*); |
---|
229 | extern OCerror oc_inq_rank(OClink,OCobject,unsigned int*); |
---|
230 | extern OCerror oc_inq_nattr(OClink,OCobject,unsigned int*); |
---|
231 | extern OCerror oc_inq_root(OClink,OCobject,OCobject*); |
---|
232 | extern OCerror oc_inq_container(OClink,OCobject,OCobject*); |
---|
233 | |
---|
234 | /* Return the subnode objects, if any, associated with a given object. |
---|
235 | Caller must free the returned subnodes memory. |
---|
236 | */ |
---|
237 | extern OCerror oc_inq_subnodes(OClink,OCobject,OCobject** subnodes); |
---|
238 | |
---|
239 | /* Return the i'th subnode object, if any, associated with a given object */ |
---|
240 | /* If there is none such, then return OC_EINVAL */ |
---|
241 | extern OCerror oc_inq_ith(OClink,OCobject, unsigned int, OCobject*); |
---|
242 | |
---|
243 | /* Return the dimension objects, if any, associated with a given object */ |
---|
244 | /* Caller must free returned vector for dimids */ |
---|
245 | /* If there are no dimensions (i.e. rank == 0), then return NULL */ |
---|
246 | extern OCerror oc_inq_dimset(OClink,OCobject, OCobject** dimids); |
---|
247 | |
---|
248 | /* Return the i'th dim object, if any, associated with a given object */ |
---|
249 | /* If there is no such dim, then return OC_EINVAL */ |
---|
250 | extern OCerror oc_inq_ithdim(OClink,OCobject, unsigned int, OCobject*); |
---|
251 | |
---|
252 | /* Return the size and name associated with a given dimension object |
---|
253 | as defined in the DDS |
---|
254 | */ |
---|
255 | extern OCerror oc_inq_dim(OClink,OCobject,ocindex_t*,char**); |
---|
256 | |
---|
257 | /* Attribute Management */ |
---|
258 | |
---|
259 | /* Added: 11/2/2009 DMH: |
---|
260 | Provide access to DDS node attributes |
---|
261 | in the form of the original underlying |
---|
262 | DAS string. |
---|
263 | One specifies the DDS root to get the global attributes. |
---|
264 | Caller must free returned strings. |
---|
265 | */ |
---|
266 | |
---|
267 | extern OCerror oc_inq_attrstrings(OClink,OCobject, unsigned int i, |
---|
268 | char** name, OCtype* octype, |
---|
269 | unsigned int* nvalues,char*** stringvalues); |
---|
270 | |
---|
271 | /* Obtain the attributes associated with a given DDS OCobject. |
---|
272 | One specifies the DDS root to get the global attributes |
---|
273 | This code takes the DAS strings and does a default |
---|
274 | conversion to binary values. |
---|
275 | */ |
---|
276 | extern OCerror oc_inq_attr(OClink,OCobject, unsigned int i, |
---|
277 | char** name,OCtype* octype, |
---|
278 | unsigned int* nvalues,void** values); |
---|
279 | |
---|
280 | /* Convenience function to simplify reclaiming the allocated attribute |
---|
281 | value memory |
---|
282 | */ |
---|
283 | extern void oc_attr_reclaim(OCtype, unsigned int nvalues, void* values); |
---|
284 | |
---|
285 | /* Access ith value string of a DAS object. |
---|
286 | OCtype of the object is assumed to be OC_Attribute. |
---|
287 | Note that this is different than the above inq_attr |
---|
288 | and inq_attrstrings, which work on DDS |
---|
289 | objects. Note also that the return value is always a string. |
---|
290 | Caller must free returned string. |
---|
291 | */ |
---|
292 | |
---|
293 | extern OCerror oc_inq_dasattr_nvalues(OClink, OCobject, |
---|
294 | unsigned int* nvaluesp); |
---|
295 | |
---|
296 | extern OCerror oc_inq_dasattr(OClink,OCobject, unsigned int, |
---|
297 | OCtype* primtypep, char** valuep); |
---|
298 | |
---|
299 | /**************************************************/ |
---|
300 | /* Data management */ |
---|
301 | |
---|
302 | /* |
---|
303 | These procedures allow for the location and extraction |
---|
304 | of data from the data packet part of a DATADDS. |
---|
305 | See ocuserman.html for detailed description. |
---|
306 | */ |
---|
307 | |
---|
308 | typedef OCobject OCdata; |
---|
309 | |
---|
310 | /* Obtain the OCdata object that references the |
---|
311 | whole data from a DATADDS fetch request specified |
---|
312 | by the root object. This does not access the server. |
---|
313 | */ |
---|
314 | extern OCerror oc_data_root(OClink, OCobject root, OCdata); |
---|
315 | |
---|
316 | /* Create an empty OCdata object */ |
---|
317 | extern OCdata oc_data_new(OClink); |
---|
318 | |
---|
319 | /* Reclaim a no longer needed OCdata object */ |
---|
320 | extern OCerror oc_data_free(OClink, OCdata); |
---|
321 | |
---|
322 | /* Given an OCdata object, set the nested subnode OCdata object |
---|
323 | to refer to the data associated with the i'th element of |
---|
324 | the parent data object. NOTE: if the i'th element is not |
---|
325 | present then this function will return OC_ENODATA. |
---|
326 | See the user's manual for details on mapping multi- |
---|
327 | dimensional arrays to single indices. |
---|
328 | */ |
---|
329 | extern OCerror oc_data_ith(OClink, |
---|
330 | OCdata parentdata, |
---|
331 | ocindex_t index, |
---|
332 | OCdata subdata); |
---|
333 | |
---|
334 | /* Return the actual data values associated with the specified OCdata. |
---|
335 | The OCdata is assumed to be referencing either a scalar |
---|
336 | primitive value or a (1d) array of primitive values. |
---|
337 | If scalar, then index must be 0 and count must be 1. |
---|
338 | */ |
---|
339 | extern OCerror oc_data_get(OClink,OCdata, |
---|
340 | void* memory, size_t memsize, |
---|
341 | ocindex_t index, ocindex_t count); |
---|
342 | |
---|
343 | /* Return the OCdata's current index */ |
---|
344 | extern OCerror oc_data_index(OClink,OCdata, ocindex_t*); |
---|
345 | |
---|
346 | /* Return the mode associated the specified OCdata object */ |
---|
347 | extern OCerror oc_data_mode(OClink,OCdata, OCmode*); |
---|
348 | |
---|
349 | /* Return the OCobject associated the specified OCdata object */ |
---|
350 | extern OCerror oc_data_object(OClink,OCdata, OCobject*); |
---|
351 | |
---|
352 | /* Compute the the count associated with the specified OCdata |
---|
353 | instance. Note: this is potentially computationally costly |
---|
354 | when computing # records. |
---|
355 | */ |
---|
356 | extern OCerror oc_data_count(OClink, OCdata, ocindex_t*); |
---|
357 | |
---|
358 | /**************************************************/ |
---|
359 | /* Misc. OCtype-related functions */ |
---|
360 | |
---|
361 | /* Return size of the given type (Primitive only) */ |
---|
362 | extern size_t oc_typesize(OCtype); |
---|
363 | |
---|
364 | /* Return a canonical printable string describing a given type: |
---|
365 | e.g. Byte, Int16, etc. |
---|
366 | */ |
---|
367 | extern const char* oc_typetostring(OCtype); |
---|
368 | |
---|
369 | /* Given a value of a primitive OC type, provide a canonical |
---|
370 | string representing that value |
---|
371 | */ |
---|
372 | extern OCerror oc_typeprint(OCtype, char* buf, size_t bufsize, void* value); |
---|
373 | |
---|
374 | /**************************************************/ |
---|
375 | /* Logging */ |
---|
376 | |
---|
377 | extern void oc_loginit(void); |
---|
378 | extern void oc_setlogging(int onoff); /* 1=>start logging 0=>stop */ |
---|
379 | extern void oc_logopen(const char* logfilename); |
---|
380 | extern void oc_logclose(void); |
---|
381 | |
---|
382 | extern void oc_logtext(int tag, const char* text); |
---|
383 | |
---|
384 | extern void oc_log(int tag, const char* fmt, ...); |
---|
385 | |
---|
386 | /**************************************************/ |
---|
387 | /* Miscellaneous */ |
---|
388 | |
---|
389 | /* Convert an OCerror to a human readable string */ |
---|
390 | extern const char* oc_errstring(int err); |
---|
391 | |
---|
392 | /* Get client parameters from the URL |
---|
393 | DO NOT free the result |
---|
394 | */ |
---|
395 | extern const char* oc_clientparam_get(OClink, const char* param); |
---|
396 | |
---|
397 | extern OCerror oc_clientparam_delete(OClink, const char* param); |
---|
398 | extern OCerror oc_clientparam_insert(OClink, const char* param, const char* value); |
---|
399 | extern OCerror oc_clientparam_replace(OClink, const char* param, const char* value); |
---|
400 | |
---|
401 | /**************************************************/ |
---|
402 | /* Merging operations */ |
---|
403 | |
---|
404 | /* Merge a specified DAS into a specified DDS or DATADDS */ |
---|
405 | extern OCerror oc_attach_das(OClink, OCobject dasroot, OCobject ddsroot); |
---|
406 | |
---|
407 | /**************************************************/ |
---|
408 | /* Debugging */ |
---|
409 | extern OCerror oc_dd(OClink,OCobject,int level); |
---|
410 | extern OCerror oc_ddnode(OClink,OCobject); |
---|
411 | |
---|
412 | /* When a server error is detected, then it is possible |
---|
413 | to get the server error info using this procedure */ |
---|
414 | extern OCerror oc_svcerrordata(OClink link, char** codep, |
---|
415 | char** msgp, long* httpp); |
---|
416 | |
---|
417 | |
---|
418 | |
---|
419 | /**************************************************/ |
---|
420 | /* Experimental */ |
---|
421 | |
---|
422 | /* New 10/31/2009: return raw information about a datadds |
---|
423 | */ |
---|
424 | |
---|
425 | extern OCerror oc_raw_xdrsize(OClink, OCobject, size_t*); |
---|
426 | |
---|
427 | /* Resend a url as a head request to check the Last-Modified time */ |
---|
428 | extern OCerror oc_update_lastmodified_data(OClink); |
---|
429 | |
---|
430 | /* Get last known modification time; -1 => data unknown */ |
---|
431 | extern long oc_get_lastmodified_data(OClink); |
---|
432 | |
---|
433 | extern OCerror oc_ping(const char* url); |
---|
434 | |
---|
435 | /**************************************************/ |
---|
436 | |
---|
437 | #endif /*OCINTERNAL_H*/ |
---|
438 | |
---|
439 | #ifdef __cplusplus |
---|
440 | } |
---|
441 | #endif |
---|
442 | |
---|
443 | #endif /*OC_H*/ |
---|