// Modified by Yen-Ju Chen /* ** Channel.m ** ** Copyright (c) 2002 ** ** Author: Ludovic Marcotte ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Channel.h" #include "Plop.h" #include "PlopletView.h" #include // XML Headers needed under GNUstep #include #include @implementation Channel - (id) initWithContentsOfFile: (NSString *) file { NSString *string; NSData *data; self = [self init]; string = [NSString stringWithContentsOfFile: file]; data = [string dataUsingEncoding: NSISOLatin1StringEncoding]; [self processData: data]; return self; } - (id) initWithURL: (NSURL *) aURL { self = [self init]; [aURL loadResourceDataNotifyingClient: self usingCache: YES]; // [self processData: [aURL resourceDataUsingCache: NO]]; return self; } - (id) init { self = [super init]; allElements = [[NSMutableArray alloc] init]; totalBytes = 0; return self; } - (void) dealloc { RELEASE(allElements); RELEASE(plop); [super dealloc]; } // access / mutation methods - (void) addElement: (Element *) theElement { [allElements addObject: theElement]; } - (void) removeElement: (Element *) theElement { [allElements removeObject: theElement]; } - (void) removeAllElements { [allElements removeAllObjects]; } - (int) count { return [allElements count]; } - (int) itemCount { int i, count; count = 0; for (i = 0; i < [allElements count]; i++) { Element *aElement; aElement = [allElements objectAtIndex: i]; if ( [aElement type] == ITEM ) { count++; } } return count; } - (Element *) elementAtIndex: (int) theIndex { return [allElements objectAtIndex: theIndex]; } - (Plop *) plop { return plop; } - (void) setPlop: (Plop *) thePlop { ASSIGN(plop, thePlop); } - (PlopletView *) plopletView { return plopletView; } // No need to RETAIN here - (void) setPlopletView: (PlopletView *) theView { plopletView = theView; } - (void) URL: (NSURL *) sender resourceDataDidBecomeAvailable: (NSData *) newBytes { totalBytes += [newBytes length]; // We finally update our "view" if ( [self plopletView] ) { [[self plopletView] updateTextView: [NSString stringWithFormat: @"Loading %d bytes ...", totalBytes]]; } } - (void) URL: (NSURL *) sender resourceDidFailLoadingWithReason: (NSString *) reason { NSLog(@"failed loading URL, reason: %@:", reason); } - (void) URLResourceDidFinishLoading: (NSURL *) sender { [self processData: [sender resourceDataUsingCache: YES]]; } - (void) URLResourceDidCancelLoading: (NSURL*) sender { // We do nothing here } - (void) processData: (NSData *) aData; { // GNUstep XML Parsing Code GSXMLParser *aParser; if ( !aData ) { NSLog(@"Unable to get the data from the content source. Ignoring Plop."); return; } [self removeAllElements]; aParser = [GSXMLParser parserWithData: aData]; if ( [aParser parse] ) { GSXMLDocument *aDocument; GSXMLNode *aRoot, *aNode; // FIXME: Not sure about this // aDocument = [aParser doc]; aDocument = [aParser document]; aRoot = [aDocument root]; aNode = [aRoot firstChild]; // // We loop inside our channel/image/item nodes // while (aNode != nil) { if ( [aNode type] == XML_ELEMENT_NODE ) { if ( [[aNode name] caseInsensitiveCompare: @"CHANNEL"] == NSOrderedSame ) { [self _parseNodeInformationUsingElement: self node: aNode]; } else { Element *aElement; aElement = [[Element alloc] init]; [self _parseNodeInformationUsingElement: aElement node: aNode]; [self addElement: aElement]; RELEASE(aElement); } } // We get the next node aNode = [aNode next]; } // We finally update our "view" if ( [self plopletView] ) { [[self plopletView] updateTextView: nil]; } } else { NSLog(@"Error while decoding the RDF content."); } } @end // Private methods @implementation Channel (Private) - (void) _updateElement: (Element *) theElement name: (NSString *) theName content: (NSString *) theContent { if ( [theName caseInsensitiveCompare: @"TITLE"] == NSOrderedSame ) { [theElement setTitle: theContent]; } else if ( [theName caseInsensitiveCompare: @"LINK"] == NSOrderedSame ) { [theElement setLink: [NSURL URLWithString: theContent] ]; } else if ( [theName caseInsensitiveCompare: @"DESCRIPTION"] == NSOrderedSame ) { [theElement setDescription: theContent]; } else if ( [theName caseInsensitiveCompare: @"URL"] == NSOrderedSame ) { [theElement setURL: [NSURL URLWithString: theContent] ]; } } - (void) _parseNodeInformationUsingElement: (Element *) theElement node: (id) theNode { NSString *aNodeName; GSXMLNode *aChild; aNodeName = [(GSXMLNode *)theNode name]; // We decode the right type if ( [aNodeName caseInsensitiveCompare: @"CHANNEL"] == NSOrderedSame ) { [theElement setType: CHANNEL]; } else if ( [aNodeName caseInsensitiveCompare: @"IMAGE"] == NSOrderedSame ) { [theElement setType: IMAGE]; } else if ( [aNodeName caseInsensitiveCompare: @"ITEM"] == NSOrderedSame ) { [theElement setType: ITEM]; } else if ( [aNodeName caseInsensitiveCompare: @"TEXTINPUT"] == NSOrderedSame ) { [theElement setType: TEXTINPUT]; } else { [theElement setType: UNKNOWN]; } // We loop inside our channel/image/item node attributes if ( (aChild = [theNode firstChild]) ) { while ( aChild ) { NSString *aName, *aContent; GSXMLNode *aNode; // // Ok, this is kinda weird. Some klips are defined like that: // // ... // ... // // and some like: // // // ... // // if ( [[aChild name] caseInsensitiveCompare: @"ITEM"] == NSOrderedSame || [[aChild name] caseInsensitiveCompare: @"IMAGE"] == NSOrderedSame || [[aChild name] caseInsensitiveCompare: @"TEXTINPUT"] == NSOrderedSame ) { Element *aElement; aElement = [[Element alloc] init]; [self _parseNodeInformationUsingElement: aElement node: aChild]; [self addElement: aElement]; RELEASE(aElement); aChild = [aChild next]; continue; } aNode = [aChild firstChild]; while ( aNode ) { if ( [aNode type] == XML_TEXT_NODE ) { if ( [[[aNode content] stringByTrimmingSpaces] length] > 0 ) { break; } } aNode = [aNode next]; } if ( !aNode ) { aChild = [aChild next]; continue; } aName = [aChild name]; aContent = [[aNode content] stringByTrimmingSpaces]; if ( aName && aContent ) { [self _updateElement: theElement name: aName content: aContent]; } aChild = [aChild next]; } } else { NSLog(@"No children"); } } @end