mirror of
https://github.com/HackPlan/winsparkle.git
synced 2026-01-12 17:02:51 +08:00
Moved is_windows_item() to anonymous namespace,
fixed tabs, added parsing break in OnEndElement()
This commit is contained in:
@@ -56,28 +56,25 @@ namespace
|
||||
#define ATTR_URL "url"
|
||||
#define ATTR_VERSION NS_SPARKLE_NAME("version")
|
||||
#define ATTR_SHORTVERSION NS_SPARKLE_NAME("shortVersionString")
|
||||
#define ATTR_OS NS_SPARKLE_NAME("os")
|
||||
#define OS_MARKER "windows"
|
||||
#define ATTR_OS NS_SPARKLE_NAME("os")
|
||||
#define OS_MARKER "windows"
|
||||
|
||||
// context data for the parser
|
||||
struct ContextData
|
||||
{
|
||||
ContextData(Appcast& a, XML_Parser& p)
|
||||
: appcast(a),
|
||||
parser(p),
|
||||
ContextData(XML_Parser& p)
|
||||
: parser(p),
|
||||
in_channel(0), in_item(0), in_relnotes(0), in_title(0), in_description(0)
|
||||
{}
|
||||
|
||||
// appcast we're parsing into
|
||||
Appcast& appcast;
|
||||
|
||||
// the parser we're using
|
||||
XML_Parser& parser;
|
||||
|
||||
// is inside <channel>, <item> or <sparkle:releaseNotesLink>, <title>, or <description> respectively?
|
||||
int in_channel, in_item, in_relnotes, in_title, in_description;
|
||||
|
||||
std::vector<Appcast> items;
|
||||
// parsed <item>s
|
||||
std::vector<Appcast> items;
|
||||
};
|
||||
|
||||
|
||||
@@ -92,8 +89,8 @@ void XMLCALL OnStartElement(void *data, const char *name, const char **attrs)
|
||||
else if ( ctxt.in_channel && strcmp(name, NODE_ITEM) == 0 )
|
||||
{
|
||||
ctxt.in_item++;
|
||||
Appcast item;
|
||||
ctxt.items.push_back(item);
|
||||
Appcast item;
|
||||
ctxt.items.push_back(item);
|
||||
}
|
||||
else if ( ctxt.in_item )
|
||||
{
|
||||
@@ -111,20 +108,20 @@ void XMLCALL OnStartElement(void *data, const char *name, const char **attrs)
|
||||
}
|
||||
else if (strcmp(name, NODE_ENCLOSURE) == 0 )
|
||||
{
|
||||
const int size = ctxt.items.size();
|
||||
const int size = ctxt.items.size();
|
||||
for ( int i = 0; attrs[i]; i += 2 )
|
||||
{
|
||||
const char *name = attrs[i];
|
||||
const char *value = attrs[i+1];
|
||||
|
||||
if ( strcmp(name, ATTR_URL) == 0 )
|
||||
ctxt.items[size-1].DownloadURL = value;
|
||||
if ( strcmp(name, ATTR_URL) == 0 )
|
||||
ctxt.items[size-1].DownloadURL = value;
|
||||
else if ( strcmp(name, ATTR_VERSION) == 0 )
|
||||
ctxt.items[size-1].Version = value;
|
||||
else if ( strcmp(name, ATTR_SHORTVERSION) == 0 )
|
||||
ctxt.items[size-1].ShortVersionString = value;
|
||||
else if ( strcmp(name, ATTR_OS) == 0 )
|
||||
ctxt.items[size-1].Os = value;
|
||||
else if ( strcmp(name, ATTR_OS) == 0 )
|
||||
ctxt.items[size-1].Os = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,13 +146,17 @@ void XMLCALL OnEndElement(void *data, const char *name)
|
||||
}
|
||||
else if ( ctxt.in_channel && strcmp(name, NODE_ITEM) == 0 )
|
||||
{
|
||||
ctxt.in_item--;
|
||||
ctxt.in_item--;
|
||||
if (ctxt.items[ctxt.items.size()-1].Os == OS_MARKER) {
|
||||
// we've found os-specific <item>, no need to continue parsing
|
||||
XML_StopParser(ctxt.parser, XML_TRUE);
|
||||
}
|
||||
}
|
||||
else if ( strcmp(name, NODE_CHANNEL) == 0 )
|
||||
{
|
||||
ctxt.in_channel--;
|
||||
// we've reached the end of <channel> element,
|
||||
// so we stop parsing
|
||||
// we've reached the end of <channel> element,
|
||||
// so we stop parsing
|
||||
XML_StopParser(ctxt.parser, XML_TRUE);
|
||||
}
|
||||
}
|
||||
@@ -164,7 +165,7 @@ void XMLCALL OnEndElement(void *data, const char *name)
|
||||
void XMLCALL OnText(void *data, const char *s, int len)
|
||||
{
|
||||
ContextData& ctxt = *static_cast<ContextData*>(data);
|
||||
const int size = ctxt.items.size();
|
||||
const int size = ctxt.items.size();
|
||||
|
||||
if ( ctxt.in_relnotes )
|
||||
ctxt.items[size-1].ReleaseNotesURL.append(s, len);
|
||||
@@ -174,6 +175,11 @@ void XMLCALL OnText(void *data, const char *s, int len)
|
||||
ctxt.items[size-1].Description.append(s, len);
|
||||
}
|
||||
|
||||
bool is_windows_item(const Appcast &item)
|
||||
{
|
||||
return item.Os == OS_MARKER;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
@@ -181,18 +187,13 @@ void XMLCALL OnText(void *data, const char *s, int len)
|
||||
Appcast class
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
bool is_windows_item(const Appcast &item)
|
||||
{
|
||||
return item.Os == OS_MARKER;
|
||||
}
|
||||
|
||||
void Appcast::Load(const std::string& xml)
|
||||
{
|
||||
XML_Parser p = XML_ParserCreateNS(NULL, NS_SEP);
|
||||
if ( !p )
|
||||
throw std::runtime_error("Failed to create XML parser.");
|
||||
|
||||
ContextData ctxt(*this, p);
|
||||
ContextData ctxt(p);
|
||||
|
||||
XML_SetUserData(p, &ctxt);
|
||||
XML_SetElementHandler(p, OnStartElement, OnEndElement);
|
||||
@@ -210,12 +211,12 @@ void Appcast::Load(const std::string& xml)
|
||||
|
||||
XML_ParserFree(p);
|
||||
|
||||
// Search for first <item> which has "sparkle:os=windows" attribute.
|
||||
// If none, use the first item.
|
||||
std::vector<Appcast>::iterator it = std::find_if(ctxt.items.begin(), ctxt.items.end(), is_windows_item);
|
||||
if (it == ctxt.items.end())
|
||||
it = ctxt.items.begin();
|
||||
*this = *it;
|
||||
// Search for first <item> which has "sparkle:os=windows" attribute.
|
||||
// If none, use the first item.
|
||||
std::vector<Appcast>::iterator it = std::find_if(ctxt.items.begin(), ctxt.items.end(), is_windows_item);
|
||||
if (it == ctxt.items.end())
|
||||
it = ctxt.items.begin();
|
||||
*this = *it;
|
||||
}
|
||||
|
||||
} // namespace winsparkle
|
||||
|
||||
Reference in New Issue
Block a user