📄 documentmodel.cpp
字号:
}
if (pos == NULL)
throw VXMLDocumentModel::InternalError();
posType = pos->GetType();
pos = const_cast<VXMLNodeRef *>(pos->GetParent());
}
VXMLElementType VXMLDocumentRep::GetParentType() const
{
if (pos == NULL)
throw VXMLDocumentModel::InternalError();
return static_cast<const VXMLElementRef *>(pos->GetParent())->name;
}
bool VXMLDocumentRep::GetAttribute(VXMLAttributeType key,
vxistring & attr) const
{
if (pos == NULL || posType != VXMLNode::Type_VXMLElement)
throw VXMLDocumentModel::InternalError();
const VXMLElementRef * temp = static_cast<const VXMLElementRef *>(pos);
return temp->GetAttribute(key, attr);
}
void VXMLDocumentRep::AddAttribute(VXMLAttributeType name,
const vxistring & attr)
{
if (pos == NULL || posType != VXMLNode::Type_VXMLElement)
throw VXMLDocumentModel::InternalError();
VXMLElementRef * temp = static_cast<VXMLElementRef *>(pos);
temp->attributes.push_back(VXMLElementRef::VXMLElementAttribute(name, attr));
}
void VXMLDocumentRep::AddChild(VXMLNodeRef * c)
{
if (root == NULL) {
root = c;
return;
}
if (pos == NULL || posType != VXMLNode::Type_VXMLElement)
throw VXMLDocumentModel::InternalError();
VXMLElementRef * temp = static_cast<VXMLElementRef *>(pos);
temp->children.push_back(c);
}
const VXMLNodeRef * VXMLDocumentRep::GetRoot() const
{
return root;
}
//#############################################################################
VXMLDocument::VXMLDocument(VXMLDocumentRep * x) : internals(x)
{
if (internals == NULL) {
internals = new VXMLDocumentRep();
if (internals == NULL) throw VXMLDocumentModel::OutOfMemory();
}
}
VXMLDocument::~VXMLDocument()
{
VXMLDocumentRep::Release(internals);
}
VXMLDocument::VXMLDocument(const VXMLDocument & x)
{
internals = x.internals;
VXMLDocumentRep::AddRef(internals);
}
VXMLDocument & VXMLDocument::operator=(const VXMLDocument & x)
{
if (this != &x) {
VXMLDocumentRep::Release(internals);
internals = x.internals;
VXMLDocumentRep::AddRef(internals);
}
return *this;
}
VXMLElement VXMLDocument::GetRoot() const
{
if (internals == NULL) return VXMLElement();
const VXMLNodeRef * root = internals->GetRoot();
if (root == NULL) return VXMLElement();
return VXMLElement(root);
}
//#############################################################################
VXMLNode::VXMLNode(const VXMLNode & x)
{
internals = x.internals;
}
VXMLNode & VXMLNode::operator=(const VXMLNode & x)
{
if (this != &x) {
internals = x.internals;
}
return *this;
}
VXMLElement VXMLNode::GetParent() const
{
if (internals != NULL && internals->GetType() == VXMLNode::Type_VXMLNode)
throw VXMLDocumentModel::InternalError();
if (internals == NULL) return VXMLElement();
return VXMLElement(internals->GetParent());
}
VXMLNode::VXMLNodeType VXMLNode::GetType() const
{
if (internals == NULL) return VXMLNode::Type_VXMLNode;
return internals->GetType();
}
//#############################################################################
const vxistring & VXMLContent::GetValue() const
{
if (internals == NULL) throw VXMLDocumentModel::InternalError();
const VXMLContentRef * ref = static_cast<const VXMLContentRef *>(internals);
return ref->data;
}
//#############################################################################
VXMLElement::VXMLElement(const VXMLNodeRef * ref) : VXMLNode(ref)
{
}
VXMLElement::VXMLElement(const VXMLElement & x)
{
internals = x.internals;
}
bool VXMLElement::hasChildren() const
{
if (internals == NULL) throw VXMLDocumentModel::InternalError();
const VXMLElementRef * ref = static_cast<const VXMLElementRef *>(internals);
return !ref->children.empty();
}
VXMLElementType VXMLElement::GetName() const
{
if (internals == NULL) throw VXMLDocumentModel::InternalError();
const VXMLElementRef * ref = static_cast<const VXMLElementRef *>(internals);
return ref->name;
}
bool VXMLElement::GetAttribute(VXMLAttributeType key, vxistring & attr) const
{
if (internals == NULL) throw VXMLDocumentModel::InternalError();
const VXMLElementRef * ref = static_cast<const VXMLElementRef *>(internals);
return ref->GetAttribute(key, attr);
}
//#############################################################################
// This code is NOT sensitive to possible byte order differences.... This is
// a problem if the cache is shared across machines with different endian
// architectures.
// ------*---------*---------*---------*---------*---------*---------*---------
static const unsigned int INT_MULTIPLIER = sizeof(VXIulong) / sizeof(VXIbyte);
static const unsigned int CHAR_MULTIPLIER = sizeof(VXIchar) / sizeof(VXIbyte);
inline void WriteInt(VXIulong i, SerializerOutput & writer)
{
writer.Write(reinterpret_cast<const VXIbyte *>(&i), INT_MULTIPLIER);
}
inline void WriteBlock(const vxistring & block, SerializerOutput & writer)
{
vxistring::size_type size = block.size();
WriteInt(size, writer);
if (size != 0) {
writer.Write(reinterpret_cast<const VXIbyte *>(block.c_str()),
block.size() * CHAR_MULTIPLIER);
}
}
inline VXIulong ReadInt(SerializerInput & reader)
{
VXIbyte temp[INT_MULTIPLIER];
if (reader.Read(temp, INT_MULTIPLIER) != INT_MULTIPLIER)
throw VXMLDocument::SerializationError();
VXIulong * ptr = reinterpret_cast<VXIulong *>(temp);
return *ptr;
}
inline void ReadBlock(vxistring & block, VXIulong size,
SerializerInput & reader)
{
const VXIulong NUM_CHARS = 256;
VXIbyte temp[NUM_CHARS * CHAR_MULTIPLIER];
// Clear string.
if (!block.empty()) block.erase();
if (size == 0) return;
do {
const VXIulong REQUEST = (size < NUM_CHARS ? size : NUM_CHARS);
const VXIulong MAXREAD = REQUEST * CHAR_MULTIPLIER;
if (reader.Read(temp, MAXREAD) != MAXREAD)
throw VXMLDocument::SerializationError();
block += vxistring(reinterpret_cast<const VXIchar *>(temp), REQUEST);
size -= REQUEST;
} while (size > 0);
}
// ------*---------*---------*---------*---------*---------*---------*---------
void WriteElement(const VXMLElementRef * elem, SerializerOutput & writer)
{
WriteInt(VXMLNode::Type_VXMLElement, writer);
// Write out the element name.
WriteInt(elem->name, writer);
// Write out the attributes.
WriteInt(elem->attributes.size(), writer);
for (VXMLElementRef::ATTRIBUTES::const_iterator i = elem->attributes.begin();
i != elem->attributes.end(); ++i)
{
WriteInt((*i).key, writer);
WriteBlock((*i).value, writer);
}
// Write out the children.
WriteInt(elem->children.size(), writer);
for (VXMLElementRef::CHILDREN::const_iterator j = elem->children.begin();
j != elem->children.end(); ++j)
{
switch ((*j)->GetType()) {
case VXMLNode::Type_VXMLElement:
WriteElement(reinterpret_cast<const VXMLElementRef *>(*j), writer);
break;
case VXMLNode::Type_VXMLContent:
WriteInt(VXMLNode::Type_VXMLContent, writer);
WriteBlock(reinterpret_cast<const VXMLContentRef *>(*j)->data, writer);
break;
default:
throw VXMLDocument::SerializationError();
}
}
}
void VXMLDocument::WriteDocument(SerializerOutput & writer) const
{
if (internals == NULL) return;
const VXMLNodeRef * root = internals->GetRoot();
if (root == NULL || root->GetType() != VXMLNode::Type_VXMLElement)
throw VXMLDocument::SerializationError();
WriteElement(static_cast<const VXMLElementRef *>(root), writer);
}
// ------*---------*---------*---------*---------*---------*---------*---------
void LoadElement(VXMLDocumentRep & docRep, SerializerInput & reader)
{
int type = ReadInt(reader);
docRep.StartElement(VXMLElementType(type));
VXIulong numAttributes = ReadInt(reader);
for (unsigned int i = 0; i < numAttributes; ++i) {
VXIulong key = ReadInt(reader);
VXIulong size = ReadInt(reader);
vxistring attr;
ReadBlock(attr, size, reader);
docRep.AddAttribute(VXMLAttributeType(key), attr);
}
VXIulong numChildren = ReadInt(reader);
for (unsigned int j = 0; j < numChildren; ++j) {
VXIulong nodeType = ReadInt(reader);
if (nodeType == VXMLNode::Type_VXMLContent) {
VXIulong size = ReadInt(reader);
vxistring data;
ReadBlock(data, size, reader);
docRep.AddContent(data.c_str(), data.size());
}
else if (nodeType == VXMLNode::Type_VXMLElement)
LoadElement(docRep, reader);
else {
throw VXMLDocument::SerializationError();
}
}
docRep.EndElement();
}
void VXMLDocument::ReadDocument(SerializerInput & reader)
{
VXIulong type = ReadInt(reader);
if (type != VXMLNode::Type_VXMLElement)
throw VXMLDocument::SerializationError();
VXMLDocumentRep * docRep = new VXMLDocumentRep();
LoadElement(*docRep, reader);
if (internals != NULL)
VXMLDocumentRep::Release(internals);
internals = docRep;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -