* GSWeb.framework/GSWHTMLTemplateParser.m/.h:

o added (New HTML Template Parser)
* GSWeb.framework/GSWHTMLRawParser.m/.h:
  o aded (New HTML Parser)
* GSWeb.framework/GSWDeclaration.h/.m:
  o added (Handle a declaration i.e. an entry from .gswd)
* GSWeb.framework/GSWDeclarationParser.h/.m:
  o added (.gswd parser)
* GSWeb.framework/GSWBaseParser.h/.m:
  o added (base class for parsers)
* GSWeb.framework/GSWTemporaryElement.h/.m:
  o added (Temporary element to handle dynamic tags)


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gsweb/trunk@18891 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
mguesdon 2004-03-25 08:25:48 +00:00
parent 4f27cd9279
commit 6ccff85df6
12 changed files with 3100 additions and 0 deletions

View file

@ -0,0 +1,97 @@
/** GSWBaseParser - <title>GSWeb: Class GSWBaseParser</title>
Copyright (C) 2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 2004
$Revision$
$Date$
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
// $Id$
#ifndef _GSWBaseParser_h__
#define _GSWBaseParser_h__
//====================================================================
@interface GSWBaseParser : NSObject
{
NSString* _string;
unichar* _uniBuf;
int _length;
int _index;
}
-(NSString*)currentLineAndColumnIndexesString;
-(NSString*)lineAndColumnIndexesStringFromIndex:(int)index;
-(int)currentLineIndex;
-(int)lineIndexFromIndex:(int)index;
-(void)lineAndColumnIndexesFromIndex:(int)index
returnsLineIndex:(int*)lineIndexPtr
columnIndex:(int*)colIndexPtr;
@end
extern void _ParserDebugLogBuffer(char* fn,char* file,int line,unichar* uniBuf,int length,int index,int charsCount);
#define ParserDebugLogBuffer(uniBuf,length,index,charsCount) _ParserDebugLogBuffer(__PRETTY_FUNCTION__,__FILE__,__LINE__,uniBuf,length,index,charsCount)
static inline BOOL _parserIsDigit(unichar c)
{
return ((c>='0' && c<='9') ? YES: NO);
};
static inline BOOL _parserIsHexDigit(unichar c)
{
return (((c>='0' && c<='9')
|| (c>='A' && c<='F')
|| (c>='a' && c<='f')) ? YES: NO);
};
static inline BOOL _parserIsBlankChar(unichar c)
{
switch(c)
{
case ' ':
case '\t':
case '\f':
case '\r':
case '\n':
case '\v':
return YES;
default:
return NO;
};
};
static inline BOOL _parserIsEndOfLineChar(unichar c)
{
switch(c)
{
case '\r':
case '\n':
return YES;
default:
return NO;
};
};
#endif // _GSWBaseParser_h__

View file

@ -0,0 +1,148 @@
/** GSWBaseParser.m - <title>GSWeb: Class GSWBaseParser</title>
Copyright (C) 2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 2004
$Revision$
$Date$
$Id$
<abstract></abstract>
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
#include "config.h"
RCS_ID("$Id$")
#include "GSWeb.h"
#include "GSWBaseParser.h"
//====================================================================
@implementation GSWBaseParser
//--------------------------------------------------------------------
+(void)initialize
{
if (self == [GSWBaseParser class])
{
};
};
//--------------------------------------------------------------------
-(void)dealloc
{
DESTROY(_string);
if (_uniBuf)
{
objc_free(_uniBuf);
_uniBuf=NULL;
};
[super dealloc];
};
//--------------------------------------------------------------------
-(NSString*)currentLineAndColumnIndexesString
{
return [self lineAndColumnIndexesStringFromIndex:_index];
}
//--------------------------------------------------------------------
-(NSString*)lineAndColumnIndexesStringFromIndex:(int)index
{
int lineIndex=0;
int columnIndex=0;
[self lineAndColumnIndexesFromIndex:index
returnsLineIndex:&lineIndex
columnIndex:&columnIndex];
return [NSString stringWithFormat:@"(line: %d column: %d)",
lineIndex,columnIndex];
}
//--------------------------------------------------------------------
-(int)currentLineIndex
{
return [self lineIndexFromIndex:_index];
}
//--------------------------------------------------------------------
-(int)lineIndexFromIndex:(int)index
{
int lineIndex=0;
[self lineAndColumnIndexesFromIndex:index
returnsLineIndex:&lineIndex
columnIndex:NULL];
return lineIndex;
};
//--------------------------------------------------------------------
-(void)lineAndColumnIndexesFromIndex:(int)index
returnsLineIndex:(int*)lineIndexPtr
columnIndex:(int*)colIndexPtr
{
int lineIndex=0;
int columnIndex=0;
int i=0;
if (index>=_length)
{
lineIndex=999999;
columnIndex=0;
};
for(i=0;i<index && i<_length;i++)
{
if (_uniBuf[i]=='\r')
{
if (i+1<_length
&& _uniBuf[i+1]=='\n')
i++;
else
{
lineIndex++;
columnIndex=0;
};
}
else if (_uniBuf[i+1]=='\n')
{
lineIndex++;
columnIndex=0;
}
else
columnIndex++;
};
if (lineIndexPtr)
*lineIndexPtr=lineIndex;
if (colIndexPtr)
*colIndexPtr=columnIndex;
};
@end
void _ParserDebugLogBuffer(char* fn,char* file,int line,unichar* uniBuf,int length,int index,int charsCount)
{
printf("In %s (%s %d): length=%d index=%d ==>\n",fn,file,line,length,index);
int i=0;
for(i=index;i<length && i-index<charsCount;i++)
printf("%c",(char)(uniBuf[i]));
printf("\n");
fflush(stdout);
}

View file

@ -0,0 +1,57 @@
/** GSWDeclaration.h - <title>GSWeb: Class GSWDeclaration</title>
Copyright (C) 2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 2004
$Revision$
$Date$
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
// $Id$
#ifndef _GSWDeclaration_h__
#define _GSWDeclaration_h__
//====================================================================
@interface GSWDeclaration: NSObject <NSCopying>
{
NSString* _name;
NSString* _type;
NSMutableDictionary* _associations;
};
+(GSWDeclaration*)declarationWithName:(NSString*)name
type:(NSString*)type
associations:(NSDictionary*)associations;
-(id)initWithName:(NSString*)name
type:(NSString*)type
associations:(NSDictionary*)associations;
-(NSString*)name;
-(void)setName:(NSString*)name;
-(NSString*)type;
-(void)setType:(NSString*)type;
-(NSDictionary*)associations;
-(void)setAssociations:(NSDictionary*)associations;
@end
#endif //_GSWDeclaration_h__

View file

@ -0,0 +1,164 @@
/** GSWDeclaration.m - <title>GSWeb: Class GSWDeclaration</title>
Copyright (C) 2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 2004
$Revision$
$Date$
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
#include "config.h"
RCS_ID("$Id$")
#include "GSWeb.h"
//====================================================================
@implementation GSWDeclaration
//--------------------------------------------------------------------
+(GSWDeclaration*)declarationWithName:(NSString*)name
type:(NSString*)type
associations:(NSDictionary*)associations
{
return [[[self alloc]initWithName:name
type:type
associations:associations]autorelease];
};
//--------------------------------------------------------------------
// init
-(id)init
{
if ((self=[super init]))
{
};
return self;
};
//--------------------------------------------------------------------
-(id)initWithName:(NSString*)name
type:(NSString*)type
associations:(NSDictionary*)associations
{
if ((self=[self init]))
{
[self setName:name];
[self setType:type];
[self setAssociations:associations];
};
return self;
};
//--------------------------------------------------------------------
-(void)dealloc
{
DESTROY(_name);
DESTROY(_type);
DESTROY(_associations);
[super dealloc];
}
//--------------------------------------------------------------------
-(id)copyWithZone:(NSZone*)zone
{
GSWDeclaration* clone = [[isa allocWithZone:zone] init];
ASSIGNCOPY(clone->_name,_name);
ASSIGNCOPY(clone->_type,_type);
ASSIGNCOPY(clone->_associations,_associations);
return clone;
};
//--------------------------------------------------------------------
-(id)initWithCoder:(NSCoder*)coder
{
if ((self = [super init]))
{
[coder decodeValueOfObjCType:@encode(id)
at:&_name];
[coder decodeValueOfObjCType:@encode(id)
at:&_type];
[coder decodeValueOfObjCType:@encode(id)
at:&_associations];
};
return self;
};
//--------------------------------------------------------------------
-(void)encodeWithCoder:(NSCoder*)coder
{
[coder encodeObject:_name];
[coder encodeObject:_type];
[coder encodeObject:_associations];
};
//--------------------------------------------------------------------
-(NSString*)description
{
return [NSString stringWithFormat:@"<%s %p name:[%@] type:[%@] associations:\n%@",
object_get_class_name(self),
(void*)self,
_name,
_type,
_associations];
};
//--------------------------------------------------------------------
-(NSString*)name
{
return _name;
};
//--------------------------------------------------------------------
-(void)setName:(NSString*)name
{
ASSIGNCOPY(_name,name);
};
//--------------------------------------------------------------------
-(NSString*)type
{
return _type;
};
//--------------------------------------------------------------------
-(void)setType:(NSString*)type
{
ASSIGNCOPY(_type,type);
};
//--------------------------------------------------------------------
-(NSDictionary*)associations
{
return _associations;
};
//--------------------------------------------------------------------
-(void)setAssociations:(NSDictionary*)associations
{
ASSIGNCOPY(_associations,associations);
};
@end

View file

@ -0,0 +1,73 @@
/** GSWDeclarationParser - <title>GSWeb: Class GSWDeclarationParser</title>
Copyright (C) 2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 2004
$Revision$
$Date$
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
// $Id$
#ifndef _GSWDeclarationParser_h__
#define _GSWDeclarationParser_h__
//====================================================================
@protocol GSWDeclarationParserPragmaDelegate
-(NSDictionary*)includedDeclarationsFromFilePath:(NSString*)file
fromFrameworkNamed:(NSString*)frameworkName;
@end
//====================================================================
@interface GSWDeclarationParser : GSWBaseParser
{
id<GSWDeclarationParserPragmaDelegate> _pragmaDelegate;
NSMutableDictionary* _declarations;
NSString* _fileName;
NSString* _frameworkName;
}
+(GSWDeclarationParser*)declarationParserWithPragmaDelegate:(id<GSWDeclarationParserPragmaDelegate>)pragmaDelegate;
-(id)initWithPragmaDelegate:(id<GSWDeclarationParserPragmaDelegate>)pragmaDelegate;
-(NSDictionary*)parseDeclarationString:(NSString*)declarationString;
-(NSDictionary*)parseDeclarationString:(NSString*)declarationString
named:(NSString*)declarationFileName
inFrameworkNamed:(NSString*)declarationFrameworkName;
-(BOOL)skipBlanks;
-(BOOL)skipComment;
-(BOOL)skipBlanksAndComments;
-(void)parsePragma;
-(NSString*)parseIdentifier;
-(NSData*)parseHexData;
-(NSNumber*)tryParseBoolean;
-(NSNumber*)parseNumber;
-(NSNumber*)parseHexNumber;
-(id)parseValueAsAssociation:(BOOL)asAssociation;
-(NSDictionary*)parseDictionaryWithValuesAsAssociations:(BOOL)valuesAsAssociations;
-(NSArray*)parseArray;
-(GSWDeclaration*)parseDeclaration;
@end
#endif // _GSWDeclarationParser_h__

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,63 @@
/** GSWHTMLRawParser - <title>GSWeb: Class GSWHTMLRawParser</title>
Copyright (C) 2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 2004
$Revision$
$Date$
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
// $Id$
#ifndef _GSWHTMLRawParser_h__
#define _GSWHTMLRawParser_h__
//====================================================================
/** 'Raw' HTML Parser
It interpret only dynamic tags (gsweb/wo/oog) and comments
All other text is considered as raw text.
**/
@interface GSWHTMLRawParser : GSWBaseParser
{
id<GSWTemplateParserDelegate> _delegate; /** Delegate **/
int _textStartIndex; /** raw text start index **/
int _textStopIndex; /** raw text stop index **/
}
+(GSWHTMLRawParser*)parserWithDelegate:(id<GSWTemplateParserDelegate>)delegate
htmlString:(NSString*)htmlString;
-(id)initWithDelegate:(id<GSWTemplateParserDelegate>)delegate
htmlString:(NSString*)htmlString;
/** Parse the html _string and call delegate methods
May raise exception.
**/
-(void)parseHTML;
@end
#endif //_GSWHTMLRawParser_h__

