You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
376 lines
11 KiB
C++
376 lines
11 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkXMLDataElement.h
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
/**
|
|
* @class vtkXMLDataElement
|
|
* @brief Represents an XML element and those nested inside.
|
|
*
|
|
* vtkXMLDataElement is used by vtkXMLDataParser to represent an XML
|
|
* element. It provides methods to access the element's attributes
|
|
* and nested elements in a convenient manner. This allows easy
|
|
* traversal of an input XML file by vtkXMLReader and its subclasses.
|
|
*
|
|
* @sa
|
|
* vtkXMLDataParser
|
|
*/
|
|
|
|
#ifndef vtkXMLDataElement_h
|
|
#define vtkXMLDataElement_h
|
|
|
|
#include "vtkCommonDataModelModule.h" // For export macro
|
|
#include "vtkObject.h"
|
|
|
|
class vtkXMLDataParser;
|
|
|
|
class VTKCOMMONDATAMODEL_EXPORT vtkXMLDataElement : public vtkObject
|
|
{
|
|
public:
|
|
vtkTypeMacro(vtkXMLDataElement, vtkObject);
|
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
|
static vtkXMLDataElement* New();
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the name of the element. This is its XML tag.
|
|
*/
|
|
vtkGetStringMacro(Name);
|
|
virtual void SetName(const char* _arg);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the value of the id attribute of the element, if any.
|
|
*/
|
|
vtkGetStringMacro(Id);
|
|
vtkSetStringMacro(Id);
|
|
//@}
|
|
|
|
/**
|
|
* Get the attribute with the given name. If it doesn't exist,
|
|
* returns 0.
|
|
*/
|
|
const char* GetAttribute(const char* name);
|
|
|
|
/**
|
|
* Set the attribute with the given name and value. If it doesn't exist,
|
|
* adds it.
|
|
*/
|
|
void SetAttribute(const char* name, const char* value);
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the character data between XML start/end tags.
|
|
*/
|
|
void SetCharacterData(const char* c, int length);
|
|
void AddCharacterData(const char* c, size_t length);
|
|
vtkGetStringMacro(CharacterData);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Get the attribute with the given name and converted to a scalar
|
|
* value. Returns whether value was extracted.
|
|
*/
|
|
int GetScalarAttribute(const char* name, int& value);
|
|
int GetScalarAttribute(const char* name, float& value);
|
|
int GetScalarAttribute(const char* name, double& value);
|
|
int GetScalarAttribute(const char* name, long& value);
|
|
int GetScalarAttribute(const char* name, unsigned long& value);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set the attribute with the given name.
|
|
* We can not use the same GetScalarAttribute() construct since
|
|
* the compiler will not be able to resolve between
|
|
* SetAttribute(..., int) and SetAttribute(..., unsigned long).
|
|
*/
|
|
void SetIntAttribute(const char* name, int value);
|
|
void SetFloatAttribute(const char* name, float value);
|
|
void SetDoubleAttribute(const char* name, double value);
|
|
void SetUnsignedLongAttribute(const char* name, unsigned long value);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Get the attribute with the given name and converted to a scalar
|
|
* value. Returns length of vector read.
|
|
*/
|
|
int GetVectorAttribute(const char* name, int length, int* value);
|
|
int GetVectorAttribute(const char* name, int length, float* value);
|
|
int GetVectorAttribute(const char* name, int length, double* value);
|
|
int GetVectorAttribute(const char* name, int length, long* value);
|
|
int GetVectorAttribute(const char* name, int length, unsigned long* value);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set the attribute with the given name.
|
|
*/
|
|
void SetVectorAttribute(const char* name, int length, const int* value);
|
|
void SetVectorAttribute(const char* name, int length, const float* value);
|
|
void SetVectorAttribute(const char* name, int length, const double* value);
|
|
void SetVectorAttribute(const char* name, int length, const unsigned long* value);
|
|
//@}
|
|
|
|
int GetScalarAttribute(const char* name, long long& value);
|
|
int GetVectorAttribute(const char* name, int length, long long* value);
|
|
void SetVectorAttribute(const char* name, int length, long long const* value);
|
|
int GetScalarAttribute(const char* name, unsigned long long& value);
|
|
int GetVectorAttribute(const char* name, int length, unsigned long long* value);
|
|
void SetVectorAttribute(const char* name, int length, unsigned long long const* value);
|
|
|
|
/**
|
|
* Get the attribute with the given name and converted to a word type
|
|
* such as VTK_FLOAT or VTK_UNSIGNED_LONG.
|
|
*/
|
|
int GetWordTypeAttribute(const char* name, int& value);
|
|
|
|
//@{
|
|
/**
|
|
* Get the number of attributes.
|
|
*/
|
|
vtkGetMacro(NumberOfAttributes, int);
|
|
//@}
|
|
|
|
/**
|
|
* Get the n-th attribute name.
|
|
* Returns 0 if there is no such attribute.
|
|
*/
|
|
const char* GetAttributeName(int idx);
|
|
|
|
/**
|
|
* Get the n-th attribute value.
|
|
* Returns 0 if there is no such attribute.
|
|
*/
|
|
const char* GetAttributeValue(int idx);
|
|
|
|
//@{
|
|
/**
|
|
* Remove one or all attributes.
|
|
*/
|
|
virtual void RemoveAttribute(const char* name);
|
|
virtual void RemoveAllAttributes();
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the parent of this element.
|
|
*/
|
|
vtkXMLDataElement* GetParent();
|
|
void SetParent(vtkXMLDataElement* parent);
|
|
//@}
|
|
|
|
/**
|
|
* Get root of the XML tree this element is part of.
|
|
*/
|
|
virtual vtkXMLDataElement* GetRoot();
|
|
|
|
/**
|
|
* Get the number of elements nested in this one.
|
|
*/
|
|
int GetNumberOfNestedElements();
|
|
|
|
/**
|
|
* Get the element nested in this one at the given index.
|
|
*/
|
|
vtkXMLDataElement* GetNestedElement(int index);
|
|
|
|
/**
|
|
* Add nested element
|
|
*/
|
|
void AddNestedElement(vtkXMLDataElement* element);
|
|
|
|
/**
|
|
* Remove nested element.
|
|
*/
|
|
virtual void RemoveNestedElement(vtkXMLDataElement*);
|
|
|
|
/**
|
|
* Remove all nested elements.
|
|
*/
|
|
virtual void RemoveAllNestedElements();
|
|
|
|
//@{
|
|
/**
|
|
* Find the first nested element with the given id, given name, or given
|
|
* name and id.
|
|
* WARNING: the search is only performed on the children, not
|
|
* the grand-children.
|
|
*/
|
|
vtkXMLDataElement* FindNestedElement(const char* id);
|
|
vtkXMLDataElement* FindNestedElementWithName(const char* name);
|
|
vtkXMLDataElement* FindNestedElementWithNameAndId(const char* name, const char* id);
|
|
vtkXMLDataElement* FindNestedElementWithNameAndAttribute(
|
|
const char* name, const char* att_name, const char* att_value);
|
|
//@}
|
|
|
|
/**
|
|
* Find the first nested element with given name.
|
|
* WARNING: the search is performed on the whole XML tree.
|
|
*/
|
|
vtkXMLDataElement* LookupElementWithName(const char* name);
|
|
|
|
/**
|
|
* Lookup the element with the given id, starting at this scope.
|
|
*/
|
|
vtkXMLDataElement* LookupElement(const char* id);
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the offset from the beginning of the XML document to this element.
|
|
*/
|
|
vtkGetMacro(XMLByteIndex, vtkTypeInt64);
|
|
vtkSetMacro(XMLByteIndex, vtkTypeInt64);
|
|
//@}
|
|
|
|
/**
|
|
* Check if the instance has the same name, attributes, character data
|
|
* and nested elements contents than the given element (this method is
|
|
* applied recursively on the nested elements, and they must be stored in
|
|
* the same order).
|
|
* Warning: Id, Parent, XMLByteIndex are ignored.
|
|
*/
|
|
virtual int IsEqualTo(vtkXMLDataElement* elem);
|
|
|
|
/**
|
|
* Copy this element from another of the same type (elem), recursively.
|
|
* Old attributes and nested elements are removed, new ones are created
|
|
* given the contents of 'elem'.
|
|
* Warning: Parent is ignored.
|
|
*/
|
|
virtual void DeepCopy(vtkXMLDataElement* elem);
|
|
|
|
//@{
|
|
/**
|
|
* Get/Set the internal character encoding of the attributes.
|
|
* Default type is VTK_ENCODING_UTF_8.
|
|
* Note that a vtkXMLDataParser has its own AttributesEncoding ivar. If
|
|
* this ivar is set to something other than VTK_ENCODING_NONE, it will be
|
|
* used to set the attribute encoding of each vtkXMLDataElement
|
|
* created by this vtkXMLDataParser.
|
|
*/
|
|
vtkSetClampMacro(AttributeEncoding, int, VTK_ENCODING_NONE, VTK_ENCODING_UNKNOWN);
|
|
vtkGetMacro(AttributeEncoding, int);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Prints element tree as XML.
|
|
*/
|
|
void PrintXML(ostream& os, vtkIndent indent);
|
|
void PrintXML(const char* fname);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Get/Set the width (in number of fields) that character
|
|
* data (that between open and closing tags ie. <X> ... </X>)
|
|
* is printed. If the width is less than one the tag's character
|
|
* data is printed all on one line. If it is greater than one
|
|
* the character data is streamed insterting line feeds every
|
|
* width number of fields. See PrintXML.
|
|
*/
|
|
vtkGetMacro(CharacterDataWidth, int);
|
|
vtkSetMacro(CharacterDataWidth, int);
|
|
//@}
|
|
|
|
protected:
|
|
vtkXMLDataElement();
|
|
~vtkXMLDataElement() override;
|
|
|
|
// The name of the element from the XML file.
|
|
char* Name;
|
|
// The value of the "id" attribute, if any was given.
|
|
char* Id;
|
|
|
|
int CharacterDataWidth;
|
|
|
|
// Data inside of the tag's open and close. ie <X> character data </X>
|
|
char* CharacterData; // Null terminated buffer.
|
|
size_t CharacterDataBlockSize; // Allocation size if buffer needs expand
|
|
size_t CharacterDataBufferSize; // Allocated size.
|
|
size_t EndOfCharacterData; // Number of bytes used.
|
|
|
|
// Tags that have specialized character data handlers
|
|
// can set this flag to improve performance. The default is unset.
|
|
int IgnoreCharacterData;
|
|
|
|
// Get/Set the stream position of the elements inline data.
|
|
vtkGetMacro(InlineDataPosition, vtkTypeInt64);
|
|
vtkSetMacro(InlineDataPosition, vtkTypeInt64);
|
|
// The offset into the XML stream where the inline data begins.
|
|
vtkTypeInt64 InlineDataPosition;
|
|
// The offset into the XML stream where the element begins.
|
|
vtkTypeInt64 XMLByteIndex;
|
|
|
|
// The raw property name/value pairs read from the XML attributes.
|
|
char** AttributeNames;
|
|
char** AttributeValues;
|
|
int NumberOfAttributes;
|
|
int AttributesSize;
|
|
int AttributeEncoding;
|
|
|
|
// The set of nested elements.
|
|
int NumberOfNestedElements;
|
|
int NestedElementsSize;
|
|
vtkXMLDataElement** NestedElements;
|
|
// The parent of this element.
|
|
vtkXMLDataElement* Parent;
|
|
|
|
// Internal utility methods.
|
|
vtkXMLDataElement* LookupElementInScope(const char* id);
|
|
vtkXMLDataElement* LookupElementUpScope(const char* id);
|
|
static int IsSpace(char c);
|
|
void PrintCharacterData(ostream& os, vtkIndent indent);
|
|
static void PrintWithEscapedData(ostream& os, const char* data);
|
|
|
|
friend class vtkXMLDataParser;
|
|
friend class vtkXMLMaterialParser;
|
|
|
|
private:
|
|
vtkXMLDataElement(const vtkXMLDataElement&) = delete;
|
|
void operator=(const vtkXMLDataElement&) = delete;
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline void vtkXMLDataElement::AddCharacterData(const char* data, size_t length)
|
|
{
|
|
if (this->IgnoreCharacterData)
|
|
{
|
|
return;
|
|
}
|
|
// This is the index where we start to put the new data at.
|
|
size_t eod = this->EndOfCharacterData - 1;
|
|
// Check if the new data will write off the end. If it does
|
|
// resize the character data buffer.
|
|
this->EndOfCharacterData += length;
|
|
if (this->EndOfCharacterData >= this->CharacterDataBufferSize)
|
|
{
|
|
while (this->EndOfCharacterData >= this->CharacterDataBufferSize)
|
|
{
|
|
this->CharacterDataBufferSize += this->CharacterDataBlockSize;
|
|
}
|
|
this->CharacterData =
|
|
static_cast<char*>(realloc(this->CharacterData, this->CharacterDataBufferSize));
|
|
}
|
|
// put the new data at the end of the buffer, and null terminate.
|
|
char* pCD = this->CharacterData + eod;
|
|
memmove(pCD, data, length);
|
|
pCD[length] = '\0';
|
|
return;
|
|
}
|
|
|
|
#endif
|