/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2011-2015 by The HDF Group. * * All rights reserved. * * * * This file is part of the H4CF conversion toolkit. The full H4CF conversion* * toolkit copyright notice including terms governing use, modification, and * * redistribution, is contained in the files COPYING and Copyright.html. * * COPYING and Copyright.html can be found at the root of the source code * * distribution tree. * * For questions contact eoshelp@hdfgroup.org or help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /***************************************************************************** Category: Header file for the eoslib namespace Description: This file includes the definition of class var. This class is the fundamental class of the eoslib namespace. This class has methods of handling attributes and dimensions of this variable. It also includes methods to check if this variable is a coordinate variable. *****************************************************************************/ #ifndef EOSLIB_VAR_H #define EOSLIB_VAR_H #include #include #include #include #include "eoslib_defs.h" #include "eoslib_rc.h" #include "eoslib_err.h" namespace eoslib { class dim; //! Variable class /*! * This class represents a variable (or data field). */ class var: public renamable { public: //! Constrictor var(group *g, const std::string& name); var(group *g, const std::string& name, const std::string& orig_name); //! Destructor virtual ~var(); //! Getting dimensions std::list& get_dims() {return m_dims;} //! Getting dimensions (const) const std::list& get_dims_c() const {return m_dims;} //! Checking if this has dim bool has_dim_of(dim *d) const; std::vector get_dim_sizes() const; //! Getting attributes std::list& get_attrs() {return m_attrs;} //! Getting attributes (const) const std::list& get_attrs_c() const {return m_attrs;} //! Getting attributes by name attr* get_attr_by_name(const std::string& name); //! Setting current variable as a coordinate variable /*! * This function sets the current var as a coordinate variable. * This means that all dimensions of the current var has * the current variable as the coordinate variable. * Note that some dimenstions (lat/lon) may have more than one * coordinate variables. This function appends the current * variable to the list of coordinate variables in all its * dimensions. */ void set_cv(); //! Getting the group where the current variable is group* get_group() const {return m_group;} //! Getting variable type virtual value_type_t get_type() const = 0; //! Getting a subset value virtual void get_value(int32 start[], int32 stride[], int32 edge[], void *buf) const = 0; //! Getting all values void get_all_values(std::vector *pbuf) const; //! Getting total number of elements unsigned int get_tot_num_elements() const; //! Getting total number of bytes unsigned int get_tot_num_bytes() const; //! Getting actual number of bytes given the number of elements unsigned int get_num_bytes(int32) const; /** get_all() allocates buffer which can hold all values, * read all values, store them in the allocated buffer, * and return the allocated buffer. */ void get_all(void **pbuf); //! Getting the original name. This is usefule for the case when hybrid SDS/Vdata objects are added to an HDF-EOS2 file. std::string get_origname() const {return var_orig_name;} //! Getting a specific element in the value array /** * This follows C-major convention. * foo[1][2][3] -> vector of [1,2,3] */ template T get_item_at(const void *buf, const std::vector& pos) { const T *b = (const T*)buf; int32 m = 1, next_m = 1, p = 0; int i; const std::list& dims = get_dims_c(); std::list::const_reverse_iterator it = dims.rbegin(); if(pos.size() != dims.size()) throw std::runtime_error("Dimension of pos is not compatible with the current variable. " "(" __FILE__ ":" TOSTRING(__LINE__)")" ); for(i=pos.size()-1; i>=0; i--) { m = next_m; next_m = next_m * (*it)->get_size(); p += m * pos[i]; it++; } return b[p]; } //! Dumping variable to stdout, this function should only be used for the internal testing(directory internal_test) void dump_r(int sp, bool bDumpValues=false) const; //! Adding a new attribute void add_attr(attr* a); //! Removing an attribute void remove_attr(attr *a); //! Checking whether the current var is a coordinate varaible in the group g bool is_cv(group* g); /** * clone_r() internally calls _clone() to * duplicae the current variable. * Since the duplicated var has the same dim pointers, * attr pointers, and group pointer, * we need to update them. * * New group pointer: g * New dim pointers: updated * New attr pointers: new instances are created. */ var *clone_r(group *g, const std::map& dimmap) const; /** * This fuction compares two variables for equivalence. * Two vars are equivalent if * they have equivalent dims * (same order, same name, same size) * they have same values * they have equivalent attributes * * Two objs are equivalent if they have the same value * even if they do not occupy the same memory storage. */ bool is_equivalent_to(var *v) const; /** * This function checks whether the current variable * and another variable v are actually the same * object in the file or not. * Since file handles are used for comparison, * this is a quick process */ virtual bool same_obj_test(var* v) const = 0; //! Replacing dims void replace_all_dims(const std::map& dimmap); // Whether can be clone const bool NOT_clone() {return disable_clone; } void unset_clone() { disable_clone = true;} ///////////////////////// // Static ///////////////////////// //! Getting name static std::string s_get_name(const var*v); //! Checking whether two variables are the same object in the file static bool s_same_obj_test(var *v1, var *v2); //! Checking whether two list of variables are the same objs static bool s_same_objlist_test(const std::list& l1, const std::list& l2); //! Converting n-dim position to 1D position static int32 INDEX_nD_TO_1D(const std::vector& dims, const std::vector& pos); static int32 INDEX_nD_TO_1D(int32 rank, const int32 dim[], const int32 pos[]); //! Getting a subset of a variable /** * \param input Input variable * \param dim dimension info of the input * \param start start indexes of each dim * \param stride stride of each dim * \param edge edge of each dim * \param poutput output variable * \return 0 if successful. -1 otherwise. */ template static int subset( const T input[], int32 rank, const int32 dim[], const int32 start[], const int32 stride[], const int32 edge[], std::vector *poutput) { std::vector pos(&start[0], &start[rank]); std::vectorend_index; end_index.resize(rank); for (int i = 0; ipush_back(input[INDEX_nD_TO_1D(rank, dim, &pos[0])]); // Getting next pos ssize_t j = -1; for(ssize_t i=0; i static int subset //! Getting a subset of a variable /** * \param input Input variable * \param dim dimension info of the input * \param start start indexes of each dim * \param stride stride of each dim * \param edge count of each dim * \param poutput output variable * \parrm index dimension index * \return 0 if successful. -1 otherwise. */ template static int subset2( const T input[], int32 rank, int32 dim[], int32 start[], int32 stride[], int32 edge[], std::vector *poutput, int32 pos[], int index) { for(int k=0; kpush_back(input[INDEX_nD_TO_1D(rank, dim, &pos[0])]); } } // end of for return 0; } // end of template static int subset2 protected: var(const var& r); /** * For each attribute, this function clone it and replace * the old attribute pointer to a new one. * This is part of the variable cloning process. */ void _clone_attrs(); /** * _clone() makes another copy of the current variable. * Note that all internal data of the var class and * attributes of the current varaible are copied. * * Warning: cloned var has the same dim pointers. * Warning: cloned var has the same attr pointers. */ virtual var *_clone() const = 0; /* This flag is to used to check if this object needs to be cloned. If true, should not be cloned. false, can be cloned. */ bool disable_clone; group *m_group; // Although eoslib_var has pointers to dims, the ownership of the dims belong // to the group. Therefore, destructors of dims are not called by var. std::list m_dims; std::list m_attrs; // The original variable name. std::string var_orig_name; private: var(); }; } // namespace #endif