View file

@ -0,0 +1,690 @@
/** GSWHTMLRawParser.m - <title>GSWeb: Class GSWHTMLRawParser</title>
Copyright (C) 2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 2004
$Revision$
$Date$
$Id$
<abstract></abstract>
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
#include "config.h"
RCS_ID("$Id$")
#include "GSWeb.h"
#include "GSWHTMLRawParser.h"
//strlen("gsweb")
#define GSWEB_TAG_LENGTH 5
//strlen("webobjects")
#define WO_TAG_LENGTH 10
//strlen("!--")
#define COMMENT_TAG_LENGTH 3
static GSWHTMLRawParserTagType GetTagType(unichar* uniBuf,int length,int* indexPtr,BOOL* isClosingTagPtr)
{
GSWHTMLRawParserTagType tagType=GSWHTMLRawParserTagType_unknown;
NSCAssert(*indexPtr<length,@"End of buffer");
if (uniBuf[(*indexPtr)]=='/')
{
*isClosingTagPtr=YES;
(*indexPtr)++;
}
else
*isClosingTagPtr=NO;
if (*indexPtr>=length)
{
[NSException raise:NSInvalidArgumentException
format:@"End of buffer reached while geting tag type"];
};
switch(uniBuf[(*indexPtr)])
{
case 'g':
case 'G':
if ((*indexPtr)+GSWEB_TAG_LENGTH<length
&& tolower(uniBuf[(*indexPtr)+1])=='s'
&& tolower(uniBuf[(*indexPtr)+2])=='w'
&& tolower(uniBuf[(*indexPtr)+3])=='e'
&& tolower(uniBuf[(*indexPtr)+4])=='b')
{
(*indexPtr)+=GSWEB_TAG_LENGTH;
tagType=GSWHTMLRawParserTagType_gsweb;
}
break;
case 'w':
case 'W':
if ((*indexPtr)+WO_TAG_LENGTH<length
&& tolower(uniBuf[(*indexPtr)+1])=='e'
&& tolower(uniBuf[(*indexPtr)+2])=='b'
&& tolower(uniBuf[(*indexPtr)+3])=='o'
&& tolower(uniBuf[(*indexPtr)+4])=='b'
&& tolower(uniBuf[(*indexPtr)+5])=='j'
&& tolower(uniBuf[(*indexPtr)+6])=='e'
&& tolower(uniBuf[(*indexPtr)+7])=='c'
&& tolower(uniBuf[(*indexPtr)+8])=='t')
{
(*indexPtr)+=WO_TAG_LENGTH;
tagType=GSWHTMLRawParserTagType_wo;
};
break;
case '#':
(*indexPtr)+=1;
tagType=GSWHTMLRawParserTagType_oog;
break;
case '!':
if ((*indexPtr)+COMMENT_TAG_LENGTH<length
&& tolower(uniBuf[(*indexPtr)+1])=='-'
&& tolower(uniBuf[(*indexPtr)+2])=='-')
{
(*indexPtr)+=COMMENT_TAG_LENGTH;
tagType=GSWHTMLRawParserTagType_comment;
};
break;
default:
tagType=GSWHTMLRawParserTagType_unknown;
break;
};
return tagType;
};
//====================================================================
@implementation GSWHTMLRawParser
//--------------------------------------------------------------------
+(GSWHTMLRawParser*)parserWithDelegate:(id<GSWTemplateParserDelegate>)delegate
htmlString:(NSString*)htmlString
{
return [[[self alloc]initWithDelegate:delegate
htmlString:htmlString]autorelease];
};
//--------------------------------------------------------------------
-(id)initWithDelegate:(id<GSWTemplateParserDelegate>)delegate
htmlString:(NSString*)htmlString
{
if ((self=[self init]))
{
ASSIGN(_delegate,delegate);
ASSIGNCOPY(_string,htmlString);
};
return self;
}
//--------------------------------------------------------------------
/** Called when finding a new dynamic tag or a new comment or at the
end of the string to record seen text parts
Call delegate -parser:didParseText:
**/
-(void)didParseText
{
LOGObjectFnStart();
// Is there some text ?
if(_textStopIndex>=_textStartIndex)
{
// Create text string
NSString* content=[NSString stringWithCharacters:_uniBuf+_textStartIndex
length:_textStopIndex-_textStartIndex+1];
NSDebugMLLog(@"GSWHTMLRawParser",@"GSWHTMLRawParser didParseText (length=%d): %@",
[content length],content);
// Call delegate -parser:didParseText:
[_delegate parser:self
didParseText:content];
// reset textStartIndex
_textStartIndex=_index;
};
LOGObjectFnStop();
}
//--------------------------------------------------------------------
/** Called when a new dynamic tag is opened
tagType can be gsweb, wo or oog
taProperties contains key+values of tag properties
Call delegate -parser:didParseOpeningDynamicTagOfType:withProperties:
**/
-(void)startDynamicTagOfType:(GSWHTMLRawParserTagType)tagType
withProperties:(NSDictionary*)tagProperties
templateInfo:(NSString*)templateInfo
{
LOGObjectFnStart();
// Records previously parsed text
[self didParseText];
NSDebugMLLog(@"GSWHTMLRawParser",@"GSWHTMLRawParser startDynamicTagOfType:%d withProperties:%@",
tagType,tagProperties);
// Calls delegate -parser:didParseOpeningDynamicTagOfType:withProperties:
[_delegate parser:self
didParseOpeningDynamicTagOfType:tagType
withProperties:tagProperties
templateInfo:templateInfo];
LOGObjectFnStop();
}
//--------------------------------------------------------------------
/** Called when a dynamic tag is closed
tagType can be gsweb, wo or oog
Call delegate -parser:didParseClosingDynamicTagOfType:
**/
-(void)stopDynamicTagOfType:(GSWHTMLRawParserTagType)tagType
withTemplateInfo:(NSString*)templateInfo
{
LOGObjectFnStart();
// Records previously parsed text
[self didParseText];
NSDebugMLLog(@"GSWHTMLRawParser",@"GSWHTMLRawParser stopDynamicTagOfType:%d",
tagType);
// Calls delegate -parser:didParseClosingDynamicTagOfType:
[_delegate parser:self
didParseClosingDynamicTagOfType:tagType
withTemplateInfo:templateInfo];
LOGObjectFnStop();
}
//--------------------------------------------------------------------
/** Called when a is parsed
Call delegate -parser:didParseComment:
**/
-(void)didParseCommentWithContentString:(NSString*)contentString
{
LOGObjectFnStart();
// Records previously parsed text
[self didParseText];
// Is there comment text
if ([contentString length]>0)
{
NSDebugMLLog(@"GSWHTMLRawParser",@"GSWHTMLRawParser didParseComment (length=%d): %@",
[contentString length],contentString);
// Calls delegate -parser:didParseComment:
[_delegate parser:self
didParseComment:contentString];
};
LOGObjectFnStop();
}
//--------------------------------------------------------------------
/** Skip a quoted string
indexPtr should point on the first quote
stopIndex should be the end of the string
when returning indexPtr point on the last quote.
Quoted substrings are handled
An exception is raised if the end quote is not found,...
**/
-(void)_skipQuotedStringWithQuote:(unichar)quote
index:(int*)indexPtr
stopIndex:(int)stopIndex
{
int startIndex=0;
LOGObjectFnStart();
//ParserDebugLogBuffer(_uniBuf,stopIndex+1,*indexPtr,stopIndex+1);
NSAssert2(_uniBuf[*indexPtr]==quote,@"First character is not a '%c' but a '%c'",
(char)quote,(char)_uniBuf[*indexPtr]);
(*indexPtr)++; //skip quote
startIndex=*indexPtr;
while(*indexPtr<=stopIndex
&& _uniBuf[*indexPtr]!=quote)
{
if (_uniBuf[*indexPtr]=='"' || _uniBuf[*indexPtr]=='\'')
{
[self _skipQuotedStringWithQuote:_uniBuf[*indexPtr]
index:indexPtr
stopIndex:stopIndex];
(*indexPtr)++;// skip last quote
}
else
(*indexPtr)++;
}
NSDebugMLog(@"startIndex=%d *indexPtr=%d _uniBuf[*indexPtr]='%c'",
startIndex,*indexPtr,(char)_uniBuf[*indexPtr]);
if (_uniBuf[*indexPtr]!=quote)
{
if (*indexPtr>stopIndex)
[NSException raise:NSInvalidArgumentException
format:@"Found end of string before end quote when skipping quoted string starting at %@.",
[self currentLineIndex]];
else
[NSException raise:NSInvalidArgumentException
format:@"Didn't found end quote when skipping quoted string starting at %@. Found '%c' instead",
[self currentLineIndex],(char)_uniBuf[_index]];
};
NSAssert2(_uniBuf[*indexPtr]==quote,@"Last character is not a '%c' but a '%c'",
(char)quote,(char)_uniBuf[*indexPtr]);
//ParserDebugLogBuffer(_uniBuf,stopIndex+1,*indexPtr,stopIndex+1);
NSDebugMLog(@"startIndex=%d *indexPtr=%d _uniBuf[*indexPtr]='%c'",
startIndex,*indexPtr,(char)_uniBuf[*indexPtr]);
LOGObjectFnStop();
}
//--------------------------------------------------------------------
/** parse and return the quoted string without quotes
indexPtr should point on the first quote
stopIndex should be the end of the string
when returning indexPtr point on the last quote.
Quoted substrings are handled
An exception is raised if the end quote is not found,...
**/
-(NSString*)_parseQuotedStringWithQuote:(unichar)quote
index:(int*)indexPtr
stopIndex:(int)stopIndex
{
NSString* string=nil;
int startIndex=0;
LOGObjectFnStart();
NSAssert2(_uniBuf[*indexPtr]==quote,@"First character is not a '%c' but a '%c'",
(char)quote,(char)_uniBuf[*indexPtr]);
//ParserDebugLogBuffer(_uniBuf,stopIndex+1,*indexPtr,stopIndex+1);
startIndex=(*indexPtr);
[self _skipQuotedStringWithQuote:quote
index:indexPtr
stopIndex:stopIndex];
NSAssert2(_uniBuf[*indexPtr]==quote,@"Last character is not a '%c' but a '%c'",
(char)quote,(char)_uniBuf[*indexPtr]);
//ParserDebugLogBuffer(_uniBuf,stopIndex+1,*indexPtr,stopIndex+1);
NSDebugMLog(@"startIndex=%d *indexPtr=%d _uniBuf[*indexPtr]='%c'",
startIndex,*indexPtr,(char)_uniBuf[*indexPtr]);
string=[NSString stringWithCharacters:_uniBuf+startIndex+1 // +1: skip begining quote
length:*indexPtr-startIndex-1]; // -1 because -1 for begining quote, -1 for ending quote +1 for length
NSDebugMLog(@"'string'='%@'",string);
LOGObjectFnStop();
return string;
}
//--------------------------------------------------------------------
/** parse and return a property string (either key or value), stoping when
ending0 or ending1 charaters is found or when stop index is reached
indexPtr should point on the begining of the string or on blanks before it.
stopIndex should be the end of the string
when returning indexPtr point on the ending char or on the character after
stopIndex if end of string is found
Quoted substrings are handled
An exception is raised if it find a problem (no end quote for quoted strings,...
It skip starting blank spaces
**/
-(NSString*)_parsePropertiesStringEndingWith:(unichar)ending0
or:(unichar)ending1
index:(int*)indexPtr
stopIndex:(int)stopIndex
{
NSString* string=nil;
int startIndex=0;
LOGObjectFnStart();
//ParserDebugLogBuffer(_uniBuf,stopIndex+1,*indexPtr,stopIndex+1);
while(*indexPtr<=stopIndex
&& _uniBuf[*indexPtr]==' ')
(*indexPtr)++;
startIndex=*indexPtr;
//ParserDebugLogBuffer(_uniBuf,stopIndex+1,startIndex,stopIndex+1);
if (*indexPtr<=stopIndex)
{
if (_uniBuf[*indexPtr]=='"'
|| _uniBuf[*indexPtr]=='\'')
{
//ParserDebugLogBuffer(_uniBuf,stopIndex+1,*indexPtr,stopIndex+1);
string=[self _parseQuotedStringWithQuote:_uniBuf[*indexPtr]
index:indexPtr
stopIndex:stopIndex];
NSDebugMLog(@"indexPtr=%d 'string'='%@'",*indexPtr,string);
(*indexPtr)++; // skip last quote
}
else
{
while(*indexPtr<=stopIndex
&& _uniBuf[*indexPtr]!=ending0
&& _uniBuf[*indexPtr]!=ending1)
{
if (_uniBuf[*indexPtr]=='"' || _uniBuf[*indexPtr]=='\'')
{
[self _skipQuotedStringWithQuote:_uniBuf[*indexPtr]
index:indexPtr
stopIndex:stopIndex];
(*indexPtr)++;// skip last quote
}
else
(*indexPtr)++;
};
NSDebugMLog(@"startIndex=%d stopIndex=%d *indexPtr=%d _uniBuf[*indexPtr]='%c'",
startIndex,stopIndex,*indexPtr,(char)_uniBuf[*indexPtr]);
if (*indexPtr>startIndex)
string=[NSString stringWithCharacters:_uniBuf+startIndex
length:*indexPtr-startIndex];
NSDebugMLog(@"'string'='%@'",string);
};
};
NSDebugMLog(@"'string'='%@'",string);
LOGObjectFnStop();
return string;
}
//--------------------------------------------------------------------
/** parse a tag properties
startIndex should point on the begining of the string
stopIndex should be the end of the string
Quoted strings are handled
An exception is raised if it find a problem (no end quote for quoted strings,...)
gsweb/wo case: start index and stopIndex must define a string that:
aa=bb c="ddd" name=element_name
OOG case: the string is like that:
element_name aa=bb c="ddd"
(for OOg, startIndex should point on the Element Name. No exception is raised
if it is not the case but you'll have problems later...)
**/
-(NSDictionary*)tagPropertiesForType:(GSWHTMLRawParserTagType)tagType
betweenIndex:(int)startIndex
andIndex:(int)stopIndex
{
NSMutableDictionary* properties=nil;
LOGObjectFnStart();
//ParserDebugLogBuffer(_uniBuf,stopIndex+1,startIndex,stopIndex+1);
if (stopIndex>=startIndex)
{
int index=startIndex;
if (tagType==GSWHTMLRawParserTagType_oog)
{
NSString* tagName=nil;
while(index<=stopIndex)
{
if (_uniBuf[index]==' ')
{
if ((index-1)>startIndex)
{
tagName=[NSString stringWithCharacters:_uniBuf+startIndex
length:index-startIndex+1];
NSDebugMLog(@"tagName=%@",tagName);
};
break;
}
};
if (!tagName && index>stopIndex)
{
tagName=[NSString stringWithCharacters:_uniBuf+startIndex
length:index-startIndex];
NSDebugMLog(@"tagName=%@",tagName);
};
if (tagName)
{
if (!properties)
properties=(NSMutableDictionary*)[NSMutableDictionary dictionary];
[properties setObject:tagName
forKey:@"name"];
};
};
// Skip blank
while(index<=stopIndex
&& _uniBuf[index]==' ')
index++;
while(index<=stopIndex)
{
NSString* key=[self _parsePropertiesStringEndingWith:'='
or:' '
index:&index
stopIndex:stopIndex];
NSDebugMLog(@"'key'='%@'",key);
// Skip blank
while(index<=stopIndex
&& _uniBuf[index]==' ')
index++;
if ([key length]>0)
{
key=[key lowercaseString];
if (!properties)
properties=(NSMutableDictionary*)[NSMutableDictionary dictionary];
if (index>stopIndex) // key without value
[properties setObject:@""
forKey:key];
else if (_uniBuf[index]=='=') // key=value
{
index++;
NSString* value=[self _parsePropertiesStringEndingWith:'='
or:' '
index:&index
stopIndex:stopIndex];
NSDebugMLog(@"'value'='%@'",value);
NSAssert(value,@"No value");
[properties setObject:value
forKey:key];
}
else // key without value
[properties setObject:@""
forKey:key];
};
};
};
NSDebugMLog(@"properties=%@",properties);
LOGObjectFnStop();
return properties;
};
//--------------------------------------------------------------------
/** Parse the html _string and call delegate methods
May raise exception.
**/
-(void)parseHTML
{
// Object obj = null;
LOGObjectFnStart();
NSDebugMLog(@"_string=%@",_string);
_length=[_string length];
_uniBuf = (unichar*)objc_malloc(sizeof(unichar)*(_length+1));
NS_DURING
{
[_string getCharacters:_uniBuf];
_index=0;
NSDebugMLog(@"index=%d length=%d",_index,_length);
//ParserDebugLogBuffer(_uniBuf,_length,_index,_length);
_textStartIndex=_index;
while(_index<_length)
{
//ParserDebugLogBuffer(_uniBuf,_length,_index,20);
switch(_uniBuf[_index])
{
case '<': // tagStart
{
int tagStartIndex=_index;
// skip '<'
_index++;
//ParserDebugLogBuffer(_uniBuf,_length,_index,20);
if (_index>=_length)
{
[NSException raise:NSInvalidArgumentException
format:@"Reached end of string when parsing tag opening at %@.",
[self lineAndColumnIndexesStringFromIndex:tagStartIndex]];
}
else
{
BOOL isClosingTag=NO;
GSWHTMLRawParserTagType tagType=GetTagType(_uniBuf,_length,&_index,&isClosingTag);
int tagPropertiesStartIndex=_index;
BOOL stopTag=NO;
_textStopIndex=tagStartIndex-1;
NSDebugMLog(@"tagType=%d isClosingTag=%s _textStartIndex=%d",tagType,(isClosingTag ? "YES" : "NO"),_textStartIndex);
if (_parserIsDynamicTagType(tagType))
{
// Find tag End;
while(_index<_length
&& _uniBuf[_index]!='>')
_index++;
//ParserDebugLogBuffer(_uniBuf,_length,_index,20);
if (_uniBuf[_index]!='>')
{
[NSException raise:NSInvalidArgumentException
format:@"Reached end of string searching for tag end. Tag started at %@.",
[self lineAndColumnIndexesStringFromIndex:tagStartIndex]];
}
else
{
int tagStopIndex=_index;
int tagPropertiesStopIndex=_index;
NSDebugMLog(@"tagStartIndex=%d tagStopIndex=%d _textStartIndex=%d _textStopIndex=%d _length=%d _index=%d",
tagStartIndex,tagStopIndex,_textStartIndex,_textStopIndex,_length,_index);
if (isClosingTag)
{
[self stopDynamicTagOfType:tagType
withTemplateInfo:[self lineAndColumnIndexesStringFromIndex:tagStartIndex]];
}
else
{
NSString* tagPropertiesString=nil;
if (_uniBuf[_index-1]=='/')
{
stopTag=YES;
tagPropertiesStopIndex--;
};
tagPropertiesString=[NSString stringWithCharacters:_uniBuf+tagPropertiesStartIndex
length:tagPropertiesStopIndex-tagPropertiesStartIndex];
NSDebugMLog(@"tagPropertiesString='%@'",tagPropertiesString);
NSDictionary* tagProperties=[self tagPropertiesForType:tagType
betweenIndex:tagPropertiesStartIndex
andIndex:tagPropertiesStopIndex-1];
NSDebugMLog(@"tagProperties='%@'",tagProperties);
[self startDynamicTagOfType:tagType
withProperties:tagProperties
templateInfo:[self lineAndColumnIndexesStringFromIndex:tagStartIndex]];
if (stopTag)
[self stopDynamicTagOfType:tagType
withTemplateInfo:[self lineAndColumnIndexesStringFromIndex:tagStartIndex]];
}
_index++;
_textStartIndex=_index;
NSDebugMLog(@"_textStartIndex=%d _textStopIndex=%d _length=%d _index=%d",
_textStartIndex,_textStopIndex,_length,_index);
};
}
else if (_parserIsCommentTagType(tagType))
{
BOOL foundCommentEnd=NO;
// Find tag End;
while(!foundCommentEnd && _index<_length)
{
if (_uniBuf[_index]=='>'
&&_uniBuf[_index-1]=='-'
&& _uniBuf[_index-2]=='-')
{
foundCommentEnd=YES;
}
else
_index++;
};
if (!foundCommentEnd)
{
[NSException raise:NSInvalidArgumentException
format:@"Reached end of string searching for comment end. Comment started at %@.",
[self lineAndColumnIndexesStringFromIndex:tagStartIndex]];
}
else
{
NSString* commentString=[NSString stringWithCharacters:_uniBuf+tagPropertiesStartIndex
length:_index-tagPropertiesStartIndex-2]; //-2 for last --
[self didParseCommentWithContentString:commentString];
_index++;
_textStartIndex=_index;
NSDebugMLog(@"_textStartIndex=%d _textStopIndex=%d _length=%d _index=%d",
_textStartIndex,_textStopIndex,_length,_index);
};
};
};
};
break;
case '\\':// escape
_index++;
break;
default:
_index++;
break;
};
};
_textStopIndex=_length-1;
[self didParseText];
//ParserDebugLogBuffer(_uniBuf,_length,_index,20);
}
NS_HANDLER
{
if (_uniBuf)
{
objc_free(_uniBuf);
_uniBuf=NULL;
};
[localException raise];
};
NS_ENDHANDLER;
LOGObjectFnStop();
};
@end

