HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_AIFSharedStringTuple.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GA_AIFSharedStringTuple.h ( GA Library, C++)
7  *
8  * COMMENTS: Attribute Interface class for string index table methods
9  */
10 
11 #ifndef __GA_AIFSharedStringTuple__
12 #define __GA_AIFSharedStringTuple__
13 
14 #include "GA_API.h"
15 
16 #include "GA_AIFStringTuple.h"
17 #include "GA_BlobContainer.h"
18 #include "GA_Types.h"
19 
20 #include <UT/UT_Array.h>
21 #include <UT/UT_VectorTypes.h>
22 
23 #include <stddef.h>
24 
25 
26 class GA_Attribute;
27 class GA_Range;
29 
30 
31 /// Index type
32 /// WARNING: We assume that GA_StringIndexType and GA_BlobIndexType
33 /// are binare compatible, so do not change this!
35 #define GA_INVALID_STRING_INDEX GA_StringIndexType(-1)
36 
38 {
39 public:
41  : myCapacity(0)
42  , myEntries(0)
43  {
44  }
46 
47  GA_Size getEntries() const { return myEntries; }
48  GA_Size getCapacity() const { return myCapacity; }
49 
50  void setEntries(GA_Size n) { myEntries = n; }
51  void setCapacity(GA_Size n) { myCapacity = n; }
52 private:
53  GA_Size myEntries, myCapacity;
54 };
55 
56 /// @brief A specialization of GA_AIFStringTuple to access "shared strings"
57 ///
58 /// This class provides the interface to access string table data. Each
59 /// attribute type may provide this interface if it makes sense.
61 {
62 public:
64  virtual ~GA_AIFSharedStringTuple();
65 
66  /// Query information about the string storage.
67  virtual bool getStatistics(const GA_Attribute *attrib,
68  GA_StringTableStatistics &stats) const = 0;
69 
70  /// Compact the string storage
71  virtual bool compactStorage(GA_Attribute *attrib) const = 0;
72 
73  /// Extract data from the string table. This will extract all the unique
74  /// strings which are referenced by the attribute.
75  /// The string handles are guaranteed to be in ascending order, but
76  /// may or may not be contiguous.
77  virtual bool extractStrings(const GA_Attribute *attrib,
79  UT_IntArray &handles) const = 0;
80  /// Stop after reaching a maximum
81  virtual bool extractStrings(const GA_Attribute *attrib,
82  UT_StringArray &strings,
83  UT_IntArray &handles,
84  exint maxstrings) const = 0;
85 
86  /// Extract all of the unique string handles of the attribute.
87  /// The string handles are guaranteed to be in ascending order, but
88  /// may or may not be contiguous.
89  virtual bool extractHandles(const GA_Attribute *attrib,
90  UT_IntArray &handles) const = 0;
91 
92 public:
93  // --------------------------------------------------------------
94  // Interface to deal with string handles.
95  // --------------------------------------------------------------
96 
97  /// Return the number of entries in the shared string table
98  GA_Size getTableEntries(const GA_Attribute *attrib) const
99  {
101  if (attrib && getStatistics(attrib, stats))
102  return stats.getCapacity();
103  return 0;
104  }
105 
106  /// It's possible that there are invalid handle indexes mixed with the
107  /// valid handles. When iterating over all the handles, you can call @c
108  /// validateTableHandle() which will ensure that there's a string
109  /// associated with the given handle.
110  virtual GA_StringIndexType validateTableHandle(const GA_Attribute *attrib,
111  GA_StringIndexType index) const = 0;
112 
113  /// Get a string from the string table (without going through an attribute)
114  virtual const char *getTableString(const GA_Attribute *attrib,
115  GA_StringIndexType handle) const = 0;
116 
117  /// Get the handle (index) corresponding to the given string, returning -1
118  /// if none.
119  virtual GA_StringIndexType getTableHandle(const GA_Attribute *attrib,
120  const char *string) const = 0;
121 
122  /// GA_StringIndexType indices may not be contiguous, this method allows
123  /// you to get a string given an ordered index. Strings will be defined
124  /// for all contiguous strings. This may be an expensive operation, it's
125  /// better to access strings by their index if possible.
126  ///
127  /// This method will return a NULL pointer past the end of the string table
128  virtual const char *getTableOrderedString(const GA_Attribute *a,
129  exint index) const = 0;
130 
131 
132  /// Replace a string in the shared string table with a new value. Warning,
133  /// it's possible that the table will "collapse" after the replacement.
134  /// For example: @code
135  /// table := [ "foo", "bar" ]
136  /// table.replaceString(1, "foo") # Replace "bar" with "foo"
137  /// table := [ "foo" ]
138  /// @endcode
139  /// In the above example, all elements which originally referenced "bar"
140  /// will now reference "foo". This means that trying to swap two values
141  /// will not work as expected.
142  virtual bool replaceTableString(GA_Attribute *attrib,
143  GA_StringIndexType handle,
144  const char *string) const = 0;
145 
146  /// Class to iterate over all the strings in the shared string table
148  {
149  public:
151  : myAIF(NULL)
152  , myAttrib(NULL)
153  , myString(NULL)
154  , myCount(0)
155  , myIndex(0)
156  {
157  }
160  {
161  myAIF = src.myAIF;
162  myAttrib = src.myAttrib;
163  myString = src.myString;
164  myCount = src.myCount;
165  myIndex = src.myIndex;
166  return *this;
167  }
168  bool operator==(const iterator &src)
169  {
170  if (!src.myAIF)
171  return atEnd();
172  if (!myAIF)
173  return src.atEnd();
174  return myAIF == src.myAIF &&
175  myAttrib == src.myAttrib &&
176  myCount == src.myCount &&
177  myIndex == src.myIndex;
178  }
179  iterator &operator++() { advance(); return *this; }
180  iterator &operator++(int) { advance(); return *this; }
181 
182  void rewind()
183  {
184  myIndex = 0;
185  setupString();
186  }
187  bool atEnd() const { return myIndex >= myCount; }
188  void advance()
189  {
190  myIndex++;
191  setupString();
192  }
193  GA_Size getCount() const { return myCount; }
194  GA_Size getIndex() const { return myIndex; }
196  { return GA_StringIndexType(myIndex); }
197  const char *getString() const { return myString; }
198  private:
199  void setupString()
200  {
201  while (myIndex < myCount)
202  {
203  if (myAIF->validateTableHandle(myAttrib,GA_StringIndexType(myIndex)) >= 0)
204  {
205  myString = myAIF->getTableString(myAttrib, GA_StringIndexType(myIndex));
206  UT_ASSERT_P(myString != nullptr);
207  break;
208  }
209  myIndex++;
210  }
211  }
212  iterator(const GA_AIFSharedStringTuple *aif,
213  const GA_Attribute *a)
214  : myAIF(aif)
215  , myAttrib(a)
216  , myString(NULL)
217  , myIndex(0)
218  , myCount(aif ? aif->getTableEntries(a) : 0)
219  {
220  setupString();
221  }
222 
223  const GA_AIFSharedStringTuple *myAIF;
224  const GA_Attribute *myAttrib;
225  const char *myString;
226  GA_Size myCount;
227  GA_Size myIndex;
229  };
230 
231  iterator begin(const GA_Attribute *a) const
232  { return iterator(this, a); }
233  iterator end() const
234  { return iterator(); }
235 
236 protected:
237  /// Add (or increment) reference to a string
239  const char *string) const = 0;
240  /// Decrement reference to a handle
242  GA_StringIndexType handle) const = 0;
243 
244 public:
245  // --------------------------------------------------------------
246  // Tuple Interface
247  // --------------------------------------------------------------
248 
249  /// Query the tuple size
250  virtual int getTupleSize(const GA_Attribute *attrib) const = 0;
251 
252  /// Set the tuple size
253  virtual bool setTupleSize(GA_Attribute *attrib, int size) const = 0;
254 
255  /// Get a single string from the array for a single tuple of an element.
256  virtual const char *getString(const GA_Attribute *attrib, GA_Offset ai,
257  int tuple_index=0) const;
258 
259  /// Get the handle from the array for a single tuple of an element
260  virtual GA_StringIndexType getHandle(const GA_Attribute *attrib,
261  GA_Offset ai,
262  int tuple_index=0) const = 0;
263 
264  /// Get the full tuple of indices for a single element
265  virtual bool getHandles(const GA_Attribute *attrib, GA_Offset ai,
266  GA_StringIndexType *handles,
267  int count, int start=0) const;
268 
269  /// Set a single component for a single element.
270  virtual bool setString(GA_Attribute *attrib, GA_Offset ai,
271  const char *string, int tuple_index) const;
272  /// Set a single component for a range of elements.
273  virtual bool setString(GA_Attribute *attrib, const GA_Range &ai,
274  const char *string, int tuple_index) const;
275  /// Set a single component for a single element.
276  virtual bool setHandle(GA_Attribute *attrib, GA_Offset ai,
277  GA_StringIndexType handle,
278  int tuple_index) const = 0;
279  /// Set a single component for a range of elements.
280  virtual bool setHandle(GA_Attribute *attrib, const GA_Range &ai,
281  GA_StringIndexType handle,
282  int tuple_index) const;
283 
284  /// Set multiple components for a single element
285  virtual bool setHandles(GA_Attribute *attrib, GA_Offset ai,
286  const GA_StringIndexType *handles,
287  int count, int start=0) const;
288  /// Set multiple components for a range of elements
289  virtual bool setHandles(GA_Attribute *attrib, const GA_Range &ai,
290  const GA_StringIndexType *handles,
291  int count, int start=0) const;
292 
293 public:
294  // --------------------------------------------------------------
295  // Interface to deal with a detail attribute as a list of strings
296  //
297  // By default interface uses the simple tuple interface defined above.
298  // --------------------------------------------------------------
299 
300  /// @{
301  /// Array API, select functions can be more efficiently implemented using
302  /// shared strings.
303  /// Please see GA_AIFStringTuple for remainder of interface
304  virtual int arrayGetLength(const GA_Attribute *attrib,
305  GA_Offset element_index=GA_Offset(0)) const;
306  virtual int arrayFindString(const GA_Attribute *attrib,
307  const char *string,
308  GA_Offset element_index=GA_Offset(0)) const;
309  virtual bool arrayDestroyString(GA_Attribute *attrib,
310  int string_index,
311  GA_Offset element_index=GA_Offset(0)) const;
312  /// @}
313 
314 public:
315  /// @brief Temporary container to hold references to multiple strings
316  ///
317  /// In some cases, it's more expedient to add multiple strings to the
318  /// attribute, and then assign the string values after the fact. This
319  /// class is similar to the GA_AIFBlob::BlobBuffer class, but is
320  /// specialized for shared string attributes.
322  {
323  public:
325  const GA_AIFSharedStringTuple *aif=NULL);
327  : myAttribute(NULL)
328  , myAIFSharedStringTuple(NULL)
329  {
330  *this = src;
331  }
333  {
334  clear();
335  }
336 
337  StringBuffer &operator=(const StringBuffer &src);
338 
339  /// Return number of strings referenced in the string buffer
340  GA_Size entries() const { return myHandleList.entries(); }
341 
342  /// Add a string to the attribute. Returns the handle of the string in
343  /// the attribute (not the string's index in the buffer).
344  GA_StringIndexType append(const char *string);
345 
346  /// Return the string index from the buffer. The index refers to the
347  /// buffer index (not the string handle).
348  GA_StringIndexType getStringIndex(GA_Size i) const;
349  /// Return a string handle from the buffer. The index refers to the
350  /// buffer index (not the string handle).
351  const char *getString(GA_Size i) const;
352 
353  /// Clear references to all strings contained in the buffer.
354  void clear();
355  private:
356  UT_Array<GA_StringIndexType> myHandleList;
357  const GA_AIFSharedStringTuple *myAIFSharedStringTuple;
358  GA_Attribute *myAttribute;
359  };
360 
361  /// @{
362  /// Method to add multiple strings in a batch process. The strings will be
363  /// temporarily added to the attribute for as long as the StringBuffer
364  /// exists. When the StringBuffer is deleted, the strings will be deleted
365  /// from the attribute unless referenced by elements in the attribute
366  /// array.
367  ///
368  /// Information about the strings (i.e. the handles) can be retriefed from
369  /// the StringBuffer. For example: @code
370  /// UT_StringArray s(strings);
371  /// GA_AIFSharedStringTuple::StringBuffer handles;
372  /// handles = a->getAIFSharedStringTuple()->addStrings(s);
373  /// for (GA_Size i = 0; i < handles.entries(); ++i)
374  /// cerr << s(i) << " handle=" << handles.getStringIndex(i) << endl;
375  /// @endcode
376  StringBuffer addStrings(GA_Attribute *attribute,
377  const UT_StringArray &strings) const;
378  StringBuffer addStrings(GA_Attribute *attribute,
379  const UT_Array<const char *> &strings) const;
380  /// @}
381  friend class StringBuffer; // Allow the string buffer to add refs
382 };
383 
384 #endif
Definition of a geometry attribute.
Definition: GA_Attribute.h:190
Temporary container to hold references to multiple strings.
GLsizeiptr size
Definition: glew.h:1681
GLenum src
Definition: glew.h:2410
virtual void delHandleReference(GA_Attribute *attribute, GA_StringIndexType handle) const =0
Decrement reference to a handle.
GA_Size entries() const
Return number of strings referenced in the string buffer.
GLuint index
Definition: glew.h:1814
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
#define GA_API
Definition: GA_API.h:12
GA_Size getTableEntries(const GA_Attribute *attrib) const
Return the number of entries in the shared string table.
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:231
virtual GA_StringIndexType addStringReference(GA_Attribute *attribute, const char *string) const =0
Add (or increment) reference to a string.
A range of elements in an index-map.
Definition: GA_Range.h:42
virtual bool setHandles(GA_Attribute *attrib, GA_Offset ai, const GA_StringIndexType *handles, int count, int start=0) const
Set multiple components for a single element.
GA_Size GA_Offset
Definition: GA_Types.h:637
virtual int arrayGetLength(const GA_Attribute *attrib, GA_Offset element_index=GA_Offset(0)) const
UT_IndexedHashMapItemId GA_BlobIndex
int64 exint
Definition: SYS_Types.h:120
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:134
iterator & operator=(const iterator &src)
GLsizei n
Definition: glew.h:4040
GLsizei const GLchar *const * strings
Definition: glew.h:5883
virtual bool getHandles(const GA_Attribute *attrib, GA_Offset ai, GA_StringIndexType *handles, int count, int start=0) const
Get the full tuple of indices for a single element.
GLuint start
Definition: glew.h:1253
virtual bool setString(GA_Attribute *attrib, GA_Offset ai, const char *string, int tuple_index) const
Set a single component for a single element.
GA_StringIndexType getHandle() const
virtual bool setTupleSize(GA_Attribute *attrib, int size) const =0
Set the tuple size.
Class to iterate over all the strings in the shared string table.
virtual int getTupleSize(const GA_Attribute *attrib) const =0
Query the tuple size.
A specialization of GA_AIFStringTuple to access "shared strings".
GLuint GLuint GLsizei count
Definition: glew.h:1253
GA_BlobIndex GA_StringIndexType
OIIO_API bool attribute(string_view name, TypeDesc type, const void *val)
iterator begin(const GA_Attribute *a) const
virtual bool arrayDestroyString(GA_Attribute *attrib, int string_index, GA_Offset element_index=GA_Offset(0)) const
virtual const char * getString(const GA_Attribute *attrib, GA_Offset ai, int tuple_index=0) const
Get a single string from the array for a single tuple of an element.
virtual int arrayFindString(const GA_Attribute *attrib, const char *string, GA_Offset element_index=GA_Offset(0)) const
virtual bool setHandle(GA_Attribute *attrib, GA_Offset ai, GA_StringIndexType handle, int tuple_index) const =0
Set a single component for a single element.
virtual GA_StringIndexType getHandle(const GA_Attribute *attrib, GA_Offset ai, int tuple_index=0) const =0
Get the handle from the array for a single tuple of an element.
Generic Attribute Interface class to work with string indices directly, rather than string values...