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,
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) const
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 
181  SYS_DEPRECATED_REPLACE(22.0, prefix increment operator)
182  iterator &operator++(int) { advance(); return *this; }
183 
184  void rewind()
185  {
186  myIndex = 0;
187  setupString();
188  }
189  bool atEnd() const { return myIndex >= myCount; }
190  void advance()
191  {
192  myIndex++;
193  setupString();
194  }
195  GA_Size getCount() const { return myCount; }
196  GA_Size getIndex() const { return myIndex; }
198  { return GA_StringIndexType(myIndex); }
199  const char *getString() const { return myString; }
200  private:
201  void setupString()
202  {
203  while (myIndex < myCount)
204  {
205  if (myAIF->validateTableHandle(myAttrib,GA_StringIndexType(myIndex)) >= 0)
206  {
207  myString = myAIF->getTableString(myAttrib, GA_StringIndexType(myIndex));
208  UT_ASSERT_P(myString != nullptr);
209  break;
210  }
211  myIndex++;
212  }
213  }
214  iterator(const GA_AIFSharedStringTuple *aif,
215  const GA_Attribute *a)
216  : myAIF(aif)
217  , myAttrib(a)
218  , myString(NULL)
219  , myIndex(0)
220  , myCount(aif ? aif->getTableEntries(a) : 0)
221  {
222  setupString();
223  }
224 
225  const GA_AIFSharedStringTuple *myAIF;
226  const GA_Attribute *myAttrib;
227  const char *myString;
228  GA_Size myCount;
229  GA_Size myIndex;
231  };
232 
233  iterator begin(const GA_Attribute *a) const
234  { return iterator(this, a); }
235  iterator end() const
236  { return iterator(); }
237 
238 protected:
239  /// Add (or increment) reference to a string
241  const char *string) const = 0;
242  /// Decrement reference to a handle
244  GA_StringIndexType handle) const = 0;
245 
246 public:
247  // --------------------------------------------------------------
248  // Tuple Interface
249  // --------------------------------------------------------------
250 
251  /// Query the tuple size
252  int getTupleSize(const GA_Attribute *attrib) const override = 0;
253 
254  /// Set the tuple size
255  bool setTupleSize(GA_Attribute *attrib, int size) const override = 0;
256 
257  /// Get a single string from the array for a single tuple of an element.
258  const char *getString(const GA_Attribute *attrib, GA_Offset ai,
259  int tuple_index=0) const override;
260 
261  /// Get the handle from the array for a single tuple of an element
262  virtual GA_StringIndexType getHandle(const GA_Attribute *attrib,
263  GA_Offset ai,
264  int tuple_index=0) const = 0;
265 
266  /// Get the full tuple of indices for a single element
267  virtual bool getHandles(const GA_Attribute *attrib, GA_Offset ai,
268  GA_StringIndexType *handles,
269  int count, int start=0) const;
270 
271  /// Set a single component for a single element.
272  bool setString(GA_Attribute *attrib, GA_Offset ai,
273  const char *string,
274  int tuple_index) const override;
275  /// Set a single component for a range of elements.
276  bool setString(GA_Attribute *attrib, const GA_Range &ai,
277  const char *string,
278  int tuple_index) const override;
279  /// Set a single component for a single element.
280  virtual bool setHandle(GA_Attribute *attrib, GA_Offset ai,
281  GA_StringIndexType handle,
282  int tuple_index) const = 0;
283  /// Set a single component for a range of elements.
284  virtual bool setHandle(GA_Attribute *attrib, const GA_Range &ai,
285  GA_StringIndexType handle,
286  int tuple_index) const;
287 
288  /// Set multiple components for a single element
289  virtual bool setHandles(GA_Attribute *attrib, GA_Offset ai,
290  const GA_StringIndexType *handles,
291  int count, int start=0) const;
292  /// Set multiple components for a range of elements
293  virtual bool setHandles(GA_Attribute *attrib, const GA_Range &ai,
294  const GA_StringIndexType *handles,
295  int count, int start=0) const;
296 
297 public:
298  // --------------------------------------------------------------
299  // Interface to deal with a detail attribute as a list of strings
300  //
301  // By default interface uses the simple tuple interface defined above.
302  // --------------------------------------------------------------
303 
304  /// @{
305  /// Array API, select functions can be more efficiently implemented using
306  /// shared strings.
307  /// Please see GA_AIFStringTuple for remainder of interface
308  int arrayGetLength(const GA_Attribute *attrib,
309  GA_Offset element_index=GA_Offset(0)
310  ) const override;
311  int arrayFindString(const GA_Attribute *attrib,
312  const char *string,
313  GA_Offset element_index=GA_Offset(0)
314  ) const override;
315  bool arrayDestroyString(GA_Attribute *attrib,
316  int string_index,
317  GA_Offset element_index=GA_Offset(0)
318  ) const override;
319  /// @}
320 
321 public:
322  /// @brief Temporary container to hold references to multiple strings
323  ///
324  /// In some cases, it's more expedient to add multiple strings to the
325  /// attribute, and then assign the string values after the fact. This
326  /// class is similar to the GA_AIFBlob::BlobBuffer class, but is
327  /// specialized for shared string attributes.
329  {
330  public:
332  const GA_AIFSharedStringTuple *aif=NULL);
334  : myAttribute(NULL)
335  , myAIFSharedStringTuple(NULL)
336  {
337  *this = src;
338  }
340  {
341  clear();
342  }
343 
345 
346  /// Return number of strings referenced in the string buffer
347  GA_Size entries() const { return myHandleList.entries(); }
348 
349  /// Add a string to the attribute. Returns the handle of the string in
350  /// the attribute (not the string's index in the buffer).
351  GA_StringIndexType append(const char *string);
352 
353  /// Return the string index from the buffer. The index refers to the
354  /// buffer index (not the string handle).
355  GA_StringIndexType getStringIndex(GA_Size i) const;
356  /// Return a string handle from the buffer. The index refers to the
357  /// buffer index (not the string handle).
358  const char *getString(GA_Size i) const;
359 
360  /// Clear references to all strings contained in the buffer.
361  void clear();
362  private:
363  UT_Array<GA_StringIndexType> myHandleList;
364  const GA_AIFSharedStringTuple *myAIFSharedStringTuple;
365  GA_Attribute *myAttribute;
366  };
367 
368  /// @{
369  /// Method to add multiple strings in a batch process. The strings will be
370  /// temporarily added to the attribute for as long as the StringBuffer
371  /// exists. When the StringBuffer is deleted, the strings will be deleted
372  /// from the attribute unless referenced by elements in the attribute
373  /// array.
374  ///
375  /// Information about the strings (i.e. the handles) can be retriefed from
376  /// the StringBuffer. For example: @code
377  /// UT_StringArray s(strings);
378  /// GA_AIFSharedStringTuple::StringBuffer handles;
379  /// handles = a->getAIFSharedStringTuple()->addStrings(s);
380  /// for (GA_Size i = 0; i < handles.entries(); ++i)
381  /// cerr << s(i) << " handle=" << handles.getStringIndex(i) << endl;
382  /// @endcode
383  StringBuffer addStrings(GA_Attribute *attribute,
384  const UT_StringArray &strings) const;
385  StringBuffer addStrings(GA_Attribute *attribute,
386  const UT_Array<const char *> &strings) const;
387  /// @}
388  friend class StringBuffer; // Allow the string buffer to add refs
389 };
390 
391 #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:203
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:243
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.
#define SYS_DEPRECATED_REPLACE(__V__, __R__)
bool setTupleSize(GA_Attribute *attrib, int size) const override=0
Set the tuple size.
GA_Size GA_Offset
Definition: GA_Types.h:653
GLdouble n
Definition: glcorearb.h:2008
UT_IndexedHashMapItemId GA_BlobIndex
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:164
bool operator==(const iterator &src) const
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