Mercurial > vba-clojure
diff src/win32/7zip/7z/CPP/Common/MyXml.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/Common/MyXml.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,209 @@ 1.4 +// MyXml.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include "MyXml.h" 1.9 + 1.10 +static bool IsValidChar(char c) 1.11 +{ 1.12 + return 1.13 + c >= 'a' && c <= 'z' || 1.14 + c >= 'A' && c <= 'Z' || 1.15 + c >= '0' && c <= '9' || 1.16 + c == '-'; 1.17 +} 1.18 + 1.19 +static bool IsSpaceChar(char c) 1.20 +{ 1.21 + return (c == ' ' || c == '\t' || c == 0x0D || c == 0x0A); 1.22 +} 1.23 + 1.24 +#define SKEEP_SPACES(s, pos) while (IsSpaceChar(s[pos])) pos++; 1.25 + 1.26 +static bool ReadProperty(const AString &s, int &pos, CXmlProp &prop) 1.27 +{ 1.28 + prop.Name.Empty(); 1.29 + prop.Value.Empty(); 1.30 + for (; pos < s.Length(); pos++) 1.31 + { 1.32 + char c = s[pos]; 1.33 + if (!IsValidChar(c)) 1.34 + break; 1.35 + prop.Name += c; 1.36 + } 1.37 + 1.38 + if (prop.Name.IsEmpty()) 1.39 + return false; 1.40 + 1.41 + SKEEP_SPACES(s, pos); 1.42 + if (s[pos++] != '=') 1.43 + return false; 1.44 + 1.45 + SKEEP_SPACES(s, pos); 1.46 + if (s[pos++] != '\"') 1.47 + return false; 1.48 + 1.49 + while (pos < s.Length()) 1.50 + { 1.51 + char c = s[pos++]; 1.52 + if (c == '\"') 1.53 + return true; 1.54 + prop.Value += c; 1.55 + } 1.56 + return false; 1.57 +} 1.58 + 1.59 +int CXmlItem::FindProperty(const AString &propName) const 1.60 +{ 1.61 + for (int i = 0; i < Props.Size(); i++) 1.62 + if (Props[i].Name == propName) 1.63 + return i; 1.64 + return -1; 1.65 +} 1.66 + 1.67 +AString CXmlItem::GetPropertyValue(const AString &propName) const 1.68 +{ 1.69 + int index = FindProperty(propName); 1.70 + if (index >= 0) 1.71 + return Props[index].Value; 1.72 + return AString(); 1.73 +} 1.74 + 1.75 +bool CXmlItem::IsTagged(const AString &tag) const 1.76 +{ 1.77 + return (IsTag && Name == tag); 1.78 +} 1.79 + 1.80 +int CXmlItem::FindSubTag(const AString &tag) const 1.81 +{ 1.82 + for (int i = 0; i < SubItems.Size(); i++) 1.83 + if (SubItems[i].IsTagged(tag)) 1.84 + return i; 1.85 + return -1; 1.86 +} 1.87 + 1.88 +AString CXmlItem::GetSubString() const 1.89 +{ 1.90 + if (SubItems.Size() == 1) 1.91 + { 1.92 + const CXmlItem &item = SubItems[0]; 1.93 + if (!item.IsTag) 1.94 + return item.Name; 1.95 + } 1.96 + return AString(); 1.97 +} 1.98 + 1.99 +AString CXmlItem::GetSubStringForTag(const AString &tag) const 1.100 +{ 1.101 + int index = FindSubTag(tag); 1.102 + if (index >= 0) 1.103 + return SubItems[index].GetSubString(); 1.104 + return AString(); 1.105 +} 1.106 + 1.107 +bool CXmlItem::ParseItems(const AString &s, int &pos, int numAllowedLevels) 1.108 +{ 1.109 + if (numAllowedLevels == 0) 1.110 + return false; 1.111 + SubItems.Clear(); 1.112 + AString finishString = "</"; 1.113 + for (;;) 1.114 + { 1.115 + SKEEP_SPACES(s, pos); 1.116 + 1.117 + if (s.Mid(pos, finishString.Length()) == finishString) 1.118 + return true; 1.119 + 1.120 + CXmlItem item; 1.121 + if (!item.ParseItem(s, pos, numAllowedLevels - 1)) 1.122 + return false; 1.123 + SubItems.Add(item); 1.124 + } 1.125 +} 1.126 + 1.127 +bool CXmlItem::ParseItem(const AString &s, int &pos, int numAllowedLevels) 1.128 +{ 1.129 + SKEEP_SPACES(s, pos); 1.130 + 1.131 + int pos2 = s.Find('<', pos); 1.132 + if (pos2 < 0) 1.133 + return false; 1.134 + if (pos2 != pos) 1.135 + { 1.136 + IsTag = false; 1.137 + Name += s.Mid(pos, pos2 - pos); 1.138 + pos = pos2; 1.139 + return true; 1.140 + } 1.141 + IsTag = true; 1.142 + 1.143 + pos++; 1.144 + SKEEP_SPACES(s, pos); 1.145 + 1.146 + for (; pos < s.Length(); pos++) 1.147 + { 1.148 + char c = s[pos]; 1.149 + if (!IsValidChar(c)) 1.150 + break; 1.151 + Name += c; 1.152 + } 1.153 + if (Name.IsEmpty() || pos == s.Length()) 1.154 + return false; 1.155 + 1.156 + int posTemp = pos; 1.157 + for (;;) 1.158 + { 1.159 + SKEEP_SPACES(s, pos); 1.160 + if (s[pos] == '/') 1.161 + { 1.162 + pos++; 1.163 + // SKEEP_SPACES(s, pos); 1.164 + return (s[pos++] == '>'); 1.165 + } 1.166 + if (s[pos] == '>') 1.167 + { 1.168 + if (!ParseItems(s, ++pos, numAllowedLevels)) 1.169 + return false; 1.170 + AString finishString = AString("</") + Name + AString(">"); 1.171 + if (s.Mid(pos, finishString.Length()) != finishString) 1.172 + return false; 1.173 + pos += finishString.Length(); 1.174 + return true; 1.175 + } 1.176 + if (posTemp == pos) 1.177 + return false; 1.178 + 1.179 + CXmlProp prop; 1.180 + if (!ReadProperty(s, pos, prop)) 1.181 + return false; 1.182 + Props.Add(prop); 1.183 + posTemp = pos; 1.184 + } 1.185 +} 1.186 + 1.187 +bool SkeepHeader(const AString &s, int &pos, const AString &startString, const AString &endString) 1.188 +{ 1.189 + SKEEP_SPACES(s, pos); 1.190 + if (s.Mid(pos, startString.Length()) == startString) 1.191 + { 1.192 + pos = s.Find(endString, pos); 1.193 + if (pos < 0) 1.194 + return false; 1.195 + pos += endString.Length(); 1.196 + SKEEP_SPACES(s, pos); 1.197 + } 1.198 + return true; 1.199 +} 1.200 + 1.201 +bool CXml::Parse(const AString &s) 1.202 +{ 1.203 + int pos = 0; 1.204 + if (!SkeepHeader(s, pos, "<?xml", "?>")) 1.205 + return false; 1.206 + if (!SkeepHeader(s, pos, "<!DOCTYPE", ">")) 1.207 + return false; 1.208 + if (!Root.ParseItem(s, pos, 1000)) 1.209 + return false; 1.210 + SKEEP_SPACES(s, pos); 1.211 + return (pos == s.Length() && Root.IsTag); 1.212 +}