usbloadergx/source/themes/Theme_List.cpp

243 lines
6.4 KiB
C++

/***************************************************************************
* Copyright (C) 2009
* by USB Loader GX Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Theme_List Class
* for the USB Loader GX
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gctypes.h>
#include "Theme_List.h"
#include "xml/xml.h"
#include "prompts/PromptWindows.h"
#define stringcompare(text, cmp, pos) strncasecmp((const char*) &text[pos-strlen(cmp)], (const char*) cmp, strlen((const char*) cmp))
static void copyhtmlsting(const char *from, char *outtext, const char *stopat, u32 &cnt)
{
u32 cnt2 = 0;
u32 stringlength = strlen(from);
while ((stringcompare(from, stopat, cnt+strlen(stopat)) != 0) && (cnt2 < 1024) && (cnt < stringlength))
{
outtext[cnt2] = from[cnt];
cnt2++;
cnt++;
}
outtext[cnt2] = '\0';
}
Theme_List::Theme_List(const char * url)
{
Theme = NULL;
themescount = 0;
if (!IsNetworkInit())
{
themescount = -1;
return;
}
struct block file = downloadfile(url);
if (!file.data || !file.size)
{
themescount = -2;
return;
}
themescount = CountThemes(file.data);
if (themescount <= 0)
{
free(file.data);
return;
}
ParseXML(file.data);
free(file.data);
}
Theme_List::~Theme_List()
{
for (int i = 0; i < themescount; i++)
{
if(Theme[i].themetitle)
delete [] Theme[i].themetitle;
if(Theme[i].author)
delete [] Theme[i].author;
if(Theme[i].imagelink)
delete [] Theme[i].imagelink;
if(Theme[i].downloadlink)
delete [] Theme[i].downloadlink;
Theme[i].themetitle = NULL;
Theme[i].author = NULL;
Theme[i].imagelink = NULL;
Theme[i].downloadlink = NULL;
}
if(Theme)
delete [] Theme;
Theme = NULL;
}
int Theme_List::CountThemes(const u8 * xmlfile)
{
char tmp[200];
u32 cnt = 0;
u32 stringlength = strlen((const char *) xmlfile);
memset(tmp, 0, sizeof(tmp));
while (cnt < stringlength)
{
if (stringcompare(xmlfile, "<totalthemes>", cnt) == 0)
{
copyhtmlsting((const char *) xmlfile, tmp, ">", cnt);
break;
}
cnt++;
}
tmp[cnt+1] = 0;
return atoi(tmp);
}
bool Theme_List::ParseXML(const u8 * xmlfile)
{
char element_text[1024];
memset(element_text, 0, sizeof(element_text));
mxml_node_t *nodetree=NULL;
mxml_node_t *nodedata=NULL;
mxml_node_t *nodeid=NULL;
mxml_index_t *nodeindex=NULL;
nodetree = mxmlLoadString(NULL, (const char *) xmlfile, MXML_OPAQUE_CALLBACK);
if (nodetree == NULL)
{
return false;
}
nodedata = mxmlFindElement(nodetree, nodetree, "themes", NULL, NULL, MXML_DESCEND);
if (nodedata == NULL)
{
return false;
}
nodeindex = mxmlIndexNew(nodedata,"name", NULL);
nodeid = mxmlIndexReset(nodeindex);
Theme = new Theme_Info[themescount];
memset(Theme, 0, sizeof(Theme));
for (int i = 0; i < themescount; i++)
{
nodeid = mxmlIndexFind(nodeindex,"name", NULL);
if (nodeid != NULL)
{
get_nodetext(nodeid, element_text, sizeof(element_text));
Theme[i].themetitle = new char[strlen(element_text)+2];
snprintf(Theme[i].themetitle,strlen(element_text)+1, "%s", element_text);
GetTextFromNode(nodeid, nodedata, (char *) "creator", NULL, NULL, MXML_NO_DESCEND, element_text,sizeof(element_text));
Theme[i].author = new char[strlen(element_text)+2];
snprintf(Theme[i].author,strlen(element_text)+1, "%s", element_text);
GetTextFromNode(nodeid, nodedata, (char *) "thumbpath", NULL, NULL, MXML_NO_DESCEND, element_text,sizeof(element_text));
Theme[i].imagelink = new char[strlen(element_text)+2];
snprintf(Theme[i].imagelink,strlen(element_text)+1, "%s", element_text);
GetTextFromNode(nodeid, nodedata, (char *) "downloadpath", NULL, NULL, MXML_NO_DESCEND, element_text,sizeof(element_text));
Theme[i].downloadlink = new char[strlen(element_text)+2];
snprintf(Theme[i].downloadlink,strlen(element_text)+1, "%s", element_text);
GetTextFromNode(nodeid, nodedata, (char *) "averagerating", NULL, NULL, MXML_NO_DESCEND, element_text,sizeof(element_text));
Theme[i].rating = atoi(element_text);
}
}
mxmlIndexDelete(nodeindex);
free(nodetree);
free(nodedata);
free(nodeid);
nodetree=NULL;
nodedata=NULL;
nodeid=NULL;
nodeindex=NULL;
return true;
}
const char * Theme_List::GetThemeTitle(int ind)
{
if (ind > themescount || ind < 0 || !Theme || themescount <= 0)
return NULL;
else
return Theme[ind].themetitle;
}
const char * Theme_List::GetThemeAuthor(int ind)
{
if (ind > themescount || ind < 0 || !Theme || themescount <= 0)
return NULL;
else
return Theme[ind].author;
}
const char * Theme_List::GetImageLink(int ind)
{
if (ind > themescount || ind < 0 || !Theme || themescount <= 0)
return NULL;
else
return Theme[ind].imagelink;
}
const char * Theme_List::GetDownloadLink(int ind)
{
if (ind > themescount || ind < 0 || !Theme || themescount <= 0)
return NULL;
else
return Theme[ind].downloadlink;
}
int Theme_List::GetThemeCount()
{
return themescount;
}
static int ListCompare(const void *a, const void *b)
{
Theme_Info *ab = (Theme_Info*) a;
Theme_Info *bb = (Theme_Info*) b;
return stricmp((char *) ab->themetitle, (char *) bb->themetitle);
}
void Theme_List::SortList()
{
qsort(Theme, themescount, sizeof(Theme_Info), ListCompare);
}