📄 pxml.cxx
字号:
BOOL PXML::Save(int _options){ if (_options >= 0) options = _options; if (!loadFromFile || !IsDirty()) return FALSE; return SaveFile(loadFilename);}BOOL PXML::SaveFile(const PFilePath & fn, int _options){ PWaitAndSignal m(rootMutex); PFile file; if (!file.Open(fn, PFile::WriteOnly)) return FALSE; PString data; if (!Save(data, _options)) return FALSE; return file.Write((const char *)data, data.GetLength());}BOOL PXML::Save(PString & data, int _options){ PWaitAndSignal m(rootMutex); if (_options >= 0) options = _options; PStringStream strm; strm << *this; data = strm; return TRUE;}void PXML::RemoveAll(){ PWaitAndSignal m(rootMutex); if (rootElement != NULL) { delete rootElement; rootElement = NULL; }}PXMLElement * PXML::GetElement(const PCaselessString & name, PINDEX idx) const{ if (rootElement == NULL) return NULL; return rootElement->GetElement(name, idx);}PXMLElement * PXML::GetElement(PINDEX idx) const{ if (rootElement == NULL) return NULL; if (idx >= rootElement->GetSize()) return NULL; return (PXMLElement *)(rootElement->GetElement(idx));}BOOL PXML::RemoveElement(PINDEX idx){ if (rootElement == NULL) return FALSE; if (idx >= rootElement->GetSize()) return FALSE; rootElement->RemoveElement(idx); return TRUE;}PINDEX PXML::GetNumElements() const{ if (rootElement == NULL) return 0; else return rootElement->GetSize();}BOOL PXML::IsNoIndentElement(const PString & elementName) const{ return noIndentElements.GetValuesIndex(elementName) != P_MAX_INDEX;}void PXML::PrintOn(ostream & strm) const{ BOOL newLine = (options & (PXMLParser::Indent|PXMLParser::NewLineAfterElement)) != 0;//<?xml version="1.0" encoding="UTF-8" standalone="yes"?> PString ver = version; PString enc = encoding; int salone = standAlone; if (ver.IsEmpty()) ver= "1.0"; if (enc.IsEmpty()) enc = "UTF-8"; if (salone == -2) salone = -1; strm << "<?xml version=\"" << ver << "\" encoding=\"" << enc << "\""; switch (salone) { case 0: strm << " standalone=\"no\""; break; case 1: strm << " standalone=\"yes\""; break; default: break; } strm << "?>"; if (newLine) strm << endl; if (rootElement != NULL) { if (!docType.IsEmpty()) strm << "<!DOCTYPE " << docType << '>'; if (newLine) strm << endl; rootElement->Output(strm, *this, 2); }}PString PXML::CreateStartTag(const PString & text){ return '<' + text + '>';}PString PXML::CreateEndTag(const PString & text){ return "</" + text + '>';}PString PXML::CreateTagNoData(const PString & text){ return '<' + text + "/>";}PString PXML::CreateTag(const PString & text, const PString & data){ return CreateStartTag(text) + data + CreateEndTag(text);}/////////////////////////////////////////////////////////void PXMLObject::SetDirty(){ dirty = TRUE; if (parent != NULL) parent->SetDirty();}PXMLObject * PXMLObject::GetNextObject(){ if (parent == NULL) return NULL; // find our index in our parent's list PINDEX idx = parent->FindObject(this); if (idx == P_MAX_INDEX) return NULL; // get the next object ++idx; if (idx >= parent->GetSize()) return NULL; return (*parent).GetElement(idx);}///////////////////////////////////////////////////////PXMLData::PXMLData(PXMLElement * _parent, const PString & _value) : PXMLObject(_parent){ value = _value;}PXMLData::PXMLData(PXMLElement * _parent, const char * data, int len) : PXMLObject(_parent){ value = PString(data, len);}void PXMLData::Output(ostream & strm, const PXMLBase & xml, int indent) const{ int options = xml.GetOptions(); if (xml.IsNoIndentElement(parent->GetName())) options &= ~PXMLParser::Indent; if (options & PXMLParser::Indent) strm << setw(indent-1) << " "; strm << value; if ((options & (PXMLParser::Indent|PXMLParser::NewLineAfterElement)) != 0) strm << endl;}void PXMLData::SetString(const PString & str, BOOL setDirty){ value = str; if (setDirty) SetDirty();}PXMLObject * PXMLData::Clone(PXMLElement * _parent) const{ return new PXMLData(_parent, value);}///////////////////////////////////////////////////////PXMLElement::PXMLElement(PXMLElement * _parent, const char * _name) : PXMLObject(_parent){ dirty = FALSE; if (_name != NULL) name = _name;}PXMLElement::PXMLElement(PXMLElement * _parent, const PString & _name, const PString & data) : PXMLObject(_parent), name(_name){ dirty = FALSE; AddSubObject(new PXMLData(this, data));}PINDEX PXMLElement::FindObject(PXMLObject * ptr) const{ return subObjects.GetObjectsIndex(ptr);}PXMLElement * PXMLElement::GetElement(const PCaselessString & name, PINDEX start) const{ PINDEX idx; PINDEX size = subObjects.GetSize(); PINDEX count = 0; for (idx = 0; idx < size; idx++) { if (subObjects[idx].IsElement()) { PXMLElement & subElement = ((PXMLElement &)subObjects[idx]); if (subElement.GetName() *= name) { if (count++ == start) return (PXMLElement *)&subObjects[idx]; } } } return NULL;}PXMLObject * PXMLElement::GetElement(PINDEX idx) const{ if (idx >= subObjects.GetSize()) return NULL; return &subObjects[idx];}BOOL PXMLElement::RemoveElement(PINDEX idx){ if (idx >= subObjects.GetSize()) return FALSE; subObjects.RemoveAt(idx); return TRUE;}PString PXMLElement::GetAttribute(const PCaselessString & key) const{ return attributes(key);}PString PXMLElement::GetKeyAttribute(PINDEX idx) const{ if (idx < attributes.GetSize()) return attributes.GetKeyAt(idx); else return PString();}PString PXMLElement::GetDataAttribute(PINDEX idx) const{ if (idx < attributes.GetSize()) return attributes.GetDataAt(idx); else return PString();}void PXMLElement::SetAttribute(const PCaselessString & key, const PString & value, BOOL setDirty){ attributes.SetAt(key, value); if (setDirty) SetDirty();}BOOL PXMLElement::HasAttribute(const PCaselessString & key){ return attributes.Contains(key);}void PXMLElement::PrintOn(ostream & strm) const{ PXMLBase xml(-1); Output(strm, xml, 0);}void PXMLElement::Output(ostream & strm, const PXMLBase & xml, int indent) const{ int options = xml.GetOptions(); BOOL newLine = (options & (PXMLParser::Indent|PXMLParser::NewLineAfterElement)) != 0; if ((options & PXMLParser::Indent) != 0) strm << setw(indent-1) << " "; strm << '<' << name; PINDEX i; if (attributes.GetSize() > 0) { for (i = 0; i < attributes.GetSize(); i++) { PCaselessString key = attributes.GetKeyAt(i); strm << ' ' << key << "=\"" << attributes[key] << '"'; } } // this ensures empty elements use the shortened form if (subObjects.GetSize() == 0) { strm << "/>"; if (newLine) strm << endl; } else { BOOL indenting = (options & PXMLParser::Indent) != 0 && !xml.IsNoIndentElement(name); strm << '>'; if (indenting) strm << endl; for (i = 0; i < subObjects.GetSize(); i++) subObjects[i].Output(strm, xml, indent + 2); if (indenting) strm << setw(indent-1) << " "; strm << "</" << name << '>'; if (newLine) strm << endl; }}PXMLObject * PXMLElement::AddSubObject(PXMLObject * elem, BOOL setDirty){ subObjects.SetAt(subObjects.GetSize(), elem); if (setDirty) SetDirty(); return elem;}PXMLElement * PXMLElement::AddChild(PXMLElement * elem, BOOL dirty){ return (PXMLElement *)AddSubObject(elem, dirty);}PXMLData * PXMLElement::AddChild(PXMLData * elem, BOOL dirty){ return (PXMLData *)AddSubObject(elem, dirty);}PXMLObject * PXMLElement::Clone(PXMLElement * _parent) const{ PXMLElement * elem = new PXMLElement(_parent); elem->SetName(name); elem->attributes = attributes; elem->dirty = dirty; PINDEX idx; for (idx = 0; idx < subObjects.GetSize(); idx++) elem->AddSubObject(subObjects[idx].Clone(elem), FALSE); return elem;}PString PXMLElement::GetData() const{ PString str; PINDEX idx; for (idx = 0; idx < subObjects.GetSize(); idx++) { if (!subObjects[idx].IsElement()) { PXMLData & dataElement = ((PXMLData &)subObjects[idx]); PStringArray lines = dataElement.GetString().Lines(); PINDEX j; for (j = 0; j < lines.GetSize(); j++) str = str & lines[j]; } } return str;}///////////////////////////////////////////////////////PXMLSettings::PXMLSettings(int options) :PXML(options){}PXMLSettings::PXMLSettings(const PString & data, int options) : PXML(data,options) {}PXMLSettings::PXMLSettings(const PConfig & data, int options) : PXML(options) { PStringList sects = data.GetSections(); for (PINDEX i = 0;i < (PINDEX)sects.GetSize();++i) { PStringToString keyvals = data.GetAllKeyValues(sects[i]); for (PINDEX j = 0; j < (PINDEX)keyvals.GetSize(); ++j) { SetAttribute(sects[i],keyvals.GetKeyAt(j),keyvals.GetDataAt(j)); } }}BOOL PXMLSettings::Load(const PString & data){ return PXML::Load(data);}BOOL PXMLSettings::LoadFile(const PFilePath & fn){ return PXML::LoadFile(fn);}BOOL PXMLSettings::Save(){ return PXML::Save();}BOOL PXMLSettings::Save(PString & data){ return PXML::Save(data);}BOOL PXMLSettings::SaveFile(const PFilePath & fn){ return PXML::SaveFile(fn);}PString PXMLSettings::GetAttribute(const PCaselessString & section, const PString & key) const{ if (rootElement == NULL) return PString(); PXMLElement * element = rootElement->GetElement(section); if (element == NULL) return PString(); return element->GetAttribute(key);}void PXMLSettings::SetAttribute(const PCaselessString & section, const PString & key, const PString & value){ if (rootElement == NULL) rootElement = new PXMLElement(NULL, "settings"); PXMLElement * element = rootElement->GetElement(section); if (element == NULL) { element = new PXMLElement(rootElement, section); rootElement->AddSubObject(element); } element->SetAttribute(key, value);}BOOL PXMLSettings::HasAttribute(const PCaselessString & section, const PString & key) const{ if (rootElement == NULL) return FALSE; PXMLElement * element = rootElement->GetElement(section); if (element == NULL) return FALSE; return element->HasAttribute(key);}void PXMLSettings::ToConfig(PConfig & cfg) const{ for (PINDEX i = 0;i < (PINDEX)GetNumElements();++i) { PXMLElement * el = GetElement(i); PString sectionName = el->GetName(); for (PINDEX j = 0; j < (PINDEX)el->GetNumAttributes(); ++j) { PString key = el->GetKeyAttribute(j); PString dat = el->GetDataAttribute(j); if (!key && !dat) cfg.SetString(sectionName, key, dat); } } }///////////////////////////////////////////////////////PXMLStreamParser::PXMLStreamParser() : rootOpen(TRUE){}void PXMLStreamParser::EndElement(const char * name){ PXMLElement * element = currentElement; PXMLParser::EndElement(name); if (currentElement == rootElement) { if (element == rootElement) { // stream closed rootOpen = FALSE; } else { PINDEX i = rootElement->FindObject(element); if (i != P_MAX_INDEX) { PXML tmp; element = (PXMLElement *)element->Clone(0); rootElement->RemoveElement(i); PXML * msg = new PXML; msg->SetRootElement(element); messages.Enqueue(msg); } } }}PXML * PXMLStreamParser::Read(PChannel * channel){ char buf[256]; channel->SetReadTimeout(1000); while (rootOpen) { if (messages.GetSize() != 0) return messages.Dequeue(); if (!channel->Read(buf, sizeof(buf) - 1) || !channel->IsOpen()) return 0; buf[channel->GetLastReadCount()] = 0; if (!Parse(buf, channel->GetLastReadCount(), FALSE)) return 0; } channel->Close(); return 0;}///////////////////////////////////////////////////////#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -