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  ~GA_AIFSharedStringTuple() override;
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,
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  int getTupleSize(const GA_Attribute *attrib) const override = 0;
251 
252  /// Set the tuple size
253  bool setTupleSize(GA_Attribute *attrib, int size) const override = 0;
254 
255  /// Get a single string from the array for a single tuple of an element.
256  const char *getString(const GA_Attribute *attrib, GA_Offset ai,
257  int tuple_index=0) const override;
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  bool setString(GA_Attribute *attrib, GA_Offset ai,
271  const char *string,
272  int tuple_index) const override;
273  /// Set a single component for a range of elements.
274  bool setString(GA_Attribute *attrib, const GA_Range &ai,
275  const char *string,
276  int tuple_index) const override;
277  /// Set a single component for a single element.
278  virtual bool setHandle(GA_Attribute *attrib, GA_Offset ai,
280  int tuple_index) const = 0;
281  /// Set a single component for a range of elements.
282  virtual bool setHandle(GA_Attribute *attrib, const GA_Range &ai,
284  int tuple_index) const;
285 
286  /// Set multiple components for a single element
287  virtual bool setHandles(GA_Attribute *attrib, GA_Offset ai,
288  const GA_StringIndexType *handles,
289  int count, int start=0) const;
290  /// Set multiple components for a range of elements
291  virtual bool setHandles(GA_Attribute *attrib, const GA_Range &ai,
292  const GA_StringIndexType *handles,
293  int count, int start=0) const;
294 
295 public:
296  // --------------------------------------------------------------
297  // Interface to deal with a detail attribute as a list of strings
298  //
299  // By default interface uses the simple tuple interface defined above.
300  // --------------------------------------------------------------
301 
302  /// @{
303  /// Array API, select functions can be more efficiently implemented using
304  /// shared strings.
305  /// Please see GA_AIFStringTuple for remainder of interface
306  int arrayGetLength(const GA_Attribute *attrib,
307  GA_Offset element_index=GA_Offset(0)
308  ) const override;
309  int arrayFindString(const GA_Attribute *attrib,
310  const char *string,
311  GA_Offset element_index=GA_Offset(0)
312  ) const override;
313  bool arrayDestroyString(GA_Attribute *attrib,
314  int string_index,
315  GA_Offset element_index=GA_Offset(0)
316  ) const override;
317  /// @}
318 
319 public:
320  /// @brief Temporary container to hold references to multiple strings
321  ///
322  /// In some cases, it's more expedient to add multiple strings to the
323  /// attribute, and then assign the string values after the fact. This
324  /// class is similar to the GA_AIFBlob::BlobBuffer class, but is
325  /// specialized for shared string attributes.
327  {
328  public:
330  const GA_AIFSharedStringTuple *aif=NULL);
332  : myAttribute(NULL)
333  , myAIFSharedStringTuple(NULL)
334  {
335  *this = src;
336  }
338  {
339  clear();
340  }
341 
343 
344  /// Return number of strings referenced in the string buffer
345  GA_Size entries() const { return myHandleList.entries(); }
346 
347  /// Add a string to the attribute. Returns the handle of the string in
348  /// the attribute (not the string's index in the buffer).
349  GA_StringIndexType append(const char *string);
350 
351  /// Return the string index from the buffer. The index refers to the
352  /// buffer index (not the string handle).
353  GA_StringIndexType getStringIndex(GA_Size i) const;
354  /// Return a string handle from the buffer. The index refers to the
355  /// buffer index (not the string handle).
356  const char *getString(GA_Size i) const;
357 
358  /// Clear references to all strings contained in the buffer.
359  void clear();
360  private:
361  UT_Array<GA_StringIndexType> myHandleList;
362  const GA_AIFSharedStringTuple *myAIFSharedStringTuple;
363  GA_Attribute *myAttribute;
364  };
365 
366  /// @{
367  /// Method to add multiple strings in a batch process. The strings will be
368  /// temporarily added to the attribute for as long as the StringBuffer
369  /// exists. When the StringBuffer is deleted, the strings will be deleted
370  /// from the attribute unless referenced by elements in the attribute
371  /// array.
372  ///
373  /// Information about the strings (i.e. the handles) can be retriefed from
374  /// the StringBuffer. For example: @code
375  /// UT_StringArray s(strings);
376  /// GA_AIFSharedStringTuple::StringBuffer handles;
377  /// handles = a->getAIFSharedStringTuple()->addStrings(s);
378  /// for (GA_Size i = 0; i < handles.entries(); ++i)
379  /// cerr << s(i) << " handle=" << handles.getStringIndex(i) << endl;
380  /// @endcode
381  StringBuffer addStrings(GA_Attribute *attribute,
382  const UT_StringArray &strings) const;
383  StringBuffer addStrings(GA_Attribute *attribute,
384  const UT_Array<const char *> &strings) const;
385  /// @}
386  friend class StringBuffer; // Allow the string buffer to add refs
387 };
388 
389 #endif
bool arrayDestroyString(GA_Attribute *attrib, int string_index, GA_Offset element_index=GA_Offset(0)) const override
Definition of a geometry attribute.
Definition: GA_Attribute.h:198
Temporary container to hold references to multiple strings.
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 start
Definition: glcorearb.h:475
int64 exint
Definition: SYS_Types.h:125
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
#define GA_API
Definition: GA_API.h:14
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:236
virtual GA_StringIndexType addStringReference(GA_Attribute *attribute, const char *string) const =0
Add (or increment) reference to a string.
int getTupleSize(const GA_Attribute *attrib) const override=0
Query the tuple size.
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.
bool setTupleSize(GA_Attribute *attrib, int size) const override=0
Set the tuple size.
GA_Size GA_Offset
Definition: GA_Types.h:646
GLdouble n
Definition: glcorearb.h:2008
UT_IndexedHashMapItemId GA_BlobIndex
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
iterator & operator=(const iterator &src)
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.
GLsizei const GLchar *const * strings
Definition: glcorearb.h:1933
int arrayGetLength(const GA_Attribute *attrib, GA_Offset element_index=GA_Offset(0)) const override
GLsizeiptr size
Definition: glcorearb.h:664
GA_StringIndexType getHandle() const
Class to iterate over all the strings in the shared string table.
LeafData & operator=(const LeafData &)=delete
GLuint index
Definition: glcorearb.h:786
bool setString(GA_Attribute *attrib, GA_Offset ai, const char *string, int tuple_index) const override
Set a single component for a single element.
A specialization of GA_AIFStringTuple to access "shared strings".
int arrayFindString(const GA_Attribute *attrib, const char *string, GA_Offset element_index=GA_Offset(0)) const override
GA_BlobIndex GA_StringIndexType
OIIO_API bool attribute(string_view name, TypeDesc type, const void *val)
iterator begin(const GA_Attribute *a) const
const char * getString(const GA_Attribute *attrib, GA_Offset ai, int tuple_index=0) const override
Get a single string from the array for a single tuple of an element.
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.
GLint GLsizei count
Definition: glcorearb.h:405
Generic Attribute Interface class to work with string indices directly, rather than string values...
GLenum src
Definition: glcorearb.h:1793