/*************************************************************************** * 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 #include #include #include #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, "", 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 ); }