00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <libCMMLParse/CMMLParser.h>
00037 #include <libCMMLParse/xtag.h>
00038
00039 #include <libCMMLTags/libCMMLTags.h>
00040 #include <libilliCore/StringHelper.h>
00041
00042 #include <fstream>
00043
00044
00045 using namespace std;
00046
00047
00048
00049
00050
00051 CMMLParser::CMMLParser(void)
00052 {
00053 }
00054
00055 CMMLParser::~CMMLParser(void)
00056 {
00057 }
00058
00059 bool CMMLParser::parseDocFromFile(wstring inFilename, C_CMMLDoc* outCMMLDoc)
00060 {
00061
00062
00063 bool locReturnValue = false;
00064
00065
00066 if (!outCMMLDoc) {
00067 return false;
00068 }
00069
00070
00071
00072 fstream locFile;
00073
00074 locFile.open(StringHelper::toNarrowStr(inFilename).c_str(), ios_base::in | ios_base::binary);
00075
00076 if (!locFile.is_open()) {
00077
00078
00079 return false;
00080 }
00081
00082
00083 locFile.seekg(0, ios::end);
00084 size_t locCMMLFileSize = locFile.tellg();
00085 locFile.clear();
00086
00087
00088 locFile.seekg(0);
00089
00090 unsigned short BUFFER_SIZE = 8192;
00091 char *locBuffer = new char[locCMMLFileSize];
00092 size_t locBytesRead = 0;
00093
00094 while (!locFile.eof()) {
00095 locFile.read(locBuffer + locBytesRead, BUFFER_SIZE);
00096 locBytesRead = locFile.gcount();
00097 }
00098
00099 locFile.close();
00100
00101
00102 wstring locCMMLFileWString = StringHelper::toWStr(locBuffer);
00103
00104
00105
00106
00107 size_t locCMMLTagIndex = locCMMLFileWString.find(L"<cmml", 0);
00108 if (locCMMLTagIndex != string::npos) {
00109 locCMMLFileWString = locCMMLFileWString.substr(locCMMLTagIndex);
00110 }
00111
00112
00113 C_CMMLRootTag* locRootTag = new C_CMMLRootTag;
00114 locReturnValue = parseCMMLRootTag(locCMMLFileWString, locRootTag);
00115 if (locReturnValue) {
00116
00117 outCMMLDoc->setRoot(locRootTag);
00118 } else {
00119
00120 outCMMLDoc = NULL;
00121 }
00122
00123
00124 delete [] locBuffer;
00125
00126 return locReturnValue;
00127 }
00128
00129
00130 bool CMMLParser::parseCMMLRootTag(wstring inCMMLRootText, C_CMMLRootTag* outCMMLRoot)
00131 {
00132
00133
00134 bool locReturnValue = false;
00135
00136
00137 if (!outCMMLRoot) {
00138 return false;
00139 }
00140
00141
00142 string locCMMLRootText = StringHelper::toNarrowStr(inCMMLRootText);
00143
00144
00145 XTag *locRootParser = NULL;
00146 locRootParser = xtag_new_parse(locCMMLRootText.c_str(), (int)locCMMLRootText.size());
00147 if (locRootParser) {
00148
00149 if (strcmp(xtag_get_name(locRootParser), "cmml") == 0) {
00150
00151 locReturnValue = parseRootTag(locRootParser, outCMMLRoot);
00152 }
00153 }
00154
00155 if (locRootParser) {
00156 xtag_free(locRootParser);
00157 }
00158
00159 return locReturnValue;
00160 }
00161
00162
00163 bool CMMLParser::parseClipTag(wstring inClipText, C_ClipTag* outClip)
00164 {
00165
00166
00167 bool locReturnValue = false;
00168
00169
00170 if (!outClip) {
00171 return false;
00172 }
00173
00174
00175 string locClipText = StringHelper::toNarrowStr(inClipText);
00176
00177
00178 XTag *locClipParser = NULL;
00179 locClipParser = xtag_new_parse(locClipText.c_str(), (int)locClipText.size());
00180 if (locClipParser) {
00181
00182 if (strcmp(xtag_get_name(locClipParser), "clip") == 0) {
00183
00184 locReturnValue = parseClipTag(locClipParser, outClip);
00185 }
00186 }
00187
00188 if (locClipParser) {
00189 xtag_free(locClipParser);
00190 }
00191
00192 return locReturnValue;
00193 }
00194
00195
00196 bool CMMLParser::parseHeadTag(wstring inHeadText, C_HeadTag* outHead)
00197 {
00198
00199
00200 bool locReturnValue = false;
00201
00202
00203 if (!outHead) {
00204 return false;
00205 }
00206
00207
00208 string locHeadText = StringHelper::toNarrowStr(inHeadText);
00209
00210
00211 XTag *locHeadParser = NULL;
00212 locHeadParser = xtag_new_parse(locHeadText.c_str(), (int)locHeadText.size());
00213 if (locHeadParser) {
00214 if (strcmp(xtag_get_name(locHeadParser), "head") == 0) {
00215 locReturnValue = parseHeadTag(locHeadParser, outHead);
00216 }
00217 }
00218
00219 if (locHeadParser) {
00220 xtag_free(locHeadParser);
00221 }
00222
00223 return locReturnValue;
00224 }
00225
00226
00227
00228
00229 #define XTAG_PARSE_INTO(tagParser, parseMethod, TagType, parentTagSetter, parentTag) \
00230 { \
00231 TagType *locTag = new TagType; \
00232 if (!parseMethod(tagParser, locTag)) { \
00233 return false; \
00234 } \
00235 parentTag->parentTagSetter(locTag); \
00236 };
00237
00238 #define XTAG_SET_ATTRIBUTE(tagParser, attributeName, tag, attributeSetter) \
00239 { \
00240 const char *locAttributeCString = xtag_get_attribute(tagParser, attributeName); \
00241 if (locAttributeCString) { \
00242 tag->attributeSetter(StringHelper::toWStr(locAttributeCString)); \
00243 \
00244 } \
00245 };
00246
00247 #define XTAG_REQUIRED_ATTRIBUTE(tagParser, attributeName, tag) \
00248 { \
00249 const char *locAttributeCString = xtag_get_attribute(tagParser, attributeName); \
00250 if (!locAttributeCString) { \
00251 return false; \
00252 } else { \
00253 \
00254 } \
00255 };
00256
00257 #define XTAG_PARSE_CHILD(parentParser, tagName, tagParser, tagType, setterMethod, parentTag) \
00258 { \
00259 XTag *locParser = NULL; \
00260 locParser = xtag_first_child(parentParser, tagName); \
00261 if (locParser) { \
00262 XTAG_PARSE_INTO(locParser, tagParser, tagType, setterMethod, parentTag); \
00263 } \
00264 };
00265
00266 #define XTAG_EXACTLY_ONE_CHILD(parentParser, tagName) \
00267 { \
00268 XTag *locParser = xtag_first_child(parentParser, tagName); \
00269 if (locParser != NULL) { \
00270 \
00271 locParser = xtag_next_child(parentParser, tagName); \
00272 if (locParser) { \
00273 \
00274 return false; \
00275 } \
00276 } else { \
00277 \
00278 return false; \
00279 } \
00280 };
00281
00282 #define XTAG_PARSE_LIST(TagType, listTagName, tagParser, parentParser, parentTag, parentGetListMethod) \
00283 { \
00284 XTag *locTagListParser = NULL; \
00285 for ( locTagListParser = xtag_first_child(parentParser, listTagName); \
00286 locTagListParser != NULL; \
00287 locTagListParser = xtag_next_child(parentParser, listTagName)) { \
00288 XTAG_PARSE_INTO(locTagListParser, tagParser, TagType, addTag, parentTag->parentGetListMethod()); \
00289 } \
00290 };
00291
00292 #define XTAG_SET_CDATA(tagParser, tag) \
00293 { \
00294 const char *locCData = xtag_get_pcdata(tagParser); \
00295 if (locCData) { \
00296 tag->setText(StringHelper::toWStr(locCData)); \
00297 \
00298 } \
00299 };
00300
00301
00302
00303
00304 bool CMMLParser::parseStreamTag(XTag* inStreamParser, C_StreamTag* outStream)
00305 {
00306 XTAG_SET_ATTRIBUTE(inStreamParser, "id", outStream, setId);
00307 XTAG_SET_ATTRIBUTE(inStreamParser, "timebase", outStream, setTimebase);
00308 XTAG_SET_ATTRIBUTE(inStreamParser, "utc", outStream, setUtc);
00309
00310 XTAG_PARSE_LIST(C_ImportTag, "import", parseImportTag,
00311 inStreamParser, outStream, importList);
00312
00313 return true;
00314 }
00315
00316
00317 bool CMMLParser::parseRootTag(XTag* inCMMLRootParser, C_CMMLRootTag* outCMMLRoot)
00318 {
00319 XTAG_SET_ATTRIBUTE(inCMMLRootParser, "id", outCMMLRoot, setId);
00320
00321 XTAG_EXACTLY_ONE_CHILD(inCMMLRootParser, "head");
00322 XTAG_PARSE_CHILD(inCMMLRootParser, "head", parseHeadTag, C_HeadTag, setHead, outCMMLRoot);
00323 XTAG_PARSE_CHILD(inCMMLRootParser, "stream", parseStreamTag, C_StreamTag, setStream, outCMMLRoot);
00324
00325 XTAG_PARSE_LIST(C_ClipTag, "clip", parseClipTag, inCMMLRootParser, outCMMLRoot, clipList);
00326
00327
00328 XTAG_SET_ATTRIBUTE(inCMMLRootParser, "lang", outCMMLRoot, setLang);
00329 XTAG_SET_ATTRIBUTE(inCMMLRootParser, "dir", outCMMLRoot, setDirn);
00330
00331 return true;
00332 }
00333
00334 bool CMMLParser::parseHeadTag(XTag* inHeadParser, C_HeadTag* outHead)
00335 {
00336 XTAG_SET_ATTRIBUTE(inHeadParser, "id", outHead, setId);
00337 XTAG_SET_ATTRIBUTE(inHeadParser, "profile", outHead, setProfile);
00338
00339 XTAG_EXACTLY_ONE_CHILD(inHeadParser, "title");
00340 XTAG_PARSE_CHILD(inHeadParser, "title", parseTitleTag, C_TitleTag, setTitle, outHead);
00341 XTAG_PARSE_CHILD(inHeadParser, "base", parseBaseTag, C_BaseTag, setBase, outHead);
00342
00343 XTAG_PARSE_LIST(C_MetaTag, "meta", parseMetaTag, inHeadParser, outHead, metaList);
00344
00345
00346 XTAG_SET_ATTRIBUTE(inHeadParser, "lang", outHead, setLang);
00347 XTAG_SET_ATTRIBUTE(inHeadParser, "dir", outHead, setDirn);
00348
00349 return true;
00350 }
00351
00352 bool CMMLParser::parseTitleTag(XTag* inTitleParser, C_TitleTag* outTitle)
00353 {
00354 XTAG_SET_ATTRIBUTE(inTitleParser, "id", outTitle, setId);
00355
00356 XTAG_SET_CDATA(inTitleParser, outTitle);
00357
00358
00359 XTAG_SET_ATTRIBUTE(inTitleParser, "lang", outTitle, setLang);
00360 XTAG_SET_ATTRIBUTE(inTitleParser, "dir", outTitle, setDirn);
00361
00362 return true;
00363 }
00364
00365 bool CMMLParser::parseBaseTag(XTag* inBaseParser, C_BaseTag* outBase)
00366 {
00367 XTAG_SET_ATTRIBUTE(inBaseParser, "id", outBase, setId);
00368 XTAG_SET_ATTRIBUTE(inBaseParser, "href", outBase, setHref);
00369 XTAG_REQUIRED_ATTRIBUTE(inBaseParser, "href", outBase);
00370
00371 return true;
00372 }
00373
00374 bool CMMLParser::parseMetaTag(XTag* inMetaParser, C_MetaTag* outMeta)
00375 {
00376 XTAG_SET_ATTRIBUTE(inMetaParser, "scheme", outMeta, setScheme);
00377 XTAG_SET_ATTRIBUTE(inMetaParser, "content", outMeta, setContent);
00378 XTAG_SET_ATTRIBUTE(inMetaParser, "id", outMeta, setId);
00379 XTAG_SET_ATTRIBUTE(inMetaParser, "name", outMeta, setName);
00380
00381
00382 XTAG_SET_ATTRIBUTE(inMetaParser, "lang", outMeta, setLang);
00383 XTAG_SET_ATTRIBUTE(inMetaParser, "dir", outMeta, setDirn);
00384
00385 return true;
00386 }
00387
00388 bool CMMLParser::parseClipTag(XTag* inClipParser, C_ClipTag* outClip)
00389 {
00390 XTAG_SET_ATTRIBUTE(inClipParser, "track", outClip, setTrack);
00391 XTAG_SET_ATTRIBUTE(inClipParser, "id", outClip, setId);
00392 XTAG_SET_ATTRIBUTE(inClipParser, "start", outClip, setStart);
00393 XTAG_REQUIRED_ATTRIBUTE(inClipParser, "start", outClip);
00394 XTAG_SET_ATTRIBUTE(inClipParser, "end", outClip, setEnd);
00395
00396 XTAG_PARSE_LIST(C_MetaTag, "meta", parseMetaTag, inClipParser, outClip, metaList);
00397
00398 XTAG_PARSE_CHILD(inClipParser, "a", parseAnchorTag, C_AnchorTag, setAnchor, outClip);
00399 XTAG_PARSE_CHILD(inClipParser, "img", parseImageTag, C_ImageTag, setImage, outClip);
00400 XTAG_PARSE_CHILD(inClipParser, "desc", parseDescTag, C_DescTag, setDesc, outClip);
00401
00402
00403 XTAG_SET_ATTRIBUTE(inClipParser, "lang", outClip, setLang);
00404 XTAG_SET_ATTRIBUTE(inClipParser, "dir", outClip, setDirn);
00405
00406 return true;
00407 }
00408
00409 bool CMMLParser::parseAnchorTag(XTag* inAnchorParser, C_AnchorTag* outAnchor)
00410 {
00411 XTAG_SET_ATTRIBUTE(inAnchorParser, "id", outAnchor, setId);
00412 XTAG_SET_ATTRIBUTE(inAnchorParser, "class", outAnchor, setCls);
00413 XTAG_SET_ATTRIBUTE(inAnchorParser, "href", outAnchor, setHref);
00414 XTAG_REQUIRED_ATTRIBUTE(inAnchorParser, "href", outAnchor);
00415
00416 XTAG_SET_CDATA(inAnchorParser, outAnchor);
00417
00418
00419 XTAG_SET_ATTRIBUTE(inAnchorParser, "lang", outAnchor, setLang);
00420 XTAG_SET_ATTRIBUTE(inAnchorParser, "dir", outAnchor, setDirn);
00421
00422 return true;
00423 }
00424
00425 bool CMMLParser::parseImageTag(XTag* inImageParser, C_ImageTag* outImage)
00426 {
00427 XTAG_SET_ATTRIBUTE(inImageParser, "id", outImage, setId);
00428 XTAG_SET_ATTRIBUTE(inImageParser, "src", outImage, setSrc);
00429 XTAG_REQUIRED_ATTRIBUTE(inImageParser, "src", outImage);
00430 XTAG_SET_ATTRIBUTE(inImageParser, "alt", outImage, setAlt);
00431
00432
00433 XTAG_SET_ATTRIBUTE(inImageParser, "lang", outImage, setLang);
00434 XTAG_SET_ATTRIBUTE(inImageParser, "dir", outImage, setDirn);
00435
00436 return true;
00437 }
00438
00439 bool CMMLParser::parseDescTag(XTag* inDescParser, C_DescTag* outDesc)
00440 {
00441 XTAG_SET_ATTRIBUTE(inDescParser, "id", outDesc, setId);
00442
00443 XTAG_SET_CDATA(inDescParser, outDesc);
00444
00445
00446 XTAG_SET_ATTRIBUTE(inDescParser, "lang", outDesc, setLang);
00447 XTAG_SET_ATTRIBUTE(inDescParser, "dir", outDesc, setDirn);
00448
00449 return true;
00450 }
00451
00452 bool CMMLParser::parseImportTag(XTag* inImportParser, C_ImportTag* outImport)
00453 {
00454 XTAG_SET_ATTRIBUTE(inImportParser, "granulerate", outImport, setGranuleRate);
00455 XTAG_SET_ATTRIBUTE(inImportParser, "contenttype", outImport, setContentType);
00456 XTAG_SET_ATTRIBUTE(inImportParser, "src", outImport, setSrc);
00457 XTAG_SET_ATTRIBUTE(inImportParser, "start", outImport, setStart);
00458 XTAG_SET_ATTRIBUTE(inImportParser, "end", outImport, setEnd);
00459 XTAG_SET_ATTRIBUTE(inImportParser, "title", outImport, setTitle);
00460
00461 XTAG_PARSE_LIST(C_ParamTag, "param", parseParamTag, inImportParser, outImport, paramList);
00462
00463 return true;
00464 }
00465
00466 bool CMMLParser::parseParamTag(XTag* inParamParser, C_ParamTag* outParam)
00467 {
00468 XTAG_SET_ATTRIBUTE(inParamParser, "id", outParam, setId);
00469 XTAG_SET_ATTRIBUTE(inParamParser, "name", outParam, setName);
00470 XTAG_REQUIRED_ATTRIBUTE(inParamParser, "name", outParam);
00471 XTAG_SET_ATTRIBUTE(inParamParser, "value", outParam, setContent);
00472 XTAG_REQUIRED_ATTRIBUTE(inParamParser, "value", outParam);
00473
00474 return true;
00475 }
00476
00477 #undef XTAG_REQUIRED_ATTRIBUTE
00478
00479 #undef XTAG_SET_ATTRIBUTE
00480
00481 #undef XTAG_PARSE_INTO
00482
00483 #undef XTAG_SET_CDATA