1 /*!********************************************************************
2 Audacity: A Digital Audio Editor
3
4 @file UpdateDataParser.cpp
5 @brief Declare a class that parses update server data format.
6
7 Anton Gerasimov
8 **********************************************************************/
9
10 #include "UpdateDataParser.h"
11
12 #include "XMLFileReader.h"
13 #include "MemoryX.h"
14 #include <wx/platinfo.h>
15
UpdateDataParser()16 UpdateDataParser::UpdateDataParser()
17 {}
18
~UpdateDataParser()19 UpdateDataParser::~UpdateDataParser()
20 {}
21
Parse(const VersionPatch::UpdateDataFormat & updateData,VersionPatch * versionPatch)22 bool UpdateDataParser::Parse(const VersionPatch::UpdateDataFormat& updateData, VersionPatch* versionPatch)
23 {
24 XMLFileReader xmlReader;
25
26 ValueRestorer<VersionPatch*> setter{ mVersionPatch, versionPatch };
27
28 return xmlReader.ParseString(this, updateData);
29 }
30
SplitChangelogSentences(const wxString & changelogContent)31 wxArrayString UpdateDataParser::SplitChangelogSentences(const wxString& changelogContent)
32 {
33 wxArrayString changelogSentenceList;
34
35 size_t pos = 0;
36 std::string s(changelogContent.ToStdString());
37 std::string token;
38 const std::string delimiter(". ");
39
40 while ((pos = s.find(delimiter)) != std::string::npos)
41 {
42 token = s.substr(0, pos + 1);
43 changelogSentenceList.Add(wxString(token).Trim());
44
45 s.erase(0, pos + delimiter.length());
46 }
47 changelogSentenceList.Add(wxString(s).Trim());
48
49 return changelogSentenceList;
50 }
51
HandleXMLTag(const std::string_view & tag,const AttributesList & attrs)52 bool UpdateDataParser::HandleXMLTag(const std::string_view& tag, const AttributesList& attrs)
53 {
54 if (tag == mXmlTagNames[XmlParsedTags::kDescriptionTag])
55 {
56 mXmlParsingState = XmlParsedTags::kDescriptionTag;
57 return true;
58 }
59
60 const wxPlatformInfo& info = wxPlatformInfo::Get();
61
62 constexpr bool is32Bit = sizeof(void*) == 4;
63 constexpr bool is64Bit = sizeof(void*) == 8;
64
65 if (is32Bit)
66 {
67 if (tag == mXmlTagNames[XmlParsedTags::kWin32Tag])
68 {
69 if (info.GetOperatingSystemId() & wxOS_WINDOWS)
70 mXmlParsingState = XmlParsedTags::kOsTag;
71 return true;
72 }
73 }
74
75 if (is64Bit)
76 {
77 if (tag == mXmlTagNames[XmlParsedTags::kWin64Tag])
78 {
79 if (info.GetOperatingSystemId() & wxOS_WINDOWS)
80 mXmlParsingState = XmlParsedTags::kOsTag;
81 return true;
82 }
83 }
84
85 if (tag == mXmlTagNames[XmlParsedTags::kMacosTag])
86 {
87 if (info.GetOperatingSystemId() & wxOS_MAC)
88 mXmlParsingState = XmlParsedTags::kOsTag;
89 return true;
90 }
91
92 if (tag == mXmlTagNames[XmlParsedTags::kLinuxTag])
93 {
94 if (info.GetOperatingSystemId() & wxOS_UNIX_LINUX)
95 mXmlParsingState = XmlParsedTags::kOsTag;
96 return true;
97 }
98
99 if (tag == mXmlTagNames[XmlParsedTags::kVersionTag])
100 {
101 if (mXmlParsingState == XmlParsedTags::kOsTag)
102 mXmlParsingState = XmlParsedTags::kVersionTag;
103 return true;
104 }
105
106 if (tag == mXmlTagNames[XmlParsedTags::kLinkTag])
107 {
108 if (mXmlParsingState == XmlParsedTags::kOsTag)
109 mXmlParsingState = XmlParsedTags::kLinkTag;
110 return true;
111 }
112
113 for (auto& xmlTag : mXmlTagNames)
114 {
115 if (tag == xmlTag.second)
116 return true;
117 }
118
119 return false;
120 }
121
HandleXMLEndTag(const std::string_view & tag)122 void UpdateDataParser::HandleXMLEndTag(const std::string_view& tag)
123 {
124 if (mXmlParsingState == XmlParsedTags::kDescriptionTag ||
125 mXmlParsingState == XmlParsedTags::kLinkTag)
126 mXmlParsingState = XmlParsedTags::kNotUsedTag;
127
128 // If it is our working OS, using "kOsTag" for keeping ready for parse state for both tags:
129 // <Version> and <Link>, that ordered one after another.
130 if (mXmlParsingState == XmlParsedTags::kVersionTag)
131 mXmlParsingState = XmlParsedTags::kOsTag;
132 }
133
HandleXMLContent(const std::string_view & content)134 void UpdateDataParser::HandleXMLContent(const std::string_view& content)
135 {
136 if (mVersionPatch == nullptr)
137 return;
138
139 wxString trimmedContent = std::string(content);
140
141 switch (mXmlParsingState)
142 {
143 case XmlParsedTags::kDescriptionTag:
144 trimmedContent.Trim(true).Trim(false);
145 mVersionPatch->changelog = SplitChangelogSentences(trimmedContent);
146 break;
147
148 case XmlParsedTags::kVersionTag:
149 trimmedContent.Trim(true).Trim(false);
150 mVersionPatch->version = VersionId::ParseFromString(trimmedContent);
151 break;
152
153 case XmlParsedTags::kLinkTag:
154 trimmedContent.Trim(true).Trim(false);
155 mVersionPatch->download = trimmedContent;
156 break;
157
158 default:
159 break;
160 }
161 }
162
HandleXMLChild(const std::string_view & tag)163 XMLTagHandler* UpdateDataParser::HandleXMLChild(const std::string_view& tag)
164 {
165 for (auto& xmlTag : mXmlTagNames)
166 {
167 if (tag == xmlTag.second)
168 return this;
169 }
170
171 return NULL;
172 }
173