1 //-*****************************************************************************
2 //
3 // Copyright (c) 2013,
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 <sstream>
38 #include <Alembic/AbcCoreAbstract/All.h>
39 #include <Alembic/AbcCoreOgawa/All.h>
40 #include <Alembic/Util/All.h>
41 
42 #include <Alembic/AbcCoreAbstract/Tests/Assert.h>
43 
44 //-*****************************************************************************
45 namespace AO = Alembic::AbcCoreOgawa;
46 
47 namespace AbcA = Alembic::AbcCoreAbstract;
48 
49 //-*****************************************************************************
testObjects(bool iUseMMap)50 void testObjects(bool iUseMMap)
51 {
52     std::string archiveName = "objectTest.abc";
53     {
54         AO::WriteArchive w;
55         AbcA::ArchiveWriterPtr a = w(archiveName, AbcA::MetaData());
56         AbcA::ObjectWriterPtr archive = a->getTop();
57         TESTING_ASSERT(archive->getName() == "ABC");
58         TESTING_ASSERT(archive->getFullName() == "/");
59 
60         AbcA::ObjectWriterPtr child1 = archive->createChild(
61             AbcA::ObjectHeader("wow", AbcA::MetaData()));
62         TESTING_ASSERT(child1->getName() == "wow");
63         TESTING_ASSERT(child1->getFullName() == "/wow");
64 
65         AbcA::ObjectWriterPtr child2 = archive->createChild(
66             AbcA::ObjectHeader("bar", AbcA::MetaData()));
67         TESTING_ASSERT(child2->getName() == "bar");
68         TESTING_ASSERT(child2->getFullName() == "/bar");
69 
70         AbcA::ObjectWriterPtr child3 = archive->createChild(
71             AbcA::ObjectHeader("foo", AbcA::MetaData()));
72         TESTING_ASSERT(child3->getName() == "foo");
73         TESTING_ASSERT(child3->getFullName() == "/foo");
74 
75         TESTING_ASSERT(archive->getNumChildren() == 3);
76 
77         TESTING_ASSERT(child1->getNumChildren() == 0);
78         AbcA::ObjectWriterPtr gchild = child1->createChild(
79             AbcA::ObjectHeader("food", AbcA::MetaData()));
80         TESTING_ASSERT(child1->getNumChildren() == 1);
81         TESTING_ASSERT(gchild->getNumChildren() == 0);
82         TESTING_ASSERT(gchild->getName() == "food");
83         TESTING_ASSERT(gchild->getFullName() == "/wow/food");
84 
85         gchild = child2->createChild(
86             AbcA::ObjectHeader("hat", AbcA::MetaData()));
87         TESTING_ASSERT(gchild->getNumChildren() == 0);
88         TESTING_ASSERT(gchild->getName() == "hat");
89         TESTING_ASSERT(gchild->getFullName() == "/bar/hat");
90         TESTING_ASSERT_THROW(child2->createChild(
91             AbcA::ObjectHeader("hat", AbcA::MetaData())),
92             Alembic::Util::Exception);
93         TESTING_ASSERT_THROW(child2->createChild(
94             AbcA::ObjectHeader("slashy/", AbcA::MetaData())),
95             Alembic::Util::Exception);
96         TESTING_ASSERT_THROW(child2->createChild(
97             AbcA::ObjectHeader("sla/shy", AbcA::MetaData())),
98             Alembic::Util::Exception);
99         TESTING_ASSERT_THROW(child2->createChild(
100             AbcA::ObjectHeader("/slashy", AbcA::MetaData())),
101             Alembic::Util::Exception);
102         TESTING_ASSERT_THROW(child2->createChild(
103             AbcA::ObjectHeader("", AbcA::MetaData())),
104             Alembic::Util::Exception);
105         gchild = child2->createChild(
106             AbcA::ObjectHeader("bowling", AbcA::MetaData()));
107         TESTING_ASSERT(gchild->getNumChildren() == 0);
108         TESTING_ASSERT(gchild->getName() == "bowling");
109         TESTING_ASSERT(gchild->getFullName() == "/bar/bowling");
110         TESTING_ASSERT(child2->getNumChildren() == 2);
111 
112         gchild = child3->createChild(
113             AbcA::ObjectHeader("hamburger", AbcA::MetaData()));
114         TESTING_ASSERT(gchild->getNumChildren() == 0);
115         TESTING_ASSERT(gchild->getName() == "hamburger");
116         TESTING_ASSERT(gchild->getFullName() == "/foo/hamburger");
117 
118         gchild = child3->createChild(
119             AbcA::ObjectHeader("burrito", AbcA::MetaData()));
120         TESTING_ASSERT(gchild->getNumChildren() == 0);
121         TESTING_ASSERT(gchild->getName() == "burrito");
122         TESTING_ASSERT(gchild->getFullName() == "/foo/burrito");
123 
124         gchild = child3->createChild(
125             AbcA::ObjectHeader("pizza", AbcA::MetaData()));
126         TESTING_ASSERT(child3->getNumChildren() == 3);
127         TESTING_ASSERT(gchild->getNumChildren() == 0);
128         TESTING_ASSERT(gchild->getName() == "pizza");
129         TESTING_ASSERT(gchild->getFullName() == "/foo/pizza");
130     }
131 
132     {
133         AO::ReadArchive r(1, iUseMMap);
134         AbcA::ArchiveReaderPtr a = r( archiveName );
135         AbcA::ObjectReaderPtr archive = a->getTop();
136         TESTING_ASSERT(archive->getNumChildren() == 3);
137         TESTING_ASSERT(archive->getName() == "ABC");
138         TESTING_ASSERT(archive->getFullName() == "/");
139 
140         AbcA::ObjectReaderPtr child = archive->getChild(0);
141         TESTING_ASSERT(child->getName() == "wow");
142         TESTING_ASSERT(child->getFullName() == "/wow");
143         TESTING_ASSERT(child->getNumChildren() == 1);
144         AbcA::ObjectReaderPtr gchild = child->getChild(0);
145         TESTING_ASSERT(gchild->getNumChildren() == 0);
146         TESTING_ASSERT(gchild->getName() == "food");
147         TESTING_ASSERT(gchild->getFullName() == "/wow/food");
148 
149         child = archive->getChild(1);
150         TESTING_ASSERT(child->getName() == "bar");
151         TESTING_ASSERT(child->getFullName() == "/bar");
152         TESTING_ASSERT(child->getNumChildren() == 2);
153         gchild = child->getChild(0);
154         TESTING_ASSERT(gchild->getNumChildren() == 0);
155         TESTING_ASSERT(gchild->getName() == "hat");
156         TESTING_ASSERT(gchild->getFullName() == "/bar/hat");
157         gchild = child->getChild(1);
158         TESTING_ASSERT(gchild->getNumChildren() == 0);
159         TESTING_ASSERT(gchild->getName() == "bowling");
160         TESTING_ASSERT(gchild->getFullName() == "/bar/bowling");
161 
162         child = archive->getChild(2);
163         TESTING_ASSERT(child->getName() == "foo");
164         TESTING_ASSERT(child->getFullName() == "/foo");
165         TESTING_ASSERT(child->getNumChildren() == 3);
166         gchild = child->getChild(0);
167         TESTING_ASSERT(gchild->getNumChildren() == 0);
168         TESTING_ASSERT(gchild->getName() == "hamburger");
169         TESTING_ASSERT(gchild->getFullName() == "/foo/hamburger");
170         gchild = child->getChild(1);
171         TESTING_ASSERT(gchild->getNumChildren() == 0);
172         TESTING_ASSERT(gchild->getName() == "burrito");
173         TESTING_ASSERT(gchild->getFullName() == "/foo/burrito");
174         gchild = child->getChild(2);
175         TESTING_ASSERT(gchild->getNumChildren() == 0);
176         TESTING_ASSERT(gchild->getFullName() == "/foo/pizza");
177         TESTING_ASSERT(gchild->getName() == "pizza");
178 
179         AO::ReadArchive r2(1, iUseMMap);
180         AbcA::ArchiveReaderPtr a2 = r2( archiveName );
181         AbcA::ObjectReaderPtr archive2 = a2->getTop();
182         AbcA::ObjectReaderPtr child2 = archive->getChild(0);
183         AbcA::ObjectReaderPtr gchild2 = child2->getChild(0);
184         TESTING_ASSERT(gchild2->getNumChildren() == 0);
185         TESTING_ASSERT(gchild2->getName() == "food");
186         TESTING_ASSERT(gchild2->getFullName() == "/wow/food");
187     }
188 }
189 
testChildObjects(bool iUseMMap)190 void testChildObjects(bool iUseMMap)
191 {
192     std::string archiveName = "objectChildrenTest.abc";
193     {
194         AO::WriteArchive w;
195         AbcA::ArchiveWriterPtr a = w(archiveName, AbcA::MetaData());
196         AbcA::ObjectWriterPtr archive = a->getTop();
197 
198         AbcA::ObjectWriterPtr smallChild = archive->createChild(
199             AbcA::ObjectHeader("small", AbcA::MetaData()));
200         for (std::size_t i = 0; i < 10; ++i)
201         {
202             std::stringstream strm;
203             strm << i;
204             smallChild->createChild(AbcA::ObjectHeader(
205                 strm.str(), AbcA::MetaData()));
206         }
207 
208         AbcA::ObjectWriterPtr medChild = archive->createChild(
209             AbcA::ObjectHeader("md", AbcA::MetaData()));
210         for (std::size_t i = 0; i < 150; ++i)
211         {
212             std::stringstream strm;
213             strm << i;
214             medChild->createChild(AbcA::ObjectHeader(
215                 strm.str(), AbcA::MetaData()));
216         }
217 
218         AbcA::ObjectWriterPtr mdlgChild = archive->createChild(
219             AbcA::ObjectHeader("mdlg", AbcA::MetaData()));
220         for (std::size_t i = 0; i < 300; ++i)
221         {
222             std::stringstream strm;
223             strm << i;
224              mdlgChild->createChild(AbcA::ObjectHeader(
225                 strm.str(), AbcA::MetaData()));
226         }
227 
228         AbcA::ObjectWriterPtr largeChild = archive->createChild(
229             AbcA::ObjectHeader("large", AbcA::MetaData()));
230         for (std::size_t i = 0; i < 33000; ++i)
231         {
232             std::stringstream strm;
233             strm << i;
234             largeChild->createChild(AbcA::ObjectHeader(
235                 strm.str(), AbcA::MetaData()));
236         }
237 
238         AbcA::ObjectWriterPtr insaneChild = archive->createChild(
239             AbcA::ObjectHeader("insane", AbcA::MetaData()));
240         for (std::size_t i = 0; i < 66000; ++i)
241         {
242             std::stringstream strm;
243             strm << i;
244             insaneChild->createChild(AbcA::ObjectHeader(
245                 strm.str(), AbcA::MetaData()));
246         }
247     }
248 
249     {
250         AO::ReadArchive r(1, iUseMMap);
251         AbcA::ArchiveReaderPtr a = r( archiveName );
252         AbcA::ObjectReaderPtr archive = a->getTop();
253         AbcA::ObjectReaderPtr smallChild = archive->getChild(0);
254         AbcA::ObjectReaderPtr mdChild = archive->getChild(1);
255         AbcA::ObjectReaderPtr mdlgChild = archive->getChild(2);
256         AbcA::ObjectReaderPtr largeChild = archive->getChild(3);
257         AbcA::ObjectReaderPtr insaneChild = archive->getChild(4);
258 
259         TESTING_ASSERT(smallChild->getNumChildren() == 10);
260         TESTING_ASSERT(mdChild->getNumChildren() == 150);
261         TESTING_ASSERT(mdlgChild->getNumChildren() == 300);
262         TESTING_ASSERT(largeChild->getNumChildren() == 33000);
263         TESTING_ASSERT(insaneChild->getNumChildren() == 66000);
264     }
265 }
266 
testMetaData(bool iUseMMap)267 void testMetaData(bool iUseMMap)
268 {
269     std::string archiveName = "objectMetaDataTest.abc";
270     {
271         AO::WriteArchive w;
272         AbcA::ArchiveWriterPtr a = w(archiveName, AbcA::MetaData());
273         AbcA::ObjectWriterPtr archive = a->getTop();
274 
275         AbcA::ObjectWriterPtr child = archive->createChild(
276             AbcA::ObjectHeader("tests", AbcA::MetaData()));
277         for (std::size_t i = 0; i < 300; ++i)
278         {
279             std::stringstream strm;
280             strm << i;
281             AbcA::MetaData m;
282             m.set(strm.str(), strm.str());
283             child->createChild(AbcA::ObjectHeader(strm.str(), m));
284         }
285     }
286 
287     {
288         AO::ReadArchive r(1, iUseMMap);
289         AbcA::ArchiveReaderPtr a = r( archiveName );
290         AbcA::ObjectReaderPtr archive = a->getTop();
291         AbcA::ObjectReaderPtr child = archive->getChild(0);
292         for (std::size_t i = 0; i < 300; ++i)
293         {
294             AbcA::ObjectReaderPtr grandChild = child->getChild(i);
295             std::stringstream strm;
296             strm << i;
297             TESTING_ASSERT(grandChild->getName() == strm.str());
298             TESTING_ASSERT(grandChild->getMetaData().get(strm.str())
299                            == strm.str());
300         }
301     }
302 }
303 
runTests(bool iUseMMap)304 void runTests(bool iUseMMap)
305 {
306     testObjects(iUseMMap);
307     testChildObjects(iUseMMap);
308     testMetaData(iUseMMap);
309 }
310 
main(int argc,char * argv[])311 int main ( int argc, char *argv[] )
312 {
313     runTests(true);     // Use mmap
314     runTests(false);    // Use streams
315     return 0;
316 }
317