View file

@ -0,0 +1,47 @@
/** GSWHTMLTemplateParser - <title>GSWeb: Class GSWHTMLTemplateParser</title>
Copyright (C) 2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 2004
$Revision$
$Date$
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
// $Id$
#ifndef _GSWHTMLTemplateParser_h__
#define _GSWHTMLTemplateParser_h__
//====================================================================
/** HTML raw parser **/
@interface GSWHTMLTemplateParser : GSWTemplateParser<GSWTemplateParserDelegate>
{
GSWTemporaryElement* _currentElement; /** Current 'Tag' (not retained) **/
}
@end
#endif //_GSWHTMLTemplateParser_h__

View file

@ -0,0 +1,216 @@
/** GSWHTMLTemplateParser.m - <title>GSWeb: Class GSWHTMLTemplateParser</title>
Copyright (C) 2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 2004
$Revision$
$Date$
$Id$
<abstract></abstract>
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
#include "config.h"
RCS_ID("$Id$")
#include "GSWeb.h"
#include "GSWHTMLRawParser.h"
//====================================================================
@implementation GSWHTMLTemplateParser
//--------------------------------------------------------------------
-(id)init
{
if ((self=[super init]))
{
NSDebugMLog(@"_currentElement=%@",_currentElement);
}
return self;
}
//--------------------------------------------------------------------
-(GSWElement*)parseHTML
{
GSWElement* template=nil;
LOGObjectFnStart();
if ([_string length])
{
GSWHTMLRawParser* htmlRawParser = [GSWHTMLRawParser parserWithDelegate:self
htmlString:_string];
[htmlRawParser parseHTML];
NSDebugMLog(@"_currentElement=%@",_currentElement);
if ([_currentElement parentElement])
{
[NSException raise:NSInvalidArgumentException
format:@"Missing dynamic tag end after reaching end of template. Tag name is '%@'.",
[_currentElement name]];
}
else
template=[_currentElement template];
};
LOGObjectFnStop();
return template;
};
//--------------------------------------------------------------------
-(GSWElement*)parse
{
GSWElement* template=nil;
LOGObjectFnStart();
[self parseDeclarations];
_currentElement = [GSWTemporaryElement temporaryElement];
template=[self parseHTML];
LOGObjectFnStop();
return template;
}
//--------------------------------------------------------------------
//TEMP should be removed later
-(GSWElement*)template
{
return [self parse];
};
//--------------------------------------------------------------------
/** Called by parser when it has parsed raw text
Creates a GSWHTMLBareString element with the text
**/
-(void)parser:(GSWBaseParser*)parser
didParseText:(NSString*)text
{
GSWHTMLBareString* element=nil;
LOGObjectFnStart();
NSDebugMLog(@"text=%@",text);
element = [GSWHTMLBareString elementWithString:text];
[_currentElement addChildElement:element];
LOGObjectFnStop();
}
//--------------------------------------------------------------------
/** Called by parser when it has opened a dynamic tag
Creates a GSWTemporaryElement element, waiting for tag end
**/
-(void) parser:(GSWBaseParser*)parser
didParseOpeningDynamicTagOfType:(GSWHTMLRawParserTagType)tagType
withProperties:(NSDictionary*)tagProperties
templateInfo:(NSString*)templateInfo
{
LOGObjectFnStart();
NSDebugMLog(@"tagProperties=%@",tagProperties);
NSDebugMLog(@"templateInfo=%@",templateInfo);
NSDebugMLog(@"_currentElement=%@",_currentElement);
_currentElement = [GSWTemporaryElement temporaryElementOfType:tagType
withProperties:tagProperties
templateInfo:templateInfo
parent:_currentElement];
NSDebugMLog(@"_currentElement=%@",_currentElement);
LOGObjectFnStop();
}
//--------------------------------------------------------------------
/** Called by parser when it has closed a dynamic tag
Creates a dynamic element from current temporary element element
**/
-(void) parser:(GSWBaseParser*)parser
didParseClosingDynamicTagOfType:(GSWHTMLRawParserTagType)tagType
withTemplateInfo:(NSString*)templateInfo
{
GSWTemporaryElement* parent=nil;
LOGObjectFnStart();
NSDebugMLog(@"_currentElement=%@",_currentElement);
parent=[_currentElement parentElement];
NSDebugMLog(@"parent=%@",parent);
if(!parent)
{
[NSException raise:NSInvalidArgumentException
format:@"Unmatched dynamic tag end %@. %@.",
templateInfo];
}
else
{
GSWElement* element = nil;
element = [_currentElement dynamicElementWithDeclarations:_declarations
languages:_languages];
NSDebugMLog(@"element=%@",element);
NSAssert2(element,@"No element for %@ with declarations %@",_currentElement,_declarations);
[parent addChildElement:element];
_currentElement = parent;
NSDebugMLog(@"_currentElement=%@",_currentElement);
}
LOGObjectFnStop();
}
//--------------------------------------------------------------------
/** Called by parser when it has parsed a comment
Creates a GSWHTMLComment with the comment text
**/
-(void) parser:(GSWBaseParser*)parser
didParseComment:(NSString*)text
{
GSWHTMLComment* element=nil;
LOGObjectFnStart();
NSDebugMLog(@"_currentElement=%@",_currentElement);
NSDebugMLog(@"string=%@",text);
element = [GSWHTMLComment elementWithString:text];
NSDebugMLog(@"element=%@",element);
[_currentElement addChildElement:element];
NSDebugMLog(@"_currentElement=%@",_currentElement);
LOGObjectFnStop();
}
@end

View file

@ -0,0 +1,100 @@
/** GSWTemporaryElement.h - <title>GSWeb: Class GSWRequest</title>
Copyright (C) 2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 2004
$Revision$
$Date$
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
// $Id$
#ifndef _GSWTemporaryElement_h__
#define _GSWTemporaryElement_h__
//====================================================================
/** Temporary element which will be converted to a dynamic element **/
@interface GSWTemporaryElement: GSWElement
{
NSDictionary* _properties; /** Tag properties **/
GSWTemporaryElement* _parent; /** Parent tag (not retained) **/
NSMutableArray* _children; /** Children **/
NSString* _templateInfo; /** Parser/Template information (tag position,....) **/
};
+(GSWTemporaryElement*)temporaryElement;
+(GSWTemporaryElement*)temporaryElementOfType:(GSWHTMLRawParserTagType)tagType
withProperties:(NSDictionary*)tagProperties
templateInfo:(NSString*)templateInfo
parent:(GSWTemporaryElement*)parent;
-(id)initWithType:(GSWHTMLRawParserTagType)tagType
withProperties:(NSDictionary*)properties
templateInfo:(NSString*)templateInfo
parent:(GSWTemporaryElement*)parent;
/** adds element to children **/
-(void)addChildElement:(GSWElement*)element;
/** Returns parent element **/
-(GSWTemporaryElement*)parentElement;
/** Returns template information **/
-(NSString*)templateInfo;
/** Create a GSWElement representing child elements tree
**/
-(GSWElement*)template;
/** Return Element Name, taken from properties
nil if none is found
**/
-(NSString*)name;
/** Returns real dynamic element usinf declarations to find element type
Raise an exception if element name is not found or if no declaration is
found for that element
**/
-(GSWElement*)dynamicElementWithDeclarations:(NSDictionary*)declarations
languages:(NSArray*)languages;
/** Returns real dynamic element using declaration
May raise exception if element can't be created
**/
-(GSWElement*)_elementWithDeclaration:(GSWDeclaration*)declaration
name:(NSString*)name
properties:(NSDictionary*)properties
template:(GSWElement*)template
languages:(NSArray*)languages;
@end
#endif //_GSWTemporaryElement_h__

View file

@ -0,0 +1,397 @@
/** GSWTemporaryElement.m - <title>GSWeb: Class GSWTemporaryElement</title>
Copyright (C) 2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 2004
$Revision$
$Date$
$Id$
<abstract></abstract>
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
#include "config.h"
RCS_ID("$Id$")
#include "GSWeb.h"
//====================================================================
@implementation GSWTemporaryElement
//--------------------------------------------------------------------
+(GSWTemporaryElement*)temporaryElement
{
return [[[self alloc]init]autorelease];
}
//--------------------------------------------------------------------
+(GSWTemporaryElement*)temporaryElementOfType:(GSWHTMLRawParserTagType)tagType
withProperties:(NSDictionary*)properties
templateInfo:(NSString*)templateInfo
parent:(GSWTemporaryElement*)parent
{
return [[[self alloc]initWithType:tagType
withProperties:properties
templateInfo:templateInfo
parent:parent]autorelease];
};
//--------------------------------------------------------------------
-(id)initWithType:(GSWHTMLRawParserTagType)tagType
withProperties:(NSDictionary*)properties
templateInfo:(NSString*)templateInfo
parent:(GSWTemporaryElement*)parent
{
LOGObjectFnStart();
if ((self=[self init]))
{
_parent=parent;
ASSIGNCOPY(_properties,properties);
ASSIGNCOPY(_templateInfo,templateInfo);
};
LOGObjectFnStop();
return self;
};
//--------------------------------------------------------------------
-(void)dealloc
{
DESTROY(_properties);
DESTROY(_children);
DESTROY(_templateInfo);
[super dealloc];
};
//--------------------------------------------------------------------
-(NSString*)description
{
return [NSString stringWithFormat:@"<%s %p: properties=%@ parent=%p children count=%d templateInfo=%@>",
object_get_class_name(self),
(void*)self,
_properties,
_parent,
[_children count],
_templateInfo];
};
//--------------------------------------------------------------------
/** adds element to children **/
-(void)addChildElement:(GSWElement*)element
{
LOGObjectFnStart();
if (!_children)
_children=[NSMutableArray new];
[_children addObject:element];
LOGObjectFnStart();
};
//--------------------------------------------------------------------
/** Returns parent element **/
-(GSWTemporaryElement*)parentElement
{
LOGObjectFnStart();
LOGObjectFnStop();
return _parent;
};
//--------------------------------------------------------------------
/** Returns template information **/
-(NSString*)templateInfo
{
LOGObjectFnStart();
LOGObjectFnStop();
return _templateInfo;
}
//--------------------------------------------------------------------
/** Create a GSWElement representing child elements tree
**/
-(GSWElement*)template
{
GSWElement* template = nil;
NSMutableArray* elementChildren=nil;
int childrenCount=0;
LOGObjectFnStart();
NSDebugMLog(@"self=%@",self);
NSDebugMLog(@"_children=%@",_children);
// Is there children ?
childrenCount=[_children count];
if (childrenCount>0)
{
// Only one ? So we don't have to make 'complex' processing
if (childrenCount==1)
{
elementChildren=_children;
}
else
{
// More than one child: try to concatenate BareStrings
NSMutableString* bareStringText=nil;
int i=0;
for(i=0;i<childrenCount;i++)
{
GSWElement* element=[_children objectAtIndex:i];
NSDebugMLog(@"element=%@",element);
if ([element isKindOfClass:[GSWHTMLBareString class]])// Concatenate BareStrings
{
NSDebugMLog(@"bareStringText=%@",bareStringText);
if (bareStringText)
{
[bareStringText appendString:[(GSWHTMLBareString*)element string]];
element=nil;
}
else if (i+1<childrenCount
&& [[_children objectAtIndex:i+1] isKindOfClass:[GSWHTMLBareString class]])
{
bareStringText=[NSMutableString stringWithString:[(GSWHTMLBareString*)element string]];
element=nil;
};
NSDebugMLog(@"element=%@",element);
}
else
{
if([bareStringText length]>0)
{
GSWHTMLBareString* bareString = [GSWHTMLBareString elementWithString:bareStringText];
[bareStringText setString:@""];
NSDebugMLog(@"bareString=%@",bareString);
if (!elementChildren)
elementChildren=(NSMutableArray*)[NSMutableArray array];
[elementChildren addObject:bareString];
};
};
if (element)
{
if (!elementChildren)
elementChildren=(NSMutableArray*)[NSMutableArray array];
[elementChildren addObject:element];
};
};
};
NSDebugMLog(@"elementChildren=%@",elementChildren);
if ([elementChildren count]==1)
{
template=[elementChildren lastObject];
}
else
{
template=[GSWHTMLStaticGroup elementWithContentElements:elementChildren];
};
};
NSDebugMLog(@"template=%@",template);
LOGObjectFnStop();
return template;
}
//--------------------------------------------------------------------
/** Return Element Name, taken from properties
nil if none is found
**/
-(NSString*)name
{
NSString* name=nil;
LOGObjectFnStart();
name=[_properties objectForKey:@"name"];
NSDebugMLog(@"name=%@",name);
NSDebugMLog(@"_properties=%@",_properties);
LOGObjectFnStop();
return name;
};
//--------------------------------------------------------------------
/** Returns real dynamic element usinf declarations to find element type
Raise an exception if element name is not found or if no declaration is
found for that element
**/
-(GSWElement*)dynamicElementWithDeclarations:(NSDictionary*)declarations
languages:(NSArray*)languages
{
GSWElement* element=nil;
GSWElement* template = nil;
NSString* name=nil;
GSWDeclaration* elementDeclaration=nil;
LOGObjectFnStart();
NSDebugMLog(@"self=%@",self);
NSDebugMLog(@"declarations=%@",declarations);
NSDebugMLog(@"languages=%@",languages);
// First, get children template
template = [self template];
NSDebugMLog(@"template=%@",template);
// Get element name
name=[self name];
NSDebugMLog(@"name=%@",name);
if (!name)
{
[NSException raise:NSInvalidArgumentException
format:@"No element name for dynamic tag %@. %@",
self,_templateInfo];
}
else
{
elementDeclaration = [declarations objectForKey:name];
NSDebugMLog(@"elementDeclaration=%@",elementDeclaration);
if (!elementDeclaration)
{
[NSException raise:NSInvalidArgumentException
format:@"No declaration for element named '%@'. Declarations: %@. %@",
name,declarations,_templateInfo];
}
else
{
element=[self _elementWithDeclaration:elementDeclaration
name:name
properties:_properties
template:template
languages:languages];
NSDebugMLog(@"element=%@",element);
};
};
LOGObjectFnStop();
return element;
}
//--------------------------------------------------------------------
/** Returns real dynamic element using declaration
May raise exception if element can't be created
**/
-(GSWElement*)_elementWithDeclaration:(GSWDeclaration*)declaration
name:(NSString*)name
properties:(NSDictionary*)properties
template:(GSWElement*)template
languages:(NSArray*)languages
{
GSWElement* element = nil;
LOGObjectFnStart();
NSDebugMLog(@"declaration=%@",declaration);
NSDebugMLog(@"name=%@",name);
NSDebugMLog(@"properties=%@",properties);
NSDebugMLog(@"template=%@",template);
if (!declaration)
{
[NSException raise:NSInvalidArgumentException
format:@"No declaration for element named '%@'. %@",
name,_templateInfo];
}
else
{
NSString* elementType=[declaration type];
NSDebugMLog(@"elementType=%@",elementType);
if ([elementType length]==0)
{
[NSException raise:NSInvalidArgumentException
format:@"No class name for named '%@' with declaration: %@. %@",
name,declaration,_templateInfo];
}
else
{
Class elementClass = NSClassFromString(elementType);
NSDebugMLog(@"elementClass=%@",elementClass);
NSDictionary* associations=[declaration associations];
if ([properties count]>0)
{
NSEnumerator* _propertiesEnum = [properties keyEnumerator];
NSMutableDictionary* addedAssoc=nil;
NSString* key=nil;
NSString* value=nil;
while ((key = [_propertiesEnum nextObject]))
{
if (![key isEqualToString:@"name"] && ![associations objectForKey:key])
{
if (!addedAssoc)
addedAssoc=(NSMutableDictionary*)[NSMutableDictionary dictionary];
value=[properties objectForKey:key];
NSDebugMLog(@"key=%@ value=%@",key,value);
[addedAssoc setObject:[GSWAssociation associationWithValue:value]
forKey:key];
};
};
if (addedAssoc)
{
associations=[associations dictionaryByAddingEntriesFromDictionary:addedAssoc];
};
};
// Create element
element=[GSWApp dynamicElementWithName:elementType
associations:associations
template:template
languages:languages];
NSDebugMLog(@"element=%@",element);
if (element)
[element setDeclarationName:[declaration name]];
else
{
[NSException raise:NSInvalidArgumentException
format:@"Can't create element named '%@' with declaration: %@. %@",
name,declaration,_templateInfo];
};
};
};
NSDebugMLog(@"element=%@",element);
LOGObjectFnStop();
return element;
}
@end