1 //-*****************************************************************************
2 //
3 // Copyright (c) 2012,
4 //  Sony Pictures Imageworks, Inc. and
5 //  Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd.
6 //
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are
11 // met:
12 // *       Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // *       Redistributions in binary form must reproduce the above
15 // copyright notice, this list of conditions and the following disclaimer
16 // in the documentation and/or other materials provided with the
17 // distribution.
18 // *       Neither the name of Sony Pictures Imageworks, nor
19 // Industrial Light & Magic nor the names of their contributors may be used
20 // to endorse or promote products derived from this software without specific
21 // prior written permission.
22 //
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 //
35 //-*****************************************************************************
36 
37 #ifndef Alembic_AbcCoreHDF5_HDF5Hierarchy_h
38 #define Alembic_AbcCoreHDF5_HDF5Hierarchy_h
39 
40 #include <Alembic/AbcCoreHDF5/Foundation.h>
41 
42 namespace Alembic {
43 namespace AbcCoreHDF5 {
44 namespace ALEMBIC_VERSION_NS {
45 
46 class HDF5Hierarchy;
47 
48 //-*****************************************************************************
49 class H5Node
50 {
51 public:
H5Node()52     H5Node()
53         : m_object( -1 ), m_ref( 0 ), m_H5HPtr( NULL ) {}
H5Node(hid_t iObject,hobj_ref_t iRef,HDF5Hierarchy * iH5HPtr)54     H5Node( hid_t iObject, hobj_ref_t iRef, HDF5Hierarchy* iH5HPtr )
55         : m_object( iObject ), m_ref( iRef ), m_H5HPtr( iH5HPtr ) {}
56 
getObject()57     hid_t               getObject() const           { return m_object; }
setObject(hid_t iObject)58     void                setObject( hid_t iObject )  { m_object = iObject; }
59 
getRef()60     hobj_ref_t          getRef() const              { return m_ref; }
getH5HPtr()61     HDF5Hierarchy*      getH5HPtr() const           { return m_H5HPtr; }
62 
isValidObject()63     bool                isValidObject() const       { return m_object >= 0; }
64 
65 private:
66     hid_t               m_object;
67     hobj_ref_t          m_ref;
68     HDF5Hierarchy*      m_H5HPtr;
69 };
70 
71 //-*****************************************************************************
72 class HDF5Hierarchy
73 {
74 public:
HDF5Hierarchy()75     HDF5Hierarchy() {}
~HDF5Hierarchy()76     ~HDF5Hierarchy() { clear(); }
77 
78     H5Node createNode( hid_t iId );
79 
80     void build( hid_t iFile );
81     void clear();
isEnabled()82     bool isEnabled()                    { return m_enabled; }
setEnabled(bool iEnabled)83     void setEnabled( bool iEnabled )    { m_enabled = iEnabled; }
84 
85     hobj_ref_t  getChildRef( hobj_ref_t iParentRef, const std::string &iName );
86     bool        childExists( hobj_ref_t iParentRef, const std::string &iName );
87     bool        attrExists( hobj_ref_t iParentRef, const std::string &iName );
88 
89     void        readMetaDataString( hobj_ref_t iParentRef,
90                                     const std::string &iMetaDataName,
91                                     std::string &oMetaDataString );
92 
93     void        readMaskInfo( hobj_ref_t iParentRef,
94                               const std::string &iPropName,
95                               size_t& oNumFields,
96                               void *oData );
97 
98     template<class T>
visitAllChildObjects(H5Node iParent,const std::string & iName,T & iVisitor)99     void visitAllChildObjects( H5Node iParent,
100                                const std::string &iName,
101                                T &iVisitor )
102     {
103         hobj_ref_t objectRef     = getChildRef( iParent.getRef(), iName );
104         ChildInfoArray& children = m_objectMap[objectRef].m_children;
105 
106         for( ChildInfoArray::iterator it = children.begin();
107              it != children.end(); ++it )
108         {
109             iVisitor( it->m_name );
110         }
111     }
112 
113     template<class T>
visitAllAttributes(hobj_ref_t iParentRef,const std::string & iName,T & iVisitor)114     void visitAllAttributes( hobj_ref_t iParentRef,
115                              const std::string &iName,
116                              T& iVisitor )
117     {
118         hobj_ref_t objectRef = getChildRef( iParentRef, iName );
119         AttrInfoArray& attrs = m_objectMap[objectRef].m_attrs;
120 
121         for( AttrInfoArray::iterator it = attrs.begin();
122              it != attrs.end(); ++it )
123         {
124             std::string attrName( it->m_name );
125             size_t attrNameLen = attrName.size();
126             if ( attrNameLen < 6 )
127             {
128                 return;
129             }
130 
131             // Last 5 characters.
132             std::string suffix( attrName, attrNameLen-5 );
133             if ( suffix == ".info" )
134             {
135                 std::string propertyName( attrName, 0, attrNameLen-5 );
136                 iVisitor( propertyName );
137             }
138         }
139     }
140 
141     void makeCompactObjectHierarchy(
142         std::vector<hobj_ref_t>     &oObjectRefs,
143         std::vector<uint32_t>       &oChildrenSizes,
144         std::vector<std::string>    &oChildrenNames,
145         std::vector<hobj_ref_t>     &oChildrenRefs,
146         std::vector<uint32_t>       &oAttrSizes,
147         std::vector<std::string>    &oAttrNames,
148         std::vector<char>           &oHasMask,
149         std::vector<uint32_t>       &oMaskBits,
150         std::vector<char>           &oHasMeta,
151         std::vector<std::string>    &oMetaStrs );
152 
153     void extractFromCompactObjectHierarchy(
154         hid_t                       iFile,
155         std::vector<hobj_ref_t>     &iObjectRefs,
156         std::vector<uint32_t>       &iChildrenSizes,
157         std::vector<std::string>    &iChildrenNames,
158         std::vector<hobj_ref_t>     &iChildrenRefs,
159         std::vector<uint32_t>       &iAttrSizes,
160         std::vector<std::string>    &iAttrNames,
161         std::vector<char>           &iHasMask,
162         std::vector<uint32_t>       &iMaskBits,
163         std::vector<char>           &iHasMeta,
164         std::vector<std::string>    &iMetaStrs );
165 
166 private:
167     void addObject( hid_t iParent, const char *iName );
168     void addAttr( hid_t iParent, const char *iName );
169 
170     friend class ObjectVisitor;
171 
172     struct ChildInfo
173     {
174         ChildInfo( const string &iName, hobj_ref_t iRef = 0 )
m_nameChildInfo175             : m_name( iName ), m_ref( iRef ) {}
176 
177         string     m_name;
178         hobj_ref_t m_ref;
179 
180         friend inline bool operator<( const ChildInfo &x, const ChildInfo &y )
181         {
182             return x.m_name < y.m_name;
183         }
184     };
185 
186     struct MaskInfo
187     {
188         size_t          m_numFields;
189         uint32_t        m_data[5];
190     };
191 
192     struct AttrInfo
193     {
AttrInfoAttrInfo194         AttrInfo( const string &iName ) : m_name( iName ), m_mask( NULL ) {}
195 
196         string    m_name;
197         string    m_meta;
198         MaskInfo* m_mask;
199 
clearAttrInfo200         void clear()
201         {
202             delete m_mask;
203             m_mask = NULL;
204         }
205 
206         friend inline bool operator<( const AttrInfo &x, const AttrInfo &y )
207         {
208             return x.m_name < y.m_name;
209         }
210     };
211 
212     typedef std::vector<ChildInfo>              ChildInfoArray;
213     typedef std::vector<AttrInfo>               AttrInfoArray;
214 
215     struct ObjectInfo
216     {
217         ChildInfoArray  m_children;
218         AttrInfoArray   m_attrs;
219     };
220 
221     typedef std::map<hobj_ref_t, ObjectInfo> ObjectMap;
222 
223     ObjectMap   m_objectMap;
224     bool        m_enabled;
225 };
226 
227 } // End namespace ALEMBIC_VERSION_NS
228 
229 using namespace ALEMBIC_VERSION_NS;
230 
231 } // End namespace AbcCoreHDF5
232 } // End namespace Alembic
233 
234 #endif
235