1 //-*****************************************************************************
2 //
3 // Copyright (c) 2009-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 #include <Alembic/AbcCoreHDF5/CpwData.h>
38 #include <Alembic/AbcCoreHDF5/CpwImpl.h>
39 #include <Alembic/AbcCoreHDF5/OwData.h>
40 #include <Alembic/AbcCoreHDF5/OwImpl.h>
41 #include <Alembic/AbcCoreHDF5/WriteUtil.h>
42 
43 namespace Alembic {
44 namespace AbcCoreHDF5 {
45 namespace ALEMBIC_VERSION_NS {
46 
47 //-*****************************************************************************
OwData(hid_t iParentGroup,const std::string & iName,const AbcA::MetaData & iMetaData)48 OwData::OwData( hid_t iParentGroup,
49                 const std::string &iName,
50                 const AbcA::MetaData &iMetaData )
51     : m_group( -1 )
52 {
53     // Check validity of all inputs.
54     ABCA_ASSERT( iParentGroup >= 0, "Invalid parent group" );
55 
56     // Create the HDF5 group corresponding to this object.
57     hid_t copl = CreationOrderPlist();
58     m_group = H5Gcreate2( iParentGroup, iName.c_str(),
59                           H5P_DEFAULT, copl, H5P_DEFAULT );
60     H5Pclose( copl );
61     ABCA_ASSERT( m_group >= 0,
62                  "Could not create group for object: " << iName );
63 
64     m_data = Alembic::Util::shared_ptr<CpwData>(
65         new CpwData( ".prop", m_group ) );
66 
67     AbcA::PropertyHeader topHeader( ".prop", iMetaData );
68     WritePropertyInfo( m_group, topHeader, false, 0, 0, 0, 0 );
69 }
70 
71 //-*****************************************************************************
~OwData()72 OwData::~OwData()
73 {
74     if ( m_group >= 0 )
75     {
76         H5Gclose( m_group );
77         m_group = -1;
78     }
79 }
80 
81 //-*****************************************************************************
82 AbcA::CompoundPropertyWriterPtr
getProperties(AbcA::ObjectWriterPtr iParent)83 OwData::getProperties( AbcA::ObjectWriterPtr iParent )
84 {
85     AbcA::CompoundPropertyWriterPtr ret = m_top.lock();
86     if ( ! ret )
87     {
88         // time to make a new one
89         ret = Alembic::Util::shared_ptr<CpwImpl>( new CpwImpl( iParent,
90             m_data, iParent->getMetaData() ) );
91         m_top = ret;
92     }
93 
94     return ret;
95 }
96 
97 //-*****************************************************************************
getNumChildren()98 size_t OwData::getNumChildren()
99 {
100     return m_childHeaders.size();
101 }
102 
103 //-*****************************************************************************
getChildHeader(size_t i)104 const AbcA::ObjectHeader & OwData::getChildHeader( size_t i )
105 {
106     if ( i >= m_childHeaders.size() )
107     {
108         ABCA_THROW( "Out of range index in OwImpl::getChildHeader: "
109                      << i );
110     }
111 
112     ABCA_ASSERT( m_childHeaders[i], "Invalid child header: " << i );
113 
114     return *(m_childHeaders[i]);
115 }
116 
117 //-*****************************************************************************
getChildHeader(const std::string & iName)118 const AbcA::ObjectHeader * OwData::getChildHeader( const std::string &iName )
119 {
120     size_t numChildren = m_childHeaders.size();
121     for ( size_t i = 0; i < numChildren; ++i )
122     {
123         if ( m_childHeaders[i]->getName() == iName )
124         {
125             return m_childHeaders[i].get();
126         }
127     }
128 
129     return NULL;
130 }
131 
132 //-*****************************************************************************
getChild(const std::string & iName)133 AbcA::ObjectWriterPtr OwData::getChild( const std::string &iName )
134 {
135     MadeChildren::iterator fiter = m_madeChildren.find( iName );
136     if ( fiter == m_madeChildren.end() )
137     {
138         return AbcA::ObjectWriterPtr();
139     }
140 
141     WeakOwPtr wptr = (*fiter).second;
142     return wptr.lock();
143 }
144 
createChild(AbcA::ObjectWriterPtr iParent,const std::string & iFullName,const AbcA::ObjectHeader & iHeader)145 AbcA::ObjectWriterPtr OwData::createChild( AbcA::ObjectWriterPtr iParent,
146                                            const std::string & iFullName,
147                                            const AbcA::ObjectHeader &iHeader )
148 {
149     std::string name = iHeader.getName();
150 
151     if ( m_madeChildren.count( name ) )
152     {
153         ABCA_THROW( "Already have an Object named: "
154                      << name );
155     }
156 
157     if ( name.empty() )
158     {
159         ABCA_THROW( "Object not given a name, parent is: " <<
160                     iFullName );
161     }
162     else if ( iHeader.getName().find('/') != std::string::npos )
163     {
164         ABCA_THROW( "Object has illegal name: "
165                      << iHeader.getName() );
166     }
167 
168     std::string parentName = iFullName;
169     if ( parentName != "/" )
170     {
171         parentName += "/";
172     }
173 
174     ObjectHeaderPtr header(
175         new AbcA::ObjectHeader( iHeader.getName(),
176                                 parentName + iHeader.getName(),
177                                 iHeader.getMetaData() ) );
178 
179     Alembic::Util::shared_ptr<OwImpl> ret( new OwImpl( iParent,
180                             m_group,
181                             header ) );
182 
183     m_childHeaders.push_back( header );
184     m_madeChildren[iHeader.getName()] = WeakOwPtr( ret );
185 
186     return ret;
187 }
188 
189 } // End namespace ALEMBIC_VERSION_NS
190 } // End namespace AbcCoreHDF5
191 } // End namespace Alembic
192