1/* Copyright 2014, UCAR/Unidata and OPeNDAP, Inc.
2   See the COPYRIGHT dap for more information. */
3
4/*
5OC External Interface
6Created: 4/4/2009
7Last Revised: 12/23/2014
8Version: 2.1
9*/
10
11#ifndef OC_H
12#define OC_H
13
14#include <stdlib.h>
15#include <stdio.h>
16#ifdef HAVE_SYS_TYPES_H
17#include <sys/types.h>
18#endif
19
20/*!\file oc.h
21*/
22
23/*!\defgroup Definitions Constants, types, etc.
24@{*/
25
26/*! OC_MAX_DIMS is the maximum allowable
27number of dimensions.
28Ideally, it should be greater or equal to max allowed by dap or netcdf
29*/
30#define OC_MAX_DIMENSIONS 1024
31
32/*!\enum OCdxd
33Define the legal kinds of fetch: DAS, DDS, or DataDDS
34*/
35typedef enum OCdxd {
36OCDDS=0,
37OCDAS=1,
38OCDATADDS=2
39OCdxd;
40
41/*!\def OCDATA
42Define an alias for OCDATADDS
43*/
44#define OCDATA OCDATADDS
45
46/*!
47\typedef OCflags
48Define flags for oc_fetch.
49*/
50typedef int OCflags;
51/*!\def OCONDISK
52Cause oc_fetch to store the retrieved data on disk.
53*/
54
55#define OCONDISK 1
56
57/**************************************************/
58/* OCtype */
59
60/*!\enum OCtype
61Define the set of legal types. The set is divided
62into two parts. The atomic types define
63leaf nodes of the DDS. The non-atomic types
64are used to tag internal nodes of the DDS tree.
65*/
66typedef enum OCtype {
67/* Atomic Types */
68/* OC_Ubyte, OC_Char, OC_Int64 and OC_UInt64 are defined for future extension*/
69OC_NAT=0,
70OC_Char=1,
71OC_Byte=2,
72OC_UByte=3,
73OC_Int16=4,
74OC_UInt16=5,
75OC_Int32=6,
76OC_UInt32=7,
77OC_Int64=8,
78OC_UInt64=9,
79OC_Float32=10,
80OC_Float64=11,
81OC_String=12,
82OC_URL=13,
83
84/* Non-Atomic Types */
85OC_Atomic=100,
86OC_Dataset=101,
87OC_Sequence=102,
88OC_Grid=103,
89OC_Structure=104,
90OC_Dimension=105,
91OC_Attribute=106,
92OC_Attributeset=107,
93OC_Map=108,
94OC_Group=109,
95OCtype;
96
97/*!\enum OCerror
98Define the set of error return codes.
99The set consists of oc errors (negative
100values) plus the set of system errors, which
101are positive.
102*/
103typedef enum OCerror {
104OC_NOERR=0,
105OC_EBADID=-1,
106OC_ECHAR=-2,
107OC_EDIMSIZE=-3,
108OC_EEDGE=-4,
109OC_EINVAL=-5,
110OC_EINVALCOORDS=-6,
111OC_ENOMEM=-7,
112OC_ENOTVAR=-8,
113OC_EPERM=-9,
114OC_ESTRIDE=-10,
115OC_EDAP=-11,
116OC_EXDR=-12,
117OC_ECURL=-13,
118OC_EBADURL=-14,
119OC_EBADVAR=-15,
120OC_EOPEN=-16,
121OC_EIO=-17,
122OC_ENODATA=-18,
123OC_EDAPSVC=-19,
124OC_ENAMEINUSE=-20,
125OC_EDAS=-21,
126OC_EDDS=-22,
127OC_EDATADDS=-23,
128OC_ERCFILE=-24,
129OC_ENOFILE=-25,
130OC_EINDEX=-26,
131OC_EBADTYPE=-27,
132OC_ESCALAR=-28,
133OC_EOVERRUN=-29,
134OC_EAUTH=-30,
135OCerror;
136
137/*!\def OCLOGNOTE
138Tag a log entry as a note.
139*/
140#define OCLOGNOTE 0
141/*!\def OCLOGWARN
142Tag a log entry as a warning.
143*/
144#define OCLOGWARN 1
145/*!\def OCLOGERR
146Tag a log entry as an error.
147*/
148#define OCLOGERR  2
149/*!\def OCLOGDBG
150Tag a log entry as a debug note.
151*/
152#define OCLOGDBG  3
153
154/**************************************************/
155/* Define the opaque types */
156
157/*!\typedef OCobject
158Define a common opaque type.
159*/
160typedef void* OCobject;
161
162/*!\typedef OCddsnode
163The OCddsnode type provide a reference
164to a component of a DAS or DDS tree:
165e.g. Sequence, Grid, Dataset, etc.
166These objects
167are nested, so most objects reference a container object
168and subnode objects. The term ddsnode is slightly misleading
169since it also covers DAS nodes.
170*/
171
172typedef OCobject OCddsnode;
173
174/*!\typedef OCdasnode
175The OCdasnode is a alias for OCddsnode.
176*/
177
178typedef OCddsnode OCdasnode;
179
180/* Data data type */
181/*!\typedef OCdatanode
182The OCdatanode type provide a reference
183to a specific piece of data in the data
184part of a Datadds.
185*/
186typedef OCobject OCdatanode;
187
188/*!\typedef OClink
189Think of OClink as analogous to the C stdio FILE structure;
190it "holds" all the other state info about
191a connection to the server, the url request, and the DAS/DDS/DATADDSinfo.
1923/24/210: Renamed from OCconnection because of confusion about
193term "connection"
194*/
195typedef OCobject OClink;
196
197/**@}*/
198
199/**************************************************/
200/* External API */
201
202#ifdef __cplusplus
203extern "C" {
204#endif
205
206/**************************************************/
207/* Link management */
208
209extern OCerror oc_open(const char* urlOClink*);
210extern OCerror oc_close(OClink);
211
212/**************************************************/
213/* Tree Management */
214
215extern OCerror oc_fetch(OClink,
216 const char* constraint,
217 OCdxd,
218 OCflags,
219 OCddsnode*);
220
221extern OCerror oc_root_free(OClinkOCddsnode root);
222extern const char* oc_tree_text(OClinkOCddsnode root);
223
224/**************************************************/
225/* Node Management */
226
227extern OCerror oc_dds_properties(OClinkOCddsnode,
228   char** namep,
229   OCtypetypep,
230   OCtypeatomictypep, /* if octype == OC_Atomic */
231   OCddsnodecontainerp,  /* NULL if octype == OC_Dataset */
232   size_t* rankp,       /* 0 if scalar */
233   size_t* nsubnodesp,
234   size_t* nattrp);
235
236/* Define some individual accessors for convenience */
237
238extern OCerror oc_dds_name(OClink,OCddsnode,char**);
239extern OCerror oc_dds_class(OClink,OCddsnode,OCtype*);
240extern OCerror oc_dds_atomictype(OClink,OCddsnode,OCtype*);
241extern OCerror oc_dds_nsubnodes(OClink,OCddsnode,size_t*);
242extern OCerror oc_dds_rank(OClink,OCddsnode,size_t*);
243extern OCerror oc_dds_attr_count(OClink,OCddsnode,size_t*);
244extern OCerror oc_dds_root(OClink,OCddsnode,OCddsnode*);
245extern OCerror oc_dds_container(OClink,OCddsnode,OCddsnode*);
246
247/* Aliases */
248#define oc_dds_octype oc_dds_class
249#define oc_dds_type oc_dds_class
250
251/* Get the i'th field of the given (container) node; return OC_EINDEX
252   if there is no such node; return OC_EBADTYPE if node is not
253   a container
254*/
255extern OCerror oc_dds_ithfield(OClinkOCddsnode, size_t indexOCddsnodeithfieldp);
256
257/* Alias for oc_dds_ithfield */
258extern OCerror oc_dds_ithsubnode(OClinkOCddsnode, size_t, OCddsnode*);
259
260/* Convenience functions that are just combinations of ithfield with other functions */
261
262/* Return the grid array dds node from the specified grid node*/
263extern OCerror oc_dds_gridarray(OClinkOCddsnode gridOCddsnodearrayp);
264
265/* Return the i'th grid map dds node from the specified grid dds node.
266   NOTE: Map indices start at ZERO.
267*/
268extern OCerror oc_dds_gridmap(OClinkOCddsnode grid, size_t indexOCddsnodemapp);
269
270/* Retrieve a dds node by name from a dds structure or dataset node.
271   return OC_EBADTYPE if node is not a container,
272   return OC_EINDEX if no field by the given name is found.
273*/
274extern OCerror oc_dds_fieldbyname(OClinkOCddsnode, const char* nameOCddsnodefieldp);
275
276
277/* Return the dimension nodes, if any, associated with a given DDS node */
278/* Caller must allocate and free the vector for dimids */
279/* If the node is scalar, then return OC_ESCALAR. */
280extern OCerror oc_dds_dimensions(OClinkOCddsnodeOCddsnodedimids);
281
282/* Return the i'th dimension node, if any, associated with a given object */
283/* If there is no such dimension, then return OC_EINVAL */
284extern OCerror oc_dds_ithdimension(OClink,OCddsnode, size_t, OCddsnode*);
285
286/* Return the size and name associated with a given dimension object
287   as defined in the DDS
288*/
289extern OCerror oc_dimension_properties(OClink,OCddsnode,size_t*,char**);
290
291/* For convenience, return only the dimension sizes */
292extern OCerror oc_dds_dimensionsizes(OClink,OCddsnode,size_t* dimsizes);
293
294/* Attribute Management */
295
296/* Obtain the attributes associated with a given DDS OCddsnode.
297   One specifies the DDS root to get the global attributes
298   The actual attribute strings are returned and the user
299   must do any required conversion based on the octype.
300   The strings vector must be allocated and freed by caller,
301   The contents of the strings vector must also be reclaimed
302   using oc_attr_reclaim(see below).
303   Standard practice is to call twice, once with the strings
304   argument == NULL so we get the number of values,
305   then the second time with an allocated char** vector.
306
307*/
308extern OCerror oc_dds_attr(OClink,OCddsnode, size_t i,
309     char** nameOCtypeoctype,
310     size_t* nvalues, char** strings);
311
312
313/* Access ith value string of a DAS OC_Attribute object.
314   OCddsnode of the object is assumed to be OC_Attribute.
315   Note that this is  different than the above oc_dds_attr
316   that works on DDS nodes.
317   Note also that the return value is always a string.
318   Caller must free returned string.
319*/
320
321extern OCerror oc_das_attr_count(OClinkOCddsnode, size_t* countp);
322
323extern OCerror oc_das_attr(OClink,OCddsnode, size_t, OCtype*, char**);
324
325/**************************************************/
326/* Free up a ddsnode that is no longer being used */
327extern OCerror oc_dds_free(OClinkOCddsnode);
328
329/**************************************************/
330/* Data Procedures */
331
332/* Given the DDS tree root, get the root data of datadds */
333extern OCerror oc_dds_getdataroot(OClinkOCddsnode treerootOCdatanoderootp);
334
335/* Alias for oc_dds_getdataroot */
336#define oc_data_getroot oc_dds_getdataroot
337
338/* Return the data of the container for the specified data.
339   If it does not exist, then return NULL.
340   In effect this procedure allows one to walk up the datatree one level.
341*/
342extern OCerror oc_data_container(OClinkOCdatanode dataOCdatanodecontainerp);
343
344/* Return the root node of the data tree that contains the specified data node.
345   In effect this procedure allows one to walk to the root of the datatree
346   containing the specified datanode.
347*/
348extern OCerror oc_data_root(OClinkOCdatanode dataOCdatanoderootp);
349
350/*
351There are multiple ways to walk down a level in a data tree
352depending on what kind of node we are currently visiting.
353The possibilities are:
3541. current node is the data for a structure or dataset node:
355   => oc_data_ithfield -- get the data node corresponding
356                          to the ith field of the structure
3572. current node is the data for a grid node:
358   => oc_data_gridarray -- get the data node for the grid array
359   => oc_data_gridmap -- get the data node for the ith grid map
3603. current node is the data for an array of structures
361   => oc_data_ithelement -- get the data node corresponding to
362                            the i'th structure in the array
363                            If the structure is scalar, then the indices
364                            are ignored.
3654. current node is the data for a sequence
366   => oc_data_ithrecord -- get the data node corresponding to
367                            the i'th record in the sequence
368
369Note that the above only apply to compound objects. Once
370you have the data node for an atomic types object (dimensioned
371or scalar), you can read its contents using oc_data_read
372or oc_data_readscalar.
373*/
374
375/* Return the data node for the i'th field of the specified container data */
376extern OCerror oc_data_ithfield(OClinkOCdatanode container, size_t index,
377                                OCdatanodefieldp);
378
379/* Retrieve the data node by name from a container data node */
380extern OCerror oc_dat_fieldbyname(OClinkOCdatanode, const char* nameOCdatanodefieldp);
381
382/* Return the grid array data for the specified grid data */
383extern OCerror oc_data_gridarray(OClinkOCdatanode gridOCdatanodearrayp);
384
385/* Return the i'th grid map data for the specified grid data.
386   NOTE: Map indices start at ZERO.
387*/
388extern OCerror oc_data_gridmap(OClinkOCdatanode grid, size_t indexOCdatanodemapp);
389
390/* Return the data of a dimensioned Structure corresponding
391   to the element specified by the indices.
392*/
393extern OCerror oc_data_ithelement(OClinkOCdatanode data, size_t* indicesOCdatanodeelementp);
394
395/* Return the i'th record data of a Sequence data. */
396extern OCerror oc_data_ithrecord(OClinkOCdatanode data, size_t indexOCdatanoderecordp);
397
398/* Free up an data that is no longer being used */
399extern OCerror oc_data_free(OClinkOCdatanode data);
400
401/* Count the records associated with a sequence */
402extern OCerror oc_data_recordcount(OClinkOCdatanode, size_t*);
403
404/* Return the actual data values associated with the specified leaf data.
405   The OCdatanode is assumed to be referencing a leaf node that is
406   either a atomic valued scalar or array.
407   If scalar, then index and count are ignored.
408   Caller is responsible for allocating memory(of proper size)
409   and free'ing it.
410   See also oc_dds_read().
411*/
412extern OCerror oc_data_read(OClinkOCdatanode, size_t*, size_t*, size_t, void*);
413
414/* Like oc_data_read, but for reading a scalar.
415   Caller is responsible for allocating memory(of proper size)
416   and free'ing it.
417   See also oc_dds_readscalar().
418*/
419extern OCerror oc_data_readscalar(OClinkOCdatanode, size_t, void*);
420
421/* Like oc_data_read, but caller provides a starting set of indices
422   and count of the number of elements to read.
423   Caller is responsible for allocating memory(of proper size)
424   and free'ing it.
425   See also oc_dds_readn().
426*/
427extern OCerror oc_data_readn(OClinkOCdatanode, size_t*, size_t, size_t, void*);
428
429/* Return the indices for this datas; Assumes the data
430   was obtained using oc_data_ithelement or oc_data_ithrecord;
431   if not, then an error is returned.
432*/
433extern OCerror oc_data_position(OClinkOCdatanode data, size_t* indices);
434
435/* Return the pattern dds node for an data */
436extern OCerror oc_data_ddsnode(OClinkOCdatanode dataOCddsnode*);
437
438/* Return the octype of the data (convenience) */
439extern OCerror oc_data_octype(OClinkOCdatanode dataOCtype*);
440
441/* Return 1 if the specified data has a valid index, 0 otherwise.
442   Valid index means it was created using
443   oc_data_ithelement or oc_data_ithrecord.
444*/
445extern int oc_data_indexed(OClink linkOCdatanode datanode);
446
447/* Return 1 if the specified data has a valid index, 0 otherwise.
448   Valid index means it was created using
449   oc_data_ithelement or oc_data_ithrecord.
450*/
451extern int oc_data_indexed(OClinkOCdatanode);
452
453/* Return 1 if the specified data can be indexed
454   Indexable means the data is pointing to
455   an indexed structure or to a sequence.
456*/
457extern int oc_data_indexable(OClinkOCdatanode);
458
459/**************************************************/
460/*
461For top-level, atomic variables, it is possible to directly
462read the associated data without having to use the oc_data_XXX
463procedures. Provide special procedures to support this.
464*/
465
466/* See oc_data_read for semantics */
467extern OCerror oc_dds_read(OClinkOCddsnode, size_t*, size_t*, size_t, void*);
468
469/* See oc_data_readscalar for semantics */
470extern OCerror oc_dds_readscalar(OClinkOCddsnode, size_t, void*);
471
472/* See oc_data_readn for semantics */
473extern OCerror oc_dds_readn(OClinkOCddsnode, size_t*, size_t, size_t, void*);
474
475/**************************************************/
476/* Misc. OCtype-related functions */
477
478/* Return size of the given type(Atomic only) */
479extern size_t oc_typesize(OCtype);
480
481/* Return a canonical printable string describing a given type:
482   e.g. Byte, Int16, etc.
483*/
484extern const char* oc_typetostring(OCtype);
485
486/* Given a value of a atomic OC type, provide a canonical
487   string representing that value; mostly for debugging.
488*/
489extern OCerror oc_typeprint(OCtype, void* value, size_t bufsize, char* buf);
490
491/**************************************************/
492/* Logging */
493
494extern void oc_loginit(void);
495extern int  oc_setlogging(int onoff); /* 1=>start logging 0=>stop */
496extern int  oc_logopen(const char* logfilename);
497extern void oc_logclose(void);
498
499extern void oc_log(int tag, const char* fmt, ...);
500
501extern void oc_logtext(int tag, const char* text);
502
503/**************************************************/
504/* Miscellaneous */
505
506/* Reclaim the strings within a string vector, but not the vector itself.
507   This is useful for reclaiming the result of oc_data_read
508   or oc_dds_attr when the type is OC_String or OC_URL.
509   Note that only the strings are reclaimed, the string vector
510   is not reclaimed because it was presumably allocated by the client.
511*/
512extern void oc_reclaim_strings(size_t n, char** svec);
513
514/* Convert an OCerror to a human readable string */
515extern const char* oc_errstring(OCerror err);
516
517/* Get client parameters from the URL
518   DO NOT free the result
519*/
520extern const char* oc_clientparam_get(OClink, const char* param);
521
522/**************************************************/
523/* Merging operations */
524
525/* Merge a specified DAS into a specified DDS or DATADDS */
526extern OCerror oc_merge_das(OClinkOCddsnode dasrootOCddsnode ddsroot);
527
528/**************************************************/
529/* Debugging */
530
531/* When a server error is detected, then it is possible
532   to get DODS supplied server error info using this procedure */
533extern OCerror oc_svcerrordata(OClink link, char** codep,
534                               char** msgp, long* httpp);
535
536/* Get the HTTP return code from the last call;
537   note that this may or may not be the same as returned
538   by oc_svcerrordata.
539 */
540extern int oc_httpcode(OClink);
541
542/*
543(Re-)initialize the oc library as if nothing had been called.
544This is primarily for debugging of rc files.
545*/
546extern OCerror oc_initialize(void);
547
548/**************************************************/
549/* Curl options */
550/* This is here because trial and error shows that
551   libcurl shows thru too much. So bow to the inevitable.
552*/
553
554/*Cause the curl library to be verbose and save error messages*/
555extern OCerror oc_trace_curl(OClink link);
556
557/* Allow specification of the rc file */
558extern OCerror oc_set_rcfile(const char* filepath);
559
560/* Allow specification of the netrc file */
561extern OCerror oc_set_netrc(OClink*, const char* filepath);
562
563/* Set arbitrary curl option */
564extern OCerror oc_set_curlopt(OClink link, const char* option, void* value);
565
566/**************************************************/
567/* Experimental/Undocumented */
568
569/* Given an arbitrary OCnode, return the connection of which it is a part */
570extern OCerror oc_get_connection(OCobject ocnodeOCobjectlinkp);
571
572/* Resend a url as a head request to check the Last-Modified time */
573extern OCerror oc_update_lastmodified_data(OClink);
574
575/* Get last known modification time; -1 => data unknown */
576extern long oc_get_lastmodified_data(OClink);
577
578/* Test if a given url responds to a DAP protocol request */
579extern OCerror oc_ping(const char* url);
580
581/* Return the size of the in-memory or on-disk
582   data chunk returned by the server for a given tree.
583   Zero implies it is not defined.
584*/
585/* For some reason, the MSVC compiler doesn't like this. */
586#ifndef _WIN32
587extern OCerror oc_raw_xdrsize(OClink,OCddsnode,off_t*);
588#endif
589
590#ifdef __cplusplus
591}
592#endif
593
594#endif /*OC_H*/


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed