00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "gdlhandler.h"
00020
00021 #include "gluonobject.h"
00022 #include "gluonobjectfactory.h"
00023 #include "debughelper.h"
00024
00025 #include <QtCore/QStringList>
00026
00027 using namespace GluonCore;
00028
00029 template<> GDLHandler* Singleton<GDLHandler>::m_instance = 0;
00030
00031 GDLHandler::GDLHandler()
00032 {
00033 }
00034
00035 GDLHandler::~GDLHandler()
00036 {
00037 }
00038
00039 GluonObject *
00040 GDLHandler::instantiateObject( QString className )
00041 {
00042 GluonObject* newObject = GluonObjectFactory::instance()->instantiateObjectByName( className );
00043 if( !newObject )
00044 newObject = new GluonObject();
00045
00046 return newObject;
00047 }
00048
00049 GluonObject *
00050 GDLHandler::createObject( QStringList objectStringList, QObject* parent )
00051 {
00052 DEBUG_BLOCK
00053 GluonObject* createdObject = 0;
00054 int index = 0;
00055 QString currentPropertyName;
00056 foreach( const QString & item, objectStringList )
00057 {
00058 switch( index )
00059 {
00060 case 0:
00061
00062 createdObject = instantiateObject( item );
00063 createdObject->setParent( parent );
00064
00065 break;
00066 case 1:
00067
00068 createdObject->setName( item );
00069 break;
00070 default:
00071
00072 if( currentPropertyName.isEmpty() )
00073 {
00074 if( item.startsWith( '{' ) )
00075 {
00076
00077 QList<GluonObject*> childList = parseGDL( item, createdObject );
00078 }
00079 else
00080 {
00081 currentPropertyName = item;
00082 }
00083 }
00084 else
00085 {
00086
00087 createdObject->setPropertyFromString( currentPropertyName, item );
00088 currentPropertyName.clear();
00089 }
00090 break;
00091 }
00092 ++index;
00093 }
00094 return createdObject;
00095 }
00096
00097 QList<QStringList>
00098 GDLHandler::tokenizeObject( QString objectString )
00099 {
00100 QList<QStringList> tokenizedObject;
00101
00102 bool inItem = false;
00103 bool inObjectDefinition = false;
00104 bool inObjectName = false;
00105 bool inObjectType = false;
00106
00107 bool inPropertyName = false;
00108 bool inPropertyValue = false;
00109 bool multilineProperty = false;
00110 bool inChild = false;
00111 bool childEnded = false;
00112
00113 bool beingEscaped = false;
00114 int extraBracketCounter = 0;
00115 QString currentString;
00116 QStringList currentItem;
00117
00118 QString::const_iterator i;
00119 for( i = objectString.begin(); i != objectString.end(); ++i )
00120 {
00121 if( !inItem )
00122 {
00123 if( i->isSpace() )
00124 {
00125
00126 }
00127 else if( i->toLower() == '{' )
00128 {
00129 inItem = true;
00130 }
00131 }
00132 else
00133 {
00134 if( !inPropertyValue && !inPropertyName && !inChild && !inObjectDefinition )
00135 {
00136 if( !currentString.isEmpty() )
00137 {
00138 currentItem.append( currentString.trimmed() );
00139 currentString.clear();
00140 }
00141
00142
00143 if( !i->isSpace() && (*i) != '#' )
00144 {
00145 if( i->toLower() == '}' )
00146 {
00147
00148
00149 QStringList theItem( currentItem );
00150 tokenizedObject.append( theItem );
00151 currentItem.clear();
00152 }
00153 else if( i->toLower() == '{' )
00154 {
00155
00156
00157 inChild = true;
00158 }
00159 else
00160 {
00161
00162 inObjectDefinition = true;
00163 }
00164 }
00165 }
00166
00167 if( inObjectDefinition )
00168 {
00169 if( !inPropertyName && !inObjectName && !inObjectType )
00170 {
00171
00172 if( !i->isSpace() )
00173 inObjectType = true;
00174 }
00175
00176 if( inObjectType )
00177 {
00178 if( i->toLower() == '(' )
00179 {
00180 currentItem.append( currentString.trimmed() );
00181 currentString.clear();
00182 inObjectType = false;
00183 inObjectName = true;
00184 }
00185 else
00186 {
00187 currentString += i->unicode();
00188 }
00189 }
00190 else if( inObjectName )
00191 {
00192 if( i->toLower() == ')' )
00193 {
00194 currentItem.append( currentString.trimmed() );
00195 currentString.clear();
00196 inObjectName = false;
00197 inPropertyName = true;
00198 }
00199 else
00200 {
00201 currentString += i->unicode();
00202 }
00203 }
00204 else if( inPropertyName )
00205 {
00206 if( !i->isSpace() )
00207 inObjectDefinition = false;
00208 }
00209 }
00210 else if( inChild )
00211 {
00212 if( childEnded )
00213 {
00214 if( !i->isSpace() )
00215 {
00216 inChild = false;
00217 }
00218 }
00219 else
00220 {
00221 if( i->toLower() == '\\' && !beingEscaped )
00222 {
00223 beingEscaped = true;
00224 }
00225 else
00226 {
00227 currentString += i->unicode();
00228 if( !beingEscaped )
00229 {
00230 if( i->toLower() == '{' )
00231 {
00232 ++extraBracketCounter;
00233 }
00234
00235 if( i->toLower() == '}' )
00236 {
00237 --extraBracketCounter;
00238 if( extraBracketCounter == -1 )
00239 {
00240
00241 extraBracketCounter = 0;
00242 childEnded = true;
00243 inPropertyName = true;
00244 currentItem.append( '{' + currentString.trimmed() );
00245 currentString.clear();
00246 }
00247 }
00248 }
00249 else
00250 {
00251 beingEscaped = false;
00252 }
00253 }
00254 }
00255 }
00256
00257 if( !inObjectDefinition && !inChild )
00258 {
00259 if( inPropertyName )
00260 {
00261
00262 if( i->toLower() == '{' )
00263 {
00264 inChild = true;
00265 childEnded = false;
00266 }
00267 else if( i->toLower() == '}' )
00268 {
00269 inPropertyName = false;
00270
00271 --i;
00272 }
00273 else if( !i->isSpace() )
00274 {
00275 currentString += i->unicode();
00276 }
00277 else
00278 {
00279 currentItem.append( currentString.trimmed() );
00280 currentString.clear();
00281 inPropertyName = false;
00282 inPropertyValue = true;
00283 }
00284 }
00285 else if( inPropertyValue )
00286 {
00287 if( *i == '<' && *(i + 1) == '<' && *(i + 2) == '<' )
00288 {
00289 multilineProperty = !multilineProperty;
00290 i = i + 2;
00291 }
00292 else if( i->toLower() == '\\' && !beingEscaped )
00293 {
00294 beingEscaped = true;
00295 }
00296 else
00297 {
00298
00299 currentString += i->unicode();
00300 if( !beingEscaped && !multilineProperty && i->toLower() == ')' )
00301 {
00302 currentItem.append( currentString.trimmed() );
00303 currentString.clear();
00304 inPropertyValue = false;
00305 inPropertyName = true;
00306
00307
00308 forever
00309 {
00310 if( i == objectString.end() )
00311 break;
00312 ++i;
00313 if( i->isSpace() )
00314 continue;
00315 --i;
00316 break;
00317 }
00318 }
00319 beingEscaped = false;
00320 }
00321 }
00322 }
00323 }
00324 }
00325
00326 return tokenizedObject;
00327 }
00328
00329 QList<GluonObject*>
00330 GDLHandler::parseGDL( const QString parseThis, QObject* parent )
00331 {
00332 QList<GluonObject*> thisObjectList;
00333
00334 QList<QStringList> tokenizedObject = tokenizeObject( parseThis );
00335
00336 foreach( const QStringList & item, tokenizedObject )
00337 {
00338 GluonObject* currentObject = createObject( item, parent );
00339 thisObjectList.append( currentObject );
00340 currentObject->sanitize();
00341 }
00342
00343 return thisObjectList;
00344 }
00345
00346 QString
00347 GDLHandler::serializeGDL( QList<const GluonObject*> serializeThis )
00348 {
00349 QString serializedData;
00350
00351 foreach( const GluonObject * theObject, serializeThis )
00352 serializedData += theObject->toGDL();
00353
00354 return serializedData;
00355 }
00356
00357 #include "gdlhandler.moc"