Length* StringImpl::toLengthArray(int& len) { RefPtr<StringImpl> str = simplifyWhiteSpace(); if (!str->length()) { len = 1; return 0; } len = countCharacter(str.get(), ',') + 1; Length* r = new Length[len]; int i = 0; int pos = 0; int pos2; while ((pos2 = str->find(',', pos)) != -1) { r[i++] = parseLength(str->characters() + pos, pos2 - pos); pos = pos2+1; } ASSERT(i == len - 1); /* IE Quirk: If the last comma is the last char skip it and reduce len by one */ if (str->length()-pos > 0) r[i] = parseLength(str->characters() + pos, str->length() - pos); else len--; return r; }
bool K3bCueFileParser::parseLine( QString& line ) { // use cap(1) for the filename static QRegExp fileRx( "FILE\\s\"?([^\"]*)\"?\\s[^\"\\s]*" ); // use cap(1) for the flags static QRegExp flagsRx( "FLAGS(\\s(DCP|4CH|PRE|SCMS)){1,4}" ); // use cap(1) for the tracknumber and cap(2) for the datatype static QRegExp trackRx( "TRACK\\s(\\d{1,2})\\s(AUDIO|CDG|MODE1/2048|MODE1/2352|MODE2/2336|MODE2/2352|CDI/2336|CDI/2352)" ); // use cap(1) for the index number, cap(3) for the minutes, cap(4) for the seconds, cap(5) for the frames, // and cap(2) for the MSF value string static QRegExp indexRx( "INDEX\\s(\\d{1,2})\\s((\\d+):([0-5]\\d):((?:[0-6]\\d)|(?:7[0-4])))" ); // use cap(1) for the MCN static QRegExp catalogRx( "CATALOG\\s(\\w{13,13})" ); // use cap(1) for the ISRC static QRegExp isrcRx( "ISRC\\s(\\w{5,5}\\d{7,7})" ); static QString cdTextRxStr = "\"?([^\"]{0,80})\"?"; // use cap(1) for the string static QRegExp titleRx( "TITLE\\s" + cdTextRxStr ); static QRegExp performerRx( "PERFORMER\\s" + cdTextRxStr ); static QRegExp songwriterRx( "SONGWRITER\\s" + cdTextRxStr ); // simplify all white spaces except those in filenames and CD-TEXT simplifyWhiteSpace( line ); // skip comments and empty lines if( line.startsWith("REM") || line.startsWith("#") || line.isEmpty() ) return true; // // FILE // if( fileRx.exactMatch( line ) ) { setValid( findImageFileName( fileRx.cap(1) ) ); if( d->inFile ) { kdDebug() << "(K3bCueFileParser) only one FILE statement allowed." << endl; return false; } d->inFile = true; d->inTrack = false; d->haveIndex1 = false; return true; } // // TRACK // else if( trackRx.exactMatch( line ) ) { if( !d->inFile ) { kdDebug() << "(K3bCueFileParser) TRACK statement before FILE." << endl; return false; } // check if we had index1 for the last track if( d->inTrack && !d->haveIndex1 ) { kdDebug() << "(K3bCueFileParser) TRACK without INDEX 1." << endl; return false; } // save last track // TODO: use d->rawData in some way if( d->currentParsedTrack > 0 ) { d->toc.append( K3bDevice::Track( d->currentDataPos, d->currentDataPos, d->trackType, d->trackMode ) ); } d->currentParsedTrack++; d->cdText.resize( d->currentParsedTrack ); // parse the tracktype if( trackRx.cap(2) == "AUDIO" ) { d->trackType = K3bDevice::Track::AUDIO; d->trackMode = K3bDevice::Track::UNKNOWN; } else { d->trackType = K3bDevice::Track::DATA; if( trackRx.cap(2).startsWith("MODE1") ) { d->trackMode = K3bDevice::Track::MODE1; d->rawData = (trackRx.cap(2) == "MODE1/2352"); } else if( trackRx.cap(2).startsWith("MODE2") ) { d->trackMode = K3bDevice::Track::MODE2; d->rawData = (trackRx.cap(2) == "MODE2/2352"); } else { kdDebug() << "(K3bCueFileParser) unsupported track type: " << trackRx.cap(2) << endl; return false; } } d->haveIndex1 = false; d->inTrack = true; d->index0 = 0; return true; } // // FLAGS // else if( flagsRx.exactMatch( line ) ) { if( !d->inTrack ) { kdDebug() << "(K3bCueFileParser) FLAGS statement without TRACK." << endl; return false; } // TODO: save the flags return true; } // // INDEX // else if( indexRx.exactMatch( line ) ) { if( !d->inTrack ) { kdDebug() << "(K3bCueFileParser) INDEX statement without TRACK." << endl; return false; } unsigned int indexNumber = indexRx.cap(1).toInt(); K3b::Msf indexStart = K3b::Msf::fromString( indexRx.cap(2) ); if( indexNumber == 0 ) { d->index0 = indexStart; if( d->currentParsedTrack < 2 && indexStart > 0 ) { kdDebug() << "(K3bCueFileParser) first track is not allowed to have a pregap > 0." << endl; return false; } } else if( indexNumber == 1 ) { d->haveIndex1 = true; d->currentDataPos = indexStart; if( d->currentParsedTrack > 1 ) { d->toc[d->currentParsedTrack-2].setLastSector( indexStart-1 ); if( d->index0 > 0 && d->index0 < indexStart ) { d->toc[d->currentParsedTrack-2].setIndex0( d->index0 - d->toc[d->currentParsedTrack-2].firstSector() ); } } } else { // TODO: add index > 0 } return true; } // // CATALOG // if( catalogRx.exactMatch( line ) ) { // TODO: set the toc's mcn return true; } // // ISRC // if( isrcRx.exactMatch( line ) ) { if( d->inTrack ) { // TODO: set the track's ISRC return true; } else { kdDebug() << "(K3bCueFileParser) ISRC without TRACK." << endl; return false; } } // // CD-TEXT // TODO: create K3bDevice::TrackCdText entries // else if( titleRx.exactMatch( line ) ) { if( d->inTrack ) d->cdText[d->currentParsedTrack-1].setTitle( titleRx.cap(1) ); else d->cdText.setTitle( titleRx.cap(1) ); return true; } else if( performerRx.exactMatch( line ) ) { if( d->inTrack ) d->cdText[d->currentParsedTrack-1].setPerformer( performerRx.cap(1) ); else d->cdText.setPerformer( performerRx.cap(1) ); return true; } else if( songwriterRx.exactMatch( line ) ) { if( d->inTrack ) d->cdText[d->currentParsedTrack-1].setSongwriter( songwriterRx.cap(1) ); else d->cdText.setSongwriter( songwriterRx.cap(1) ); return true; } else { kdDebug() << "(K3bCueFileParser) unknown Cue line: '" << line << "'" << endl; return false; } }