[409] | 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*/ |
---|