From affe807f4895b1c0c1140a7a7bfe0ee0a773009e Mon Sep 17 00:00:00 2001 From: skeezix Date: Wed, 9 Mar 2011 11:50:15 -0500 Subject: [PATCH] libpnd; supporting newer and blocks (with backwards compat for existing and <description> series) --- include/pnd_pxml_names.h | 6 ++ lib/pnd_tinyxml.cpp | 197 ++++++++++++++++++++++++++++----------- 2 files changed, 149 insertions(+), 54 deletions(-) diff --git a/include/pnd_pxml_names.h b/include/pnd_pxml_names.h index 766a0c9..24c2294 100644 --- a/include/pnd_pxml_names.h +++ b/include/pnd_pxml_names.h @@ -13,12 +13,18 @@ extern "C" { #define PND_PXML_APP "application" /* <title lang="..."> */ +// deprecated - Zaxxon firmware through HF5 (supported for backwards compatibility) #define PND_PXML_ENAME_TITLE "title" #define PND_PXML_ATTRNAME_TITLELANG "lang" +// Zaxxon firmware from HF6 onwards +#define PND_PXML_NODENAME_TITLES "titles" /* <description lang="...">... */ +// deprecated - Zaxxon firmware through HF5 (supported for backwards compatibility) #define PND_PXML_ENAME_DESCRIPTION "description" #define PND_PXML_ATTRNAME_DESCRLANG "lang" +// Zaxxon firmware from HF6 onwards +#define PND_PXML_NODENAME_DESCRIPTIONS "descriptions" /* <exec background="true" standalone="false" command="..." startdir="..." /> */ #define PND_PXML_ENAME_EXEC "exec" diff --git a/lib/pnd_tinyxml.cpp b/lib/pnd_tinyxml.cpp index 2c6d4e9..8e8319f 100644 --- a/lib/pnd_tinyxml.cpp +++ b/lib/pnd_tinyxml.cpp @@ -26,80 +26,169 @@ unsigned char pnd_pxml_parse_titles(const TiXmlHandle hRoot, pnd_pxml_t *app) { app->titles = (pnd_localized_string_t *)malloc(sizeof(pnd_localized_string_t) * app->titles_alloc_c); if (!app->titles) return (0); //errno = NOMEM - //Go through all title tags and load them. - for (pElem = hRoot.FirstChild(PND_PXML_ENAME_TITLE).Element(); pElem; - pElem = pElem->NextSiblingElement(PND_PXML_ENAME_TITLE)) - { + // Go through all title tags and load them. + // - Check if newer style titles sub-block exists; if so, use that. + // - if not, fall back to old style + // - failing that, crash earth into sun + if ( (pElem = hRoot.FirstChild(PND_PXML_NODENAME_TITLES).Element()) ) { + // newer <titles> block - if ( ! pElem->GetText() ) { - continue; - } + pElem = pElem -> FirstChildElement ( PND_PXML_ENAME_TITLE ); + + while ( pElem ) { + + // handle <title lang="en_US">Program Title + // + + // parse out the text and lang + char *text, *lang; + + if ( ! ( text = strdup ( pElem -> GetText() ) ) ) { + continue; + } + + if ( ! ( lang = pnd_pxml_get_attribute ( pElem, PND_PXML_ATTRNAME_TITLELANG ) ) ) { + continue; + } + + // increment counter; if we're running out of buffers, grow to handle the new strings + app -> titles_c++; + + if ( app -> titles_c > app -> titles_alloc_c ) { + // we don't have enough strings allocated + app -> titles_alloc_c <<= 1; + app -> titles = (pnd_localized_string_t *)realloc((void*)app->titles, app->titles_alloc_c); + if (!app->titles) return (0); //errno = ENOMEM + } + + // populate the stringbuf + pnd_localized_string_t *title = &app->titles[app->titles_c - 1]; + title->language = lang; + title->string = text; + + // next + pElem = pElem -> NextSiblingElement ( PND_PXML_ENAME_TITLE ); - char *text = strdup(pElem->GetText()); - if (!text) continue; + } // foreach - char *lang = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_TITLELANG); - if (!lang) continue; + } else { + // older style entry series - app->titles_c++; - if (app->titles_c > app->titles_alloc_c) //we don't have enough strings allocated + for ( pElem = hRoot.FirstChild(PND_PXML_ENAME_TITLE).Element(); pElem; + pElem = pElem->NextSiblingElement(PND_PXML_ENAME_TITLE)) { - app->titles_alloc_c <<= 1; - app->titles = (pnd_localized_string_t *)realloc((void*)app->titles, app->titles_alloc_c); - if (!app->titles) return (0); //errno = ENOMEM - } - pnd_localized_string_t *title = &app->titles[app->titles_c - 1]; - title->language = lang; - title->string = text; + if ( ! pElem->GetText() ) { + continue; + } + + char *text = strdup(pElem->GetText()); + if (!text) continue; - //pnd_log ( PND_LOG_DEFAULT, (char*)" Title/Lang: %s/%s\n", text, lang ); + char *lang = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_TITLELANG); + if (!lang) continue; - } + app->titles_c++; + if (app->titles_c > app->titles_alloc_c) //we don't have enough strings allocated + { + app->titles_alloc_c <<= 1; + app->titles = (pnd_localized_string_t *)realloc((void*)app->titles, app->titles_alloc_c); + if (!app->titles) return (0); //errno = ENOMEM + } + + pnd_localized_string_t *title = &app->titles[app->titles_c - 1]; + title->language = lang; + title->string = text; + + //pnd_log ( PND_LOG_DEFAULT, (char*)" Title/Lang: %s/%s\n", text, lang ); + + } // for + + } // new or old style <title(s)> return ( 1 ); } -unsigned char pnd_pxml_parse_descriptions(const TiXmlHandle hRoot, pnd_pxml_t *app) -{ - TiXmlElement *pElem; - app->descriptions_alloc_c = 4; //TODO: adjust this based on how many descriptions a PXML usually has. Power of 2. +unsigned char pnd_pxml_parse_descriptions(const TiXmlHandle hRoot, pnd_pxml_t *app) { + TiXmlElement *pElem; + app->descriptions_alloc_c = 4; //TODO: adjust this based on how many descriptions a PXML usually has. Power of 2. - app->descriptions = (pnd_localized_string_t *)malloc(sizeof(pnd_localized_string_t) * app->descriptions_alloc_c); - if (!app->descriptions) - { - app->descriptions_alloc_c = 0; - return (0); //errno = NOMEM - } + app->descriptions = (pnd_localized_string_t *)malloc(sizeof(pnd_localized_string_t) * app->descriptions_alloc_c); + if (!app->descriptions) + { + app->descriptions_alloc_c = 0; + return (0); //errno = NOMEM + } - for (pElem = hRoot.FirstChild(PND_PXML_ENAME_DESCRIPTION).Element(); pElem; - pElem = pElem->NextSiblingElement(PND_PXML_ENAME_DESCRIPTION)) - { + // similar logic to how <titles> or <title> is parsed + // - if <titles> block is found, use that; otherwise fall back to <title> deprecated form + if ( (pElem = hRoot.FirstChild ( PND_PXML_NODENAME_DESCRIPTIONS).Element() ) ) { + // newer style <descriptions> block - if ( ! pElem->GetText() ) { - continue; - } + pElem = pElem -> FirstChildElement ( PND_PXML_ENAME_DESCRIPTION ); - char *text = strdup(pElem->GetText()); - if (!text) continue; + while ( pElem ) { - char *lang = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_DESCRLANG); - if (!lang) continue; + char *text, *lang; - app->descriptions_c++; - if (app->descriptions_c > app->descriptions_alloc_c) //we don't have enough strings allocated - { - app->descriptions_alloc_c <<= 1; - app->descriptions = (pnd_localized_string_t*)realloc((void*)app->descriptions, app->descriptions_alloc_c * sizeof(pnd_localized_string_t) ); - if (!app->descriptions) return (0); //errno = ENOMEM - } + if ( ! ( text = strdup ( pElem -> GetText() ) ) ) { + continue; + } - pnd_localized_string_t *description = &app->descriptions[app->descriptions_c - 1]; - description->language = lang; - description->string = text; - } + if ( ! ( lang = pnd_pxml_get_attribute ( pElem, PND_PXML_ATTRNAME_DESCRLANG ) ) ) { + continue; + } + + app->descriptions_c++; + if (app->descriptions_c > app->descriptions_alloc_c) //we don't have enough strings allocated + { + app->descriptions_alloc_c <<= 1; + app->descriptions = (pnd_localized_string_t*)realloc((void*)app->descriptions, app->descriptions_alloc_c * sizeof(pnd_localized_string_t) ); + if (!app->descriptions) return (0); //errno = ENOMEM + } + + pnd_localized_string_t *description = &app->descriptions[app->descriptions_c - 1]; + description->language = lang; + description->string = text; + + // next + pElem = pElem -> NextSiblingElement ( PND_PXML_ENAME_DESCRIPTION ); - return (1); + } // foreach + + } else { + // fallback to older approach + + for (pElem = hRoot.FirstChild(PND_PXML_ENAME_DESCRIPTION).Element(); pElem; + pElem = pElem->NextSiblingElement(PND_PXML_ENAME_DESCRIPTION)) + { + + if ( ! pElem->GetText() ) { + continue; + } + + char *text = strdup(pElem->GetText()); + if (!text) continue; + + char *lang = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_DESCRLANG); + if (!lang) continue; + + app->descriptions_c++; + if (app->descriptions_c > app->descriptions_alloc_c) //we don't have enough strings allocated + { + app->descriptions_alloc_c <<= 1; + app->descriptions = (pnd_localized_string_t*)realloc((void*)app->descriptions, app->descriptions_alloc_c * sizeof(pnd_localized_string_t) ); + if (!app->descriptions) return (0); //errno = ENOMEM + } + + pnd_localized_string_t *description = &app->descriptions[app->descriptions_c - 1]; + description->language = lang; + description->string = text; + } // for + + } // new form or old form? + + return ( 1 ); } unsigned char pnd_pxml_parse ( const char *pFilename, char *buffer, unsigned int length, pnd_pxml_t **apps ) { -- 2.39.2