HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MetaData.h
Go to the documentation of this file.
1 //-*****************************************************************************
2 //
3 // Copyright (c) 2009-2011,
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_AbcCoreAbstract_MetaData_h_
38 #define _Alembic_AbcCoreAbstract_MetaData_h_
39 
41 
42 namespace Alembic {
43 namespace AbcCoreAbstract {
44 namespace ALEMBIC_VERSION_NS {
45 
46 //-*****************************************************************************
47 //! The MetaData class lies at the core of Alembic's notion of
48 //! "Object and Property Identity". It is a refinement of the idea of
49 //! Protocol (for Objects) and Interpretation (for Properties) in OpenGTO.
50 //! It is, essentially, an UNORDERED, UNIQUE DICTIONARY of strings.
51 //! It turns itself into a regular string for serialization and deserialization.
52 //! This is not a virtual class, nor is it intended to be used as a base
53 //! for derivation. It is explicitly declared and implemented as part of
54 //! the AbcCoreAbstract library.
55 //! It is composed (not inherited) from \ref Alembic::Util::TokenMap.
56 //! In order to not have duplicated (and possibly conflicting) policy
57 //! implementation, we present this class here as a MOSTLY-WRITE-ONCE interface,
58 //! with selective exception throwing behavior for failed writes.
59 class MetaData
60 {
61 public:
62  //-*************************************************************************
63  // TYPEDEFS
64  //-*************************************************************************
65 
66  //! Our internals are handled by a TokenMap, which we expose
67  //! through these typedefs.
69 
70  //! Key type.
71  //! Keys are unique within each MetaData instance.
73 
74  //! Data type.
75  //! Data is associated with a key, with each key being unique.
77 
78  //! Value-type
79  //! This is what the MetaData class "contains", when viewed
80  //! as a standard container.
82 
83  //! Const reference type
84  //! This is what the iterators dereference to.
86 
87  //! const_iterator typedef
88  //! this dereferences to a const \ref value_type reference.
90 
91  //! const_reverse_iterator typedef
92  //! this dereferences to a const \ref value_type instance.
94 
95  //-*************************************************************************
96  // CONSTRUCTION
97  //-*************************************************************************
98 
99  //! Default constructor creates an empty dictionary.
100  //! ...
101  MetaData() {}
102 
103  //! Copy constructor copies another MetaData.
104  //! ...
105  MetaData( const MetaData &iCopy ) : m_tokenMap( iCopy.m_tokenMap ) {}
106 
107  //! Assignment operator copies the contents of another
108  //! MetaData instance.
109  MetaData& operator=( const MetaData &iCopy )
110  {
111  m_tokenMap = iCopy.m_tokenMap;
112  return *this;
113  }
114 
115  //-*************************************************************************
116  // SERIALIZATION/DESERIALIZATION
117  //-*************************************************************************
118 
119  //! Deserialization will replace the contents of this class with the
120  //! parsed contents of a string. It will just clear the contents first.
121  //! It will throw an exception if the string is mal-formed.
122  //! \internal For library implementation internal use.
123  void deserialize( const std::string &iFrom )
124  {
125  m_tokenMap.clear();
126  m_tokenMap.setUnique( iFrom, ';', '=', true );
127  }
128 
129  //! Serialization will convert the contents of this MetaData into a
130  //! single string.
131  //! \internal For library implementation internal use.
133  {
134  return m_tokenMap.get( ';', '=', true );
135  }
136 
137  //-*************************************************************************
138  // SIZE
139  //-*************************************************************************
140  size_t size() const { return m_tokenMap.size(); }
141 
142  //-*************************************************************************
143  // ITERATION
144  //-*************************************************************************
145 
146  //! Returns a \ref const_iterator corresponding to the beginning of the
147  //! MetaData or the end of the MetaData if empty.
148  const_iterator begin() const { return m_tokenMap.begin(); }
149 
150  //! Returns a \ref const_iterator corresponding to the end of the
151  //! MetaData.
152  const_iterator end() const { return m_tokenMap.end(); }
153 
154  //! Returns a \ref const_reverse_iterator corresponding to the beginning
155  //! of the MetaData or the end of the MetaData if empty.
156  const_reverse_iterator rbegin() const { return m_tokenMap.rbegin(); }
157 
158  //! Returns an \ref const_reverse_iterator corresponding to the end
159  //! of the MetaData.
160  const_reverse_iterator rend() const { return m_tokenMap.rend(); }
161 
162  //-*************************************************************************
163  // ACCESS/ASSIGNMENT
164  //-*************************************************************************
165 
166  //! set lets you set a key/data pair.
167  //! This will silently overwrite an existing value.
168  void set( const std::string &iKey, const std::string &iData )
169  {
170  m_tokenMap.setValue( iKey, iData );
171  }
172 
173  //! setUnique lets you set a key/data pair,
174  //! but throws an exception if you attempt to change the value
175  //! of an existing field. It is fine if you set the same value.
176  //! \remarks Not the most efficient implementation at the moment.
177  void setUnique( const std::string &iKey, const std::string &iData )
178  {
179  std::string found = m_tokenMap.value( iKey );
180  if ( found == "" )
181  {
182  m_tokenMap.setValue( iKey, iData );
183  }
184  else if ( found != iData )
185  {
186  ABCA_THROW( "Key: " << iKey << " already exists in MetaData" );
187  }
188  }
189 
190  //! get returns the value, or an empty string if it is not set.
191  //! ...
192  std::string get( const std::string &iKey ) const
193  {
194  return m_tokenMap.value( iKey );
195  }
196 
197  //! getRequired returns the value, and throws an exception if it is
198  //! not found.
199  std::string getRequired( const std::string &iKey ) const
200  {
201  std::string ret = m_tokenMap.value( iKey );
202  if ( ret == "" )
203  {
204  ABCA_THROW( "Key: " << iKey << " did not exist in MetaData" );
205  }
206  return ret;
207  }
208 
209  //! append appends the given MetaData to this class. Duplicates are
210  //! overwritten.
211  void append( const MetaData &iMetaData )
212  {
213  for ( const_iterator iter = iMetaData.begin();
214  iter != iMetaData.end(); ++iter )
215  {
216  set( (*iter).first, (*iter).second );
217  }
218  }
219 
220  //! append appends the given MetaData to this class. Duplicate values
221  //! will cause an exception to be thrown.
222  void appendUnique( const MetaData &iMetaData )
223  {
224  for ( const_iterator iter = iMetaData.begin();
225  iter != iMetaData.end(); ++iter )
226  {
227  setUnique( (*iter).first, (*iter).second );
228  }
229  }
230 
231  //-*************************************************************************
232  // MATCHING
233  // Simple matching for now, we'll save regex stuff for later.
234  //-*************************************************************************
235 
236  //! The matches function returns true if each of the fields in the passed
237  //! iMetaData are found in this instance and have the same values.
238  //! it returns false otherwise.
239  //! This is not the same as "equals", because this MetaData may contain
240  //! fields that are not included in the passed iMetaData.
241  //! This should be the default "matching" function.
242  bool matches( const MetaData &iMetaData ) const
243  {
244  for ( const_iterator iter = iMetaData.begin();
245  iter != iMetaData.end(); ++iter )
246  {
247  if ( get( (*iter).first ) != (*iter).second )
248  {
249  return false;
250  }
251  }
252  return true;
253  }
254 
255  //! The matchesExisting function returns true if, for each of the fields
256  //! in the passed iMetaData, we have either no entry, or the same entry.
257  bool matchesOverlap( const MetaData &iMetaData ) const
258  {
259  for ( const_iterator iter = iMetaData.begin();
260  iter != iMetaData.end(); ++iter )
261  {
262  std::string found = get( (*iter).first );
263  if ( found != "" && found != (*iter).second )
264  {
265  return false;
266  }
267  }
268  return true;
269  }
270 
271  //! the matchesExactly function returns true if we're exactly equal in
272  //! every field. This is a rarely useful concept with MetaData.
273  //! It is for this reason that we explicitly do not overload the == operator.
274  bool matchesExactly( const MetaData &iMetaData ) const
275  {
276  return m_tokenMap.exactMatch( iMetaData.m_tokenMap );
277  }
278 
279 private:
280  Alembic::Util::TokenMap m_tokenMap;
281 };
282 
283 } // End namespace ALEMBIC_VERSION_NS
284 
285 using namespace ALEMBIC_VERSION_NS;
286 
287 } // End namespace AbcCoreAbstract
288 } // End namespace Alembic
289 
290 #endif
reverse_iterator rbegin()
same as std::map rbegin Returns an reverse_iterator corresponding to the reverse_beginning of the map...
Definition: TokenMap.h:275
void setUnique(const std::string &config, char pairSeparator= ';', char assignSeparator= '=', bool quiet=true)
This function sets only unique (not already stored) token/value pairs by deserializing them from a do...
bool matches(const MetaData &iMetaData) const
Definition: MetaData.h:242
void setValue(const std::string &keyStr, const std::string &valueStr)
This function sets the value of a token. It will either add a new token-value pair if the map does no...
Definition: TokenMap.h:239
map_type::const_iterator const_iterator
Definition: TokenMap.h:89
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
#define ABCA_THROW(TEXT)
Definition: Foundation.h:96
void appendUnique(const MetaData &iMetaData)
Definition: MetaData.h:222
size_t size() const
This function returns the number of pairs. ...
Definition: TokenMap.h:201
map_type::const_reference const_reference
Definition: TokenMap.h:105
iterator begin()
same as std::map begin Returns an iterator corresponding to the beginning of the map or the end of th...
Definition: TokenMap.h:252
A wrapper around std::map that serializes and deserializes the map into a doubly-tokenized string...
Definition: TokenMap.h:60
bool matchesExactly(const MetaData &iMetaData) const
Definition: MetaData.h:274
bool matchesOverlap(const MetaData &iMetaData) const
Definition: MetaData.h:257
token_map_type::const_reference const_reference
Definition: MetaData.h:85
void deserialize(const std::string &iFrom)
Definition: MetaData.h:123
iterator end()
same as std::map end Returns an iterator corresponding to the end of the map.
Definition: TokenMap.h:261
token_map_type::const_reverse_iterator const_reverse_iterator
Definition: MetaData.h:93
token_map_type::const_iterator const_iterator
Definition: MetaData.h:89
map_type::const_reverse_iterator const_reverse_iterator
Definition: TokenMap.h:97
std::string getRequired(const std::string &iKey) const
Definition: MetaData.h:199
std::string get(char pairSeparator= ';', char assignSeparator= '=', bool check=false) const
This function turns the map back into a doubly-tokenized string.
bool exactMatch(const TokenMap &iOther) const
Definition: TokenMap.h:298
MetaData & operator=(const MetaData &iCopy)
Definition: MetaData.h:109
void set(const std::string &iKey, const std::string &iData)
Definition: MetaData.h:168
std::string value(const std::string &token) const
This function returns the string value associated with a particular token, or the empty string "" if ...
Definition: TokenMap.h:213
reverse_iterator rend()
same as std::map rend Returns an reverse_iterator corresponding to the reverse end of the map...
Definition: TokenMap.h:285
void setUnique(const std::string &iKey, const std::string &iData)
Definition: MetaData.h:177
#define ALEMBIC_VERSION_NS
Definition: Foundation.h:104