DRAMA C++ Intro   Class Hierarchy   Alphabetical List of types   List of Classes   File List   Class Member Index   File Members Index   Related Pages  

sds.h

00001 /*
00002  * Name: filter.m4
00003  *
00004  * Description:
00005  *     DOXYGEN Input file filter for DRAMA source files.
00006  *
00007  *     This file must be complatible with both Solaris and GNU m4.  All
00008  *     unused macros are deleted and this comment must end up as a C/C++
00009  *     compatible comment which is not picked up by DOXYGEN.
00010  * 
00011  * Synopsis:
00012  *    DCF(func)  => Produces a link to a DRAMA C source file func.html 
00013  *                   in ../routines.
00014  *     DDL(link,text) => Produce a link to ../link.html, specified link text.
00015  *
00016  * Language: m4 macro. 
00017  *
00018  * Author: Tony Farrell, AAO.
00019  *
00020  * "@(#) $Id: ACMM:DramaHtml/filter.m4,v 3.24 03-Nov-2009 09:07:29+11 tjf $"
00021  *
00022  * History:
00023  *     10-Nov-2004 - TJF - Original Version.
00024  */
00025 
00026 
00027 
00028 /*  SDS Include file                                         */
00029 /*                                                           */
00030 /*  Jeremy Bailey      1998  Jul 13                          */
00031 /*                                                           */
00032 /*     @(#) $Id: ACMM:sds/sds.h,v 3.48 02-Nov-2009 14:50:59+11 tjf $                        */
00033 /*                                                           */
00034 /*                                                           */
00035 /*                                                           */
00036 
00037 /*
00038  * This file now uses DOXYGEN comments to generate the C++ web pages.
00039  * m4 macros of the form @htmlonly <a href="../routines/function.html">function()</a>@endhtmlonly are used in the comments
00040  * to refer to DRAMA C function documention (see DramaHtml/Makefile,
00041  * DramaHtml/doxygen.config and DramaHtml/filter.m4 for detials)
00042  */
00043 #ifndef _SDS_INCLUDE_
00044 #define _SDS_INCLUDE_ 1
00045 
00046 #include "sdsport.h"
00047 #include "status.h"
00048 
00049 #ifdef __cplusplus
00050 extern "C" {
00051 #endif
00052 
00058 #define SDS_VERSION 100
00059 
00060 /*    Status codes  */
00061 
00062 #include "sds_err.h"
00063 
00064 /*    Type codes   */
00065 
00066 #define SDS_STRUCT   0              /*  Structure   */
00067 #define SDS_CHAR     1              /*  Character   */
00068 #define SDS_UBYTE    2              /*  Unsigned byte */
00069 #define SDS_BYTE     3              /*  byte          */
00070 #define SDS_USHORT   4              /*  Unsigned short */
00071 #define SDS_SHORT    5              /*  short  */
00072 #define SDS_UINT     6              /*  Unsigned int  */
00073 #define SDS_INT      7              /*  int  */
00074 #define SDS_FLOAT    8              /*  float  */
00075 #define SDS_DOUBLE   9              /*  double  */
00076 #define SDS_I64      11             /*  Int 64  */
00077 #define SDS_UI64     12             /*  Unsigned Int 64  */
00078 #define SDS_C_MAXCODE SDS_UI64      /* The maximum code value */
00079 
00080 /*  Name length  */
00081 
00082 #define SDS_C_NAMELEN 16
00083 
00084 #define SDS_C_MAXARRAYDIMS 7
00085 
00086 #define SDS_WATCH_EVENT_FREE        0
00087 #define SDS_WATCH_EVENT_DELETE      1
00088 #define SDS_WATCH_EVENT_READFREE    2
00089 #define SDS_WATCH_EVENT_NEW         3
00090 #define SDS_WATCH_EVENT_COPY        4
00091 #define SDS_WATCH_EVENT_INSERT      5
00092 #define SDS_WATCH_EVENT_INSERT_CELL 6
00093 #define SDS_WATCH_EVENT_EXTRACT     7
00094 #define SDS_WATCH_EVENT_RESIZE      8
00095 #define SDS_WATCH_EVENT_NEWID       9
00096 
00097 typedef long  SdsIdType;
00098 
00099 typedef long  SdsCodeType;
00100 
00101 typedef void (*SdsWatchRoutineType)(SdsIdType, void *, int reserved);
00102 
00103 SDSEXTERN void SdsSetWatch(SdsIdType id,
00104                            SdsWatchRoutineType watchRoutine,
00105                            void * clientData,
00106                            SdsIdType *oldId,
00107                            SdsWatchRoutineType *oldWatchRoutine,
00108                            void ** oldClientData,
00109                            StatusType * SDSCONST status);
00110 
00111 SDSEXTERN void SdsCreate(SDSCONST char *name, long nextra, SDSCONST char *extra, 
00112                 SdsIdType *id, StatusType * SDSCONST status);
00113 
00114 SDSEXTERN void SdsInfo(SdsIdType id,char *name, SdsCodeType *code, long *ndims, 
00115                unsigned long* dims, StatusType * SDSCONST status);
00116 
00117 SDSEXTERN void SdsNew(SdsIdType parent_id, SDSCONST char *name, long nextra, 
00118                SDSCONST char *extra, SdsCodeType code, long ndims,  
00119                SDSCONST unsigned long *dims, 
00120                SdsIdType *id, StatusType * SDSCONST status);
00121 
00122 SDSEXTERN int SdsIsDefined(SdsIdType parent_id, StatusType * SDSCONST status);
00123 
00124 SDSEXTERN void SdsIndex(SdsIdType parent_id, long index, SdsIdType *id, StatusType * SDSCONST status);
00125 
00126 SDSEXTERN void SdsFind(SdsIdType parent_id, SDSCONST char *name, SdsIdType *id, StatusType * SDSCONST status);
00127 
00128 SDSEXTERN void SdsFindByPath(SdsIdType parent_id, SDSCONST char *name, SdsIdType *id, StatusType * SDSCONST status);
00129 
00130 SDSEXTERN void SdsPointer(SdsIdType id, void **data, unsigned long *length, StatusType * SDSCONST status);
00131 
00132 SDSEXTERN void SdsGet(SdsIdType id, unsigned long length, unsigned long offset, 
00133         void *data, unsigned long *actlen, StatusType * SDSCONST status);
00134 
00135 SDSEXTERN void SdsPut(SdsIdType id, unsigned long length, unsigned long offset, 
00136                 SDSCONST void *data,  StatusType * SDSCONST status);
00137 
00138 
00139 SDSEXTERN void SdsCell(SdsIdType array_id, long nindices, 
00140                 SDSCONST unsigned long *indices, 
00141                 SdsIdType *id, StatusType * SDSCONST status);
00142 
00143 
00144 SDSEXTERN void SdsInsertCell(SdsIdType array_id, long nindices, 
00145                 SDSCONST unsigned long *indices, 
00146                 SdsIdType id, StatusType * SDSCONST status);
00147 
00148 SDSEXTERN void SdsDelete(SdsIdType id, StatusType * SDSCONST status);
00149 
00150 SDSEXTERN void SdsSize(SdsIdType id, unsigned long *bytes, StatusType * SDSCONST status);
00151 SDSEXTERN void SdsExport(SdsIdType id, unsigned long length, void *data, StatusType * SDSCONST status);
00152 
00153 SDSEXTERN void SdsImport(SDSCONST void *data, SdsIdType *id, 
00154                         StatusType * SDSCONST status);
00155 
00156 SDSEXTERN void SdsAccess(void *data, SdsIdType *id, StatusType * SDSCONST status);
00157 
00158 SDSEXTERN void SdsExtract(SdsIdType id, StatusType * SDSCONST status);
00159 
00160 SDSEXTERN void SdsInsert(SdsIdType parent_id, SdsIdType id, StatusType * SDSCONST status);
00161 
00162 SDSEXTERN void SdsCopy(SdsIdType id, SdsIdType *copy_id, StatusType * SDSCONST status);
00163 
00164 SDSEXTERN void SdsResize(SdsIdType id, long ndims, SDSCONST unsigned long *dims,
00165                  StatusType * SDSCONST status);
00166 
00167 SDSEXTERN void SdsRename(SdsIdType id, SDSCONST char* name, StatusType * SDSCONST status);
00168 
00169 SDSEXTERN void SdsGetExtra(SdsIdType id, long length, char* extra, unsigned long *actlen, 
00170 StatusType * SDSCONST status);
00171 
00172 SDSEXTERN void SdsPutExtra(SdsIdType id, long length, SDSCONST char *extra, 
00173                                         StatusType * SDSCONST status);
00174     
00175 SDSEXTERN void SdsExportDefined(SdsIdType id, unsigned long length, void *data, StatusType * SDSCONST status);    
00176       
00177 SDSEXTERN void SdsSizeDefined(SdsIdType id, unsigned long *bytes, StatusType * SDSCONST status);
00178 
00179 SDSEXTERN void SdsIsExternal(SdsIdType id, int *external, StatusType * SDSCONST status);
00180 
00181 SDSEXTERN void SdsGetExternInfo(SdsIdType id, void **data, StatusType * SDSCONST status);
00182            
00183 SDSEXTERN void SdsList(SdsIdType id, StatusType * SDSCONST status);
00184 
00185 SDSEXTERN void SdsWrite(SdsIdType id, SDSCONST char *filename, StatusType * SDSCONST status);
00186 
00187 SDSEXTERN void SdsFreeId(SdsIdType id, StatusType * SDSCONST status);
00188 
00189 SDSEXTERN void SdsFlush(SdsIdType id, StatusType * SDSCONST status);
00190 
00191 SDSEXTERN void SdsRead(SDSCONST char *filename, SdsIdType *id, StatusType * SDSCONST status);
00192 
00193 SDSEXTERN void SdsFillArray(SdsIdType array_id, SdsIdType elem_id,
00194                 StatusType * SDSCONST status);
00195 
00196 
00197 SDSEXTERN void SdsReadFree(SdsIdType id, StatusType * SDSCONST status);
00198 SDSEXTERN SDSCONST char *SdsTypeToStr(SdsCodeType code, int mode);
00199 SDSEXTERN void SdsFindByName( SdsIdType parent_id,  
00200                     SDSCONST char * name, 
00201                     unsigned int * skip, 
00202                     SdsIdType * id, 
00203                     StatusType * SDSCONST status );
00204 
00205 
00206 
00207 SDSEXTERN void Sds__MarkFree(SdsIdType id);
00208 
00209 SDSEXTERN void Sds__Free(SdsIdType id, StatusType * SDSCONST status);
00210 
00211 SDSEXTERN void Sds___WatchEvent(SdsIdType id, int eventFlag, const char * sourceFunc);
00212 
00213 
00214 #define SDS_COMP_MESS_ERROR 1
00215 #define SDS_COMP_MESS_WARN  2
00216 
00217 SDSEXTERN void SdsCompiler(SDSCONST char *string, int messages, int intaslong, SdsIdType *id, StatusType *status);
00218 
00219 
00220 /*
00221  * Note - if you get a syntax error at this point, it is likely
00222  * that INT64 has not been defined.  See the relevant part of
00223  * sdsport.h. 
00224  */
00225 SDSEXTERN INT64 SdsSetI64(long high, unsigned long low);
00226 
00227 SDSEXTERN UINT64 SdsSetUI64(unsigned long high, unsigned long low);
00228 
00229 SDSEXTERN void SdsGetI64(INT64 i64, long *high, unsigned long *low);
00230 
00231 SDSEXTERN void SdsGetUI64(UINT64 i64, unsigned long *high, unsigned long *low);
00232 
00233 
00234 SDSEXTERN void SdsGetIdInfo( INT32 * pnum, INT32 * pasize, INT32 * puids );
00235 
00236 struct SdsCheckStruct {
00237     INT32 _init_last_id;
00238     INT32 _init_current_array_size;
00239     INT32 _init_unused_ids;
00240     INT32 leakCount;
00241     INT32 _spare2;
00242     INT32 _spare3;
00243     INT32 _spare4;
00244 };
00245 typedef struct SdsCheckStruct SdsCheckType;
00246 
00247 SDSEXTERN void SdsCheckInit(SdsCheckType *chkData, StatusType *status);
00248 SDSEXTERN void SdsCheck(const char *mes, SdsCheckType *chkData, 
00249                         StatusType *status); 
00250 
00251 SDSEXTERN void SdsFreeIdAndCheck(const char *mes, SdsIdType id, StatusType *status);
00252 SDSEXTERN SDSCONST char * SdsErrorCodeString(StatusType error);
00253 SDSEXTERN void SdsListInUse();
00254 
00255 #if defined(SDS_CHECK_FREE)||defined(SDS_CHECK_FREE_W)
00256 #include <stdio.h>
00257 #ifndef SdsFreeId
00258 #ifdef SDS_CHECK_FREE_W
00259 #warning "Checking SdsFree operations"
00260 #endif
00261 /*
00262  * Note - the C++ version does its own thing below - see cleanup().
00263  */
00264 #define SdsFreeId(_id_, _status) \
00265     { \
00266         if (*(_status) == STATUS__OK)                   \
00267         {                                               \
00268             SdsFreeIdAndCheck("", (_id_), (_status));    \
00269             if (*(_status) == SDS__CHK_FREE)             \
00270             {                                           \
00271                 fprintf(stderr, "    At file %s, line %d\n", __FILE__, __LINE__); \
00272                 fprintf(stderr, "    This warning was enabled by SDS_CHECK_FREE or SDS_CHECK_FREE_W macro\n"); \
00273                 *(_status) = STATUS__OK;                \
00274             }                                           \
00275         }                                               \
00276     }
00277 #endif
00278 #endif
00279 
00280 #ifdef __cplusplus
00281 
00282 } /* extern "C" */
00283 
00284 /*
00285  * C++ only section.
00286  *
00287  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00288  *  Here is the a C++ interface to SDS. No object code is required since
00289  *  all code is inline.
00290  *
00291  */
00324 #ifdef DRAMA_ALLOW_CPP_STDLIB
00325 #include <string>
00326 template <typename T> class SdsArrayAccessHelper {
00327 public:
00328     friend class SdsId;
00329     /* Some exceptions thrown from the subscript operator */
00334     class NoDataException {
00335         std::string detail;
00336     public:
00341         NoDataException(const char *why) :detail(why) { }
00345         std::string const & GetDetails() const { return detail; };
00346 
00347     };
00352     class InvalidIndexException {
00353         std::string detail;
00354     public:
00359         InvalidIndexException(const char *why) :detail(why) { }
00363         std::string const & GetDetails() const { return detail; };
00364     };
00365 
00366 private:
00367     SdsCodeType code;         /* The SDS code of the item */
00368     unsigned long elements;   /* Number of element in the array */
00369     T* data;                  /* The array pointer is written here */
00370 
00371     /*
00372      * Help function used to check an index is valid.  Also checks
00373      * that we have some data. Throws expections on problems.
00374      */
00375     void CheckIndexAndData(unsigned long index) const {
00376         if (!data)
00377         {
00378             throw new NoDataException("Index %d, Code %d, elements %d - data is invalid");
00379         }
00380         if (index >= elements)
00381         {
00382             throw new InvalidIndexException("Index %d, Code %d, elements %d - index is invalid");
00383         }
00384     }
00385 
00386 
00387     /*
00388      * The remaining private items are accessed by SdsId as a friend class.
00389      */
00390     /*
00391      * Return the address of the address of the data being accessed  
00392      *
00393      * This is used by SdsId.AccessArray() to put the address of the
00394      * data item.
00395      */
00396     void ** Data() { return (void **)&data; }
00397 
00398     /*
00399      * Set the number of elements in the array.
00400      *
00401      * This is used by SdsId.AccessArray() set the number of elements in
00402      * the array.
00403      */
00404     void SetElements(unsigned long nelem) {
00405         elements = nelem;
00406     }
00407 
00408 
00409 protected:
00417     SdsArrayAccessHelper(SdsCodeType c) : code(c), elements(0), data(0) {
00418     }
00419 public:
00420  
00423     SdsCodeType Code() const { return code; }
00426     unsigned long Size() const { return elements; }
00440     T const & operator[](const unsigned long index) const {
00441         CheckIndexAndData(index);
00442         return data[index];
00443     }
00457     T  & operator[](const unsigned long index) {
00458         CheckIndexAndData(index);
00459         return data[index];
00460     }
00467     T * DataAddressRW() {
00468         return data;
00469     }
00476     const T * DataAddressRO() const {
00477         return data;
00478     }
00479 };  /* SdsArrayAccessHelper */
00480 
00481 /*
00482  * Classes for each SDS data type.
00483  */
00490 class SdsArrayChar : public SdsArrayAccessHelper<char> {
00491 public:
00492     SdsArrayChar() : SdsArrayAccessHelper<char>(SDS_CHAR) {
00493     }
00494 
00495 };
00502 class SdsArrayUbyte : public SdsArrayAccessHelper<unsigned char> {
00503 public:
00504     SdsArrayUbyte() : SdsArrayAccessHelper<unsigned char>(SDS_UBYTE) {
00505     }
00506 
00507 };
00514 class SdsArrayByte : public SdsArrayAccessHelper<signed char> {
00515 public:
00516     SdsArrayByte() : SdsArrayAccessHelper<signed char>(SDS_BYTE) {
00517     }
00518 
00519 };
00520 
00521 
00528 class SdsArrayUshort : public SdsArrayAccessHelper<unsigned short> {
00529 public:
00530     SdsArrayUshort() : SdsArrayAccessHelper<unsigned short>(SDS_USHORT) {
00531     }
00532 
00533 };
00540 class SdsArrayShort : public SdsArrayAccessHelper<short> {
00541 public:
00542     SdsArrayShort() : SdsArrayAccessHelper<short>(SDS_SHORT) {
00543     }
00544 
00545 };
00546 
00547 
00548 
00555 class SdsArrayINT32 : public SdsArrayAccessHelper<INT32> {
00556 public:
00557     SdsArrayINT32() : SdsArrayAccessHelper<INT32>(SDS_INT) {
00558     }
00559 
00560 };
00567 class SdsArrayUINT32 : public SdsArrayAccessHelper<UINT32> {
00568 public:
00569     SdsArrayUINT32() : SdsArrayAccessHelper<UINT32>(SDS_UINT) {
00570     }
00571 };
00572 
00573 
00580 class SdsArrayINT64 : public SdsArrayAccessHelper<INT64> {
00581 public:
00582     SdsArrayINT64() : SdsArrayAccessHelper<INT64>(SDS_I64) {
00583     }
00584 
00585 };
00592 class SdsArrayUINT64 : public SdsArrayAccessHelper<UINT64> {
00593 public:
00594     SdsArrayUINT64() : SdsArrayAccessHelper<UINT64>(SDS_UI64) {
00595     }
00596 };
00597 
00604 class SdsArrayDouble : public SdsArrayAccessHelper<double> {
00605 public:
00606     SdsArrayDouble() : SdsArrayAccessHelper<double>(SDS_DOUBLE) {
00607     }
00608 };
00615 class SdsArrayFloat : public SdsArrayAccessHelper<float> {
00616  public:
00617     SdsArrayFloat() : SdsArrayAccessHelper<float>(SDS_FLOAT) {
00618     }
00619 };
00620 
00621 #endif /* defined DRAMA_ALLOW_CPP_STDLIB */
00622 
00677 SDSCLASS SdsId {
00678     private:
00679         SdsIdType id;   /* Actual Sds id.  If 0, then no id is allocated */
00680         struct {
00681                 bool free : 1;/* Set true to cause destructor to free the id*/
00682                 bool del  : 1;/* If free is true, destructor will do SdsDelete*/
00683                 bool readfree : 1;/* if free and del, to SdsReadFree */
00684                 } flags;
00685 
00686         /* Private routine to clean up, will be called by destructor and 
00687            Shallow and Deep copy operations */
00688 
00689         /* If this check free code is not to be run, we don't want the from_where argument, it
00690            causes warnings in all using code.  This macro setup allows that
00691         */
00692 #if defined(SDS_CHECK_FREE)||defined(SDS_CHECK_FREE_W)            
00693 #define SDS__CHECK_ARG(_arg_) _arg_
00694 #else
00695 #define SDS__CHECK_ARG(_arg_) 
00696 #endif
00697 
00698 
00699         void CleanUp(const char * SDS__CHECK_ARG(from_where)) {
00700             /* If we have an id and the free flag is set */
00701             /* In the future, we should consider do a throw if status goes */
00702             /* bad, instead of just ignoring it                 */
00703             
00704             if ((id)&&(flags.free))
00705             {
00706                 /* If del and readfree, we need to do SdsReadFree */
00707                 if ((flags.del)&&(flags.readfree))
00708                 {
00709                     StatusType ignore = STATUS__OK;
00710                     SdsReadFree(id,&ignore);
00711                 }
00712                 /* If del and not readfree, we need to to SdsDelete */
00713                 else if (flags.del)
00714                 {
00715                     StatusType ignore = STATUS__OK;
00716                     SdsDelete(id,&ignore);
00717                 }
00718                 /* Free the id */
00719                 StatusType ignore = STATUS__OK;
00720 #if defined(SDS_CHECK_FREE)||defined(SDS_CHECK_FREE_W)            
00721                 SdsFreeIdAndCheck("", id, &ignore);
00722                 if (ignore != STATUS__OK)
00723                 {
00724                     fprintf(stderr, "SDS FreeId failure in C++ cleanup(), called from \"%s\" for id %d\n", from_where,(int)id);
00725                     fprintf(stderr, "    Status Code:%s\n", SdsErrorCodeString(ignore));
00726                     fprintf(stderr, "    SdsId object address is %p\n", (void *)(this));
00727                     fprintf(stderr, "    Sorry - don't have more exact location information\n");
00728                     fprintf(stderr, "    This warning was enabled by SDS_CHECK_FREE or SDS_CHECK_FREE_W macro\n");
00729                 }
00730 #else
00731                 SdsFreeId(id,&ignore);
00732 #endif
00733 
00734             }
00735         }
00736         /* Assignment and Copy operators, made private to avoid misuse */       
00737         SdsId& operator=(const SdsId& a); /* Assignment */
00738         SdsId(const SdsId&); /* Copy */
00739 
00740 
00741 #ifdef DRAMA_ALLOW_CPP_STDLIB
00742         /* This is used by the ArrayAccess methods to check the item
00743            is appropiate for the SdsArrayAccessHelper being used
00744         */
00745         void CheckArrayType(
00746             const SdsCodeType code,     /* Expected code */
00747             const int ndims,            /* Expected number of dims */
00748             unsigned long * const dims, /* Actual dims written here */
00749             StatusType * const status) {
00750             
00751             if (*status != STATUS__OK) return;
00752             char name[SDS_C_NAMELEN];
00753             SdsCodeType tcode;
00754             long tndims;
00755             /*
00756              * Get details on the object.
00757              */
00758             Info(name, &tcode, &tndims, dims, status);
00759             /*
00760              * Check the code and number of dimensions are correct.
00761              */
00762             if (tcode != code)
00763             {
00764                 *status = SDS__TYPE;
00765                 return;
00766             }
00767             if (tndims == 0)
00768             {
00769                 *status = SDS__NOTARR;
00770                 return;
00771             }
00772             if (tndims != ndims)
00773             {
00774                 *status = SDS__INVDIMS;
00775                 return;
00776             }
00777             
00778         }
00779         /*
00780          * A simplified access to  CheckArrayType, for a single dimensional
00781          * array.
00782          */
00783         void CheckArrayTypeSingleDim(
00784             const SdsCodeType code, 
00785             unsigned long * const nitems,  /* Actual number of items written here*/
00786             StatusType * const status) {
00787             
00788             unsigned long dims[SDS_C_MAXARRAYDIMS];
00789             CheckArrayType(code, 1, dims, status);
00790             if (*status != STATUS__OK) return;
00791             *nitems = dims[0];
00792             
00793         }
00794 #endif /* defined DRAMA_ALLOW_CPP_STDLIB */
00795 
00796     public:
00825         SdsId(const SdsIdType item = 0, const bool free=false, 
00826                         const bool del = false, const bool readfree = false) :
00827                 id(item) {
00828                  flags.free = free;
00829                  flags.del = del; 
00830                  flags.readfree = readfree;
00831         }
00851         SdsId(void * const data, StatusType * const status, 
00852                    const bool import = false) :
00853                 id(0) {
00854             flags.free = true;
00855             flags.readfree = false;
00856             if (import)
00857             {
00858                 SdsImport(data,&id,status);
00859                 flags.del = true;
00860             }
00861             else
00862             {
00863                 SdsAccess(data,&id,status);
00864                 flags.del = false; 
00865             }
00866         }
00883         SdsId(const void * const data, StatusType * const status) : id(0) {
00884             flags.free = true;
00885             flags.readfree = false;
00886             flags.del = true;
00887             SdsImport(data,&id,status);
00888         }
00902         SdsId(const char * const filename, StatusType * const status) :
00903                 id(0) {
00904             flags.free = true;
00905             flags.del = true;
00906             flags.readfree = true;
00907             SdsRead(filename,&id,status);
00908         }
00924         SdsId(const SdsId &parent_id, const char * const name, 
00925             const SdsCodeType code,
00926             StatusType * const status, const long nextra = 0, 
00927             const char * const extra = 0) :
00928                 id(0) {
00929             flags.free = true;
00930             flags.del = false;
00931             flags.readfree = false;
00932             SdsNew(parent_id.id,name,nextra,extra,code,0,0,&id,status);
00933         }    
00945         SdsId(const char * const name, const SdsCodeType code,
00946             StatusType * const status, const long nextra = 0, 
00947             const char * const extra = 0) :
00948                 id(0) {
00949             flags.free = true;
00950             flags.del = true;
00951             flags.readfree = false;
00952             SdsNew(0,name,nextra,extra,code,0,0,&id,status);
00953         }    
00971         SdsId(const SdsId &parent_id, const char * const name, 
00972             const SdsCodeType code,
00973             const long ndims, const unsigned long *dims,
00974             StatusType * const status, const long nextra = 0, 
00975             const char * const extra = 0) :
00976                 id(0) {
00977             flags.free = true;
00978             flags.del = false;
00979             flags.readfree = false;
00980             SdsNew(parent_id.id,name,nextra,extra,code,ndims,dims,&id,status);
00981         }    
00997         /* Constructor which creates a new array top-level item */
00998         SdsId(const char * const name, const SdsCodeType code,
00999             const long ndims, const unsigned long *dims,
01000             StatusType * const status, const long nextra = 0, 
01001             const char * const extra = 0) :
01002                 id(0) {
01003             flags.free = true;
01004             flags.del = true;
01005             flags.readfree = false;
01006             SdsNew(0,name,nextra,extra,code,ndims,dims,&id,status);
01007         }    
01008         
01022         SdsId(const SdsId &array_id, const long nindicies, 
01023             const unsigned long * const indicies, StatusType * const status) :
01024                 id(0) {
01025             flags.free = true;
01026             flags.del = false;
01027             flags.readfree = false;
01028             SdsCell(array_id.id, nindicies, indicies, &id,status);      
01029         }
01042         SdsId(const SdsId& source, StatusType * const status):
01043                 id(0) {
01044             flags.free = true;
01045             flags.del = true;
01046             flags.readfree = false;
01047             SdsCopy(source.id, &id, status);
01048         }
01061         SdsId(const SdsId& source, const char * const name, 
01062                 StatusType * const status) :
01063                 id(0) {
01064             flags.free = true;
01065             flags.del = false;
01066             flags.readfree = false;
01067             SdsFind(source.id,name,&id,status);
01068         }
01069         
01084         SdsId(const SdsId& source, const long index, StatusType * const status):
01085                 id(0) {
01086             flags.free = true;
01087             flags.del = false;
01088             flags.readfree = false;
01089             SdsIndex(source.id,index,&id,status);
01090         }
01091         
01108         /*Just invoke the private cleanup routine */
01109         virtual ~SdsId() {
01110             CleanUp("SdsId destructor");
01111         }
01112         /* Modify flags */
01113 
01119         void SetFree() { flags.free = true; }
01125         void SetDelete() { flags.del = true; }
01126 
01135         void ClearDelete() { flags.del = false; }
01136 
01144         void Outlive() { flags.free = false; flags.del = false; 
01145                            flags.readfree = false; }
01146         
01147 /*
01148  *      General operations, as per similar Sds operation.
01149  *      Currently only Delete, Get and Put are virtual.
01150  */
01151         
01168         virtual void Delete(StatusType * const status) {
01169             SdsDelete(id,status);
01170             if (*status == STATUS__OK)
01171             {
01172                 flags.del = false;
01173                 if (flags.free)
01174                 {
01175                     SdsFreeId(id, status);
01176                     if (*status == STATUS__OK)
01177                     {
01178                         id = 0;
01179                         flags.free = false;
01180                     }
01181                 }
01182             }
01183         }
01206         void Export(const unsigned long length, 
01207                     void * const data,
01208                     StatusType * const status) {
01209             SdsExport(id,length,data,status);
01210         }
01230         void ExportDefined(const unsigned long length, 
01231                     void * const data,
01232                     StatusType * const status) {
01233             SdsExportDefined(id,length,data,status);
01234         }
01247         void Extract(StatusType * const status) {
01248             SdsExtract(id,status);
01249             /* If we succeed, we need to modify the flags to appropiate for
01250                and indepent toplevel item */
01251             if (*status == STATUS__OK)
01252             {
01253                 flags.free = true;
01254                 flags.del = true;
01255                 flags.readfree = false;
01256             }
01257         }
01271         void Flush(StatusType * const status) {
01272             SdsFlush(id,status);
01273         }
01296         virtual void Get(const unsigned long length,
01297                  void * const data,
01298                  StatusType * const status,
01299                  unsigned long *actlen = 0,
01300                  const unsigned long offset=0) const
01301         {
01302             unsigned long myactlen;
01303             if (!actlen) actlen = &myactlen;
01304             SdsGet(id,length,offset,data,actlen,status);
01305         }
01322         void GetExtra(const unsigned long length,
01323                  char * const extra,
01324                  StatusType * const status,
01325                  unsigned long *actlen = 0) const
01326         {
01327             unsigned long myactlen;
01328             if (!actlen) actlen = &myactlen;
01329             SdsGetExtra(id,length,extra,actlen,status);
01330         }
01351         void Info(char * const name,
01352                   SdsCodeType * const code,
01353                   long * const ndims,
01354                   unsigned long * const dims,
01355                   StatusType * const status) const {
01356             SdsInfo(id,name,code,ndims,dims,status);
01357         }
01358         /* Give access to individual things normally returned by SdsInfo*/
01374         void GetName(char * const name,
01375                      StatusType * const status) const {
01376             SdsCodeType code;
01377             long ndims;
01378             unsigned long dims[SDS_C_MAXARRAYDIMS];
01379             SdsInfo(id,name,&code,&ndims,dims,status);
01380         }
01396         void Code(SdsCodeType * const code,
01397                         StatusType * const status) const {
01398             char name[16];
01399             long ndims;
01400             unsigned long dims[SDS_C_MAXARRAYDIMS];
01401             SdsInfo(id,name,code,&ndims,dims,status);
01402         }
01422          void Dims(long * const ndims, unsigned long * const dims,
01423                         StatusType * const status) const {
01424             char name[16];
01425             SdsCodeType code;
01426             SdsInfo(id,name,&code,ndims,dims,status);
01427         }
01438         void Insert(SdsId & to_insert, StatusType * const status) {
01439             SdsInsert(id,to_insert.id,status);
01440             /* If we succeed, the new child should not be deleted when
01441                 it's id is destroyed, so clear the flag */
01442             if (*status == STATUS__OK)
01443                 to_insert.flags.del = false;
01444         }
01459         void Insert(SdsId & to_insert, const long ndims,
01460                         const unsigned long * const dims, 
01461                         StatusType * const status) {
01462             SdsInsertCell(id,ndims,dims,to_insert.id,status);
01463             /* If we succeed, the new child should not be deleted when
01464                 it's id is destroyed, so clear the flag */
01465             if (*status == STATUS__OK)
01466                 to_insert.flags.del = false;
01467         }
01468 
01480         void FillArray(const SdsId &elem, StatusType * const status) {
01481             SdsFillArray(id,elem.id,status);
01482         }
01483 
01508         void Pointer(void **data, StatusType * const status, 
01509                      unsigned long * length = 0) {
01510             unsigned long mylength;
01511             if (!length) length = &mylength;
01512             SdsPointer(id,data,length,status);
01513         }
01514 
01535         virtual void Put(const unsigned long length,
01536                  void * const data,
01537                  StatusType * const status,
01538                  const unsigned long offset=0)
01539         {
01540             SdsPut(id,length,offset,data,status);
01541         }
01556         void PutExtra(const long nextra,
01557                  const char * const extra,
01558                  StatusType * const status)
01559         {
01560             SdsPutExtra(id,nextra,extra,status);
01561         }
01571         void Rename(const char * const name, 
01572                         StatusType * const status) {
01573             SdsRename(id,name,status);
01574         }
01598         void Resize(const long ndims, const unsigned long *dims, 
01599                         StatusType * const status) {
01600              SdsResize(id,ndims,dims,status);
01601         }
01610         void Size(unsigned long * const bytes, 
01611                   StatusType * const status) const {
01612             SdsSize(id,bytes,status);
01613         }
01623         void SizeDefined(unsigned long * const bytes, 
01624                   StatusType * const status) const {
01625             SdsSizeDefined(id,bytes,status);
01626         }
01633         void List(StatusType * const status) const {
01634             SdsList(id,status);
01635         }
01647         void Write(const char * const filename,
01648                    StatusType * const status) const {
01649             SdsWrite(id,filename,status);
01650         }        
01651 
01664         void IsExternal(int * const external, 
01665                    StatusType * const status) const {
01666             SdsIsExternal(id, external, status);
01667         }
01679         void GetExternInfo(void **data, 
01680                    StatusType * const status) const {
01681             SdsGetExternInfo(id, data, status);
01682         }
01683         
01695         operator SdsIdType(void) const { return id; }
01696         
01702         /* Note, if there is no bool type, we can just use the above operator which 
01703            returns the Sds id. Similary for Borland Cpp which does not like
01704            this operator (ambigious with the above operator 
01705          */
01706 #       if (!defined(CPP_NOBOOL))  && (!defined(BORLAND))
01707         operator bool(void) const { return (id != 0); }
01708 #       endif
01709         
01737         SdsIdType COut(const bool outlives, bool * const free = 0,
01738                 bool * const del= 0, bool * const readfree = 0) {
01739             if (free)
01740                 *free = flags.free;
01741             if (del)
01742                 *del  = flags.del;
01743             if (readfree)
01744                 *readfree = flags.readfree;
01745             if (outlives)
01746                 flags.free = flags.del = flags.readfree = false;
01747             return (SdsId::id);
01748         }
01749         /* Obsolete version     */
01779         void COut(const bool outlives, SdsIdType *item, bool * const free = 0,
01780                 bool * const del= 0, bool * const readfree = 0) {
01781             *item = COut(outlives,free,del,readfree);
01782         }
01783 
01801         void ShallowCopy (SdsId & source, const bool outlives=true) {
01802             if (this != &source)
01803             {
01804                 CleanUp("SdsId::ShallowCopy 1");        /* Run destructor on old id */
01805                 id = source.id;
01806                 if (outlives)
01807                 {
01808                     /* If we will outlive the source, then we copy the source's 
01809                      * flags and set  the sources flags to false.       
01810                      */
01811 
01812                     flags.free = source.flags.free;
01813                     flags.del  = source.flags.del;
01814                     flags.readfree  = source.flags.readfree;
01815 
01816                     source.flags.free = source.flags.del = 
01817                                         source.flags.readfree = false;
01818                 }
01819                 else
01820                 {
01821                     flags.free = flags.del = flags.readfree = false;
01822                 }
01823             }
01824         }
01837         void DeepCopy (const SdsId &source, StatusType * const status)
01838         {
01839             if (this != &source)
01840             {
01841                 CleanUp("SdsId::DeepCopy 1");   /* Run destructor code on old id */
01842                 id = 0;
01843                 SdsCopy(source.id,&id,status);
01844                 flags.free = true;
01845                 flags.del = true;
01846                 flags.readfree = false;
01847             }
01848             else
01849             {
01850                 /*
01851                  * this = &source;
01852                  *
01853                  * Deep copy of self.  If this item is external, then
01854                  * we actual do a copy - but we have to get the ordering
01855                  * right.  This ensures that DeepCopy() always gives us
01856                  * something we can modify the structure of.
01857                  */
01858                 int external;
01859                 SdsIsExternal(id, &external, status);
01860                 if (external)
01861                 {
01862                     /*
01863                      * copy this to a new SDS id..
01864                      */
01865                     SdsIdType newId;
01866                     SdsCopy(id,&newId,status);
01867                     
01868                     if (*status == STATUS__OK)
01869                     {
01870                         /*
01871                          * Run the contructor on "this" and then set up 
01872                          * this again.
01873                          */
01874                         CleanUp("SdsId::DeepCopy 2");
01875                         id = newId;
01876                         flags.free = true;
01877                         flags.del = true;
01878                         flags.readfree = false;
01879                         
01880                     }
01881                     
01882                 }
01883             }
01884         }
01904         void ShallowCopy (const SdsIdType source, const bool free=false, 
01905                         const bool del = false, const bool readfree = false)
01906         {
01907             CleanUp("SdsId::ShallowCopy 2");    /* Run destructor on old id */
01908             flags.free = free;
01909             flags.del = del; 
01910             flags.readfree = readfree;
01911             id = source;
01912         }
01920         void DeepCopy (const SdsIdType source, StatusType *status)
01921         {
01922             CleanUp("SdsId::DeepCopy 3");       /* Run destructor code on old id */
01923             id = 0;
01924             SdsCopy(source,&id,status);
01925             flags.free = true;
01926             flags.del = true;
01927             flags.readfree = false;
01928         }
01929 #ifdef DRAMA_ALLOW_CPP_STDLIB
01930 
01967         template <typename T> void ArrayAccess(
01968             SdsArrayAccessHelper<T> * const data,
01969             StatusType *const status) {
01970             
01971             unsigned long dims[SDS_C_MAXARRAYDIMS];
01972             CheckArrayTypeSingleDim(data->Code(), dims, status);
01973             if (*status != STATUS__OK) return;
01974             data->SetElements(dims[0]);
01975             
01976             Pointer(data->Data(), status); 
01977         }
02018         template <typename T> void ArrayAccess(
02019             const unsigned long expitems, /* Expected number of elements in array*/
02020             SdsArrayAccessHelper<T> * const data,
02021             StatusType *const status) {
02022             
02023             unsigned long dims[SDS_C_MAXARRAYDIMS];
02024             CheckArrayTypeSingleDim(data->Code(), dims, status);
02025             if (*status != STATUS__OK) return;
02026             if (dims[0] != expitems)
02027             {
02028                 *status = SDS__INVDIMS;
02029                 return;
02030             }
02031             data->SetElements(dims[0]);
02032             Pointer(data->Data(), status); 
02033         }
02076         template <typename T> void ArrayAccess(
02077             SdsArrayAccessHelper<T> * const data,
02078             long ndims,
02079             unsigned long dims[],
02080             StatusType *const status) {
02081             
02082             if ((ndims < 1)||(ndims > 7))
02083             {
02084                 *status = SDS__INVDIMS;
02085                 return;
02086             }
02087             CheckArrayType(data->Code(), ndims, dims, status);
02088             if (*status != STATUS__OK) return;
02089 
02090             /*
02091              * work out the number of elements
02092              */
02093             unsigned long elements = dims[0];
02094             for (long i = 1; i < ndims ; ++i)
02095             {
02096                 elements *= dims[i];
02097             }
02098             data->SetElements(elements);
02099             /*
02100              * Access the data.
02101              */
02102             Pointer(data->Data(), status); 
02103         }
02104 
02105 
02151         template <typename T> void ArrayAccess(
02152             SdsArrayAccessHelper<T> * const data,
02153             long *ndims,
02154             unsigned long dims[],
02155             StatusType *const status) {
02156             
02157             /*
02158              * A bit of a pain, we need to call Dims to get the number
02159              * of dimensions.
02160              */
02161             Dims(ndims, dims, status);
02162             /*
02163              * The use the above version where we know the number of dimenions
02164              */
02165             ArrayAccess(data, *ndims, dims, status);
02166         }
02167 
02168 
02169 
02170 #endif /* defined DRAMA_ALLOW_CPP_STDLIB */
02171 
02172 
02173 }; /* class SdsId */
02174 
02175 SDSEXTERN const SdsId SdsNull;
02176 
02177 #ifdef DRAMA_ALLOW_CPP_STDLIB
02178 #include <stdio.h>
02187 class  SdsIDChecker {
02188 private:
02189     SdsCheckType _chkData;
02190     int _line;
02191     std::string _file;
02192     std::string _function;
02193 public:
02210     SdsIDChecker(int line, const char *file, const char *function) 
02211         : _line(line), _file(file), _function(function) {
02212         StatusType ignore = STATUS__OK;
02213         SdsCheckInit(&_chkData, &ignore);
02214     }
02220     virtual ~SdsIDChecker() {
02221         StatusType status = STATUS__OK;
02222         SdsCheck(0, &_chkData, &status);
02223         if (status == SDS__CHK_LEAK)
02224             fprintf(stderr,"Warning:SdsIDChecker:Function leaked SDS id's - function %s, file %s, check object at line %d\n", _function.c_str(), _file.c_str(), _line);
02225         else if (status == SDS__CHK_RELEASED)
02226             fprintf(stderr,"Warning:SdsIDChecker:Function released SDS id's - function %s, file %s, check object at line %d\n", _function.c_str(), _file.c_str(), _line);
02227     }
02228 };
02240 #define SDS_CHECK_IDS(_function_) SdsIDChecker _sds_id_checker(__LINE__, __FILE__, (_function_))
02241 #endif /* defined DRAMA_ALLOW_CPP_STDLIB */
02242 
02243  
02244 #endif
02245 
02246 /* Define SdsMalloc and SdsFree.  These are normally just defined
02247    to malloc and free but sometimes when debugging we want different
02248    versions
02249  */
02250  
02251 #define SdsMalloc(_size) (void *)malloc(_size)
02252 #define SdsFree(_where)   (void)free((void *)(_where))
02253 
02254 #endif
02255 
02256 
02257 

Click here for the DRAMA home page and here for the AAO home page.

For more information, contact tjf@aaoepp.aao.gov.au 

Generated on Tue Nov 3 09:09:56 2009 for AAO DRAMA C++ Interfaces by doxygen 1.2.18