public void CopyFrom(CueSheetTrackInfo rhs) { path = rhs.path; title = rhs.title; trackId = rhs.trackId; startTick = rhs.startTick; endTick = rhs.endTick; indexId = rhs.indexId; performer = rhs.performer; albumTitle = rhs.albumTitle; readSeparatorAfter = rhs.readSeparatorAfter; }
private bool ParseOneLine(string line, int lineno) { line = line.Trim(); List <string> tokenList = Tokenize(line); if (tokenList.Count == 0) { return(true); } switch (tokenList[0].ToUpperInvariant()) { case "PERFORMER": mCurrentTrackInfo.performer = string.Empty; if (2 <= tokenList.Count && 0 < tokenList[1].Trim().Length) { if (mIsAlbumInfoParsing) { mAlbumPerformer = tokenList[1]; } else { mCurrentTrackInfo.performer = tokenList[1]; } } break; case "TITLE": mCurrentTrackInfo.title = string.Empty; if (2 <= tokenList.Count && 0 < tokenList[1].Trim().Length) { if (mIsAlbumInfoParsing) { mAlbumTitle = tokenList[1]; } else { mCurrentTrackInfo.title = tokenList[1]; } } break; case "REM": if (2 <= tokenList.Count && 0 == string.Compare(tokenList[1], "KOKOMADE", StringComparison.OrdinalIgnoreCase)) { mCurrentTrackInfo.readSeparatorAfter = true; } break; case "FILE": if (tokenList.Count < 2) { Console.WriteLine("Error on line {0}: FILE directive error: filename is not specified", lineno); return(true); } if (3 <= tokenList[1].Length && ((tokenList[1][0] == '\\' && tokenList[1][1] == '\\') || ((tokenList[1][1] == ':')))) { // フルパス。 mCurrentTrackInfo.path = tokenList[1]; } else { // 相対パス。 mCurrentTrackInfo.path = mDirPath + tokenList[1]; } // file tag has come; End album info. mIsAlbumInfoParsing = false; mCurrentTrackInfo.Debug(); break; case "TRACK": if (tokenList.Count < 2) { Console.WriteLine("Error on line {0}: track number is not specified", lineno); return(true); } if (!int.TryParse(tokenList[1], out mCurrentTrackInfo.trackId)) { Console.WriteLine("Error on line {0}: track number TryParse failed", lineno); return(true); } mCurrentTrackInfo.Debug(); break; case "INDEX": if (tokenList.Count < 3) { Console.WriteLine("Error on line {0}: index number tick format err", lineno); return(true); } if (!int.TryParse(tokenList[1], out mCurrentTrackInfo.indexId)) { mCurrentTrackInfo.indexId = 1; } mCurrentTrackInfo.startTick = CueSheetTrackInfo.TickStrToInt(tokenList[2]); if (mCurrentTrackInfo.startTick < 0) { Console.WriteLine("Error on line {0}: index {1} time format error ({2})", lineno, mCurrentTrackInfo.indexId, tokenList[2]); return(true); } if (mCurrentTrackInfo.indexId == 0 || mCurrentTrackInfo.indexId == 1) { CueSheetTrackInfo newTrackInfo = new CueSheetTrackInfo(); newTrackInfo.CopyFrom(mCurrentTrackInfo); mTrackInfoList.Add(newTrackInfo); mCurrentTrackInfo.Debug(); // 揮発要素はここでリセットする。 mCurrentTrackInfo.startTick = -1; mCurrentTrackInfo.readSeparatorAfter = false; mCurrentTrackInfo.performer = string.Empty; mCurrentTrackInfo.albumTitle = string.Empty; } break; default: Console.WriteLine("D: skipped {0}", tokenList[0]); break; } return(true); }
/// <summary> /// throws IOException, ArgumentException, UnauthorizedException /// </summary> public bool WriteToFile(string path) { if (m_trackInfoList.Count() == 0) { return(false); } using (StreamWriter sw = new StreamWriter(path, false, Encoding.Default)) { // アルバムタイトル if (null != m_albumTitle && 0 < m_albumTitle.Length) { sw.WriteLine( string.Format(CultureInfo.InvariantCulture, "TITLE \"{0}\"", m_albumTitle)); } else { sw.WriteLine( string.Format(CultureInfo.InvariantCulture, "TITLE \"\"")); } // アルバム演奏者。 if (null != m_albumPerformer && 0 < m_albumPerformer.Length) { sw.WriteLine( string.Format(CultureInfo.InvariantCulture, "PERFORMER \"{0}\"", m_albumPerformer)); } // 曲情報出力 int trackCount = 1; for (int i = 0; i < m_trackInfoList.Count(); ++i) { CueSheetTrackInfo cti = m_trackInfoList[i]; if (0 == string.CompareOrdinal(Path.GetDirectoryName(path), Path.GetDirectoryName(cti.path))) { sw.WriteLine("FILE \"{0}\" WAVE", Path.GetFileName(cti.path)); } else { sw.WriteLine("FILE \"{0}\" WAVE", cti.path); } sw.WriteLine(" TRACK {0:D2} AUDIO", trackCount++); sw.WriteLine(" TITLE \"{0}\"", cti.title); if (null != cti.performer && 0 < cti.performer.Length) { sw.WriteLine(" PERFORMER \"{0}\"", cti.performer); } // INDEX ?? で曲情報が確定するので、その前にREM KOKOMADEを入れる。 if (!(0 <= cti.endTick && (i == m_trackInfoList.Count() - 1)) && cti.readSeparatorAfter) { sw.WriteLine(" REM KOKOMADE"); } sw.WriteLine(" INDEX {0} {1}", cti.indexId, CueSheetTrackInfo.TickIntToStr(cti.startTick)); if (0 <= cti.endTick && ((i == m_trackInfoList.Count() - 1) || (0 == string.CompareOrdinal(m_trackInfoList[i + 1].path, m_trackInfoList[i].path) && m_trackInfoList[i + 1].startTick != m_trackInfoList[i].endTick))) { sw.WriteLine(" TRACK {0:D2} AUDIO", trackCount++); sw.WriteLine(" TITLE \" gap \""); sw.WriteLine(" INDEX 00 {0}", CueSheetTrackInfo.TickIntToStr(cti.endTick)); } } } return(true); }
/// <summary> /// if file read is failed IOException or ArgumentException or UnauthrizedAccessException occurs /// </summary> public bool ReadFromFile(string path) { // 2パス処理する。 // パス1…ファイルから読み込んでm_trackInfoListに骨格を作る。 // パス2…m_trackInfoListを走査して、前後関係によって判明する情報を埋める。 // 現在のtrackInfoと1個後のトラックが同一ファイル名で // cur.endTickが埋まっていない場合 // cur.endTick←next.startTickする。 mTrackInfoList = new List <CueSheetTrackInfo>(); mDirPath = System.IO.Path.GetDirectoryName(path) + "\\"; mCurrentTrackInfo = new CueSheetTrackInfo(); mCurrentTrackInfo.Clear(); mAlbumTitle = string.Empty; mIsAlbumInfoParsing = true; // Pass 1の処理 bool result = false; using (StreamReader sr = new StreamReader(path, encoding)) { string line; int lineno = 0; while ((line = sr.ReadLine()) != null) { ++lineno; result = ParseOneLine(line, lineno); if (!result) { break; } } } if (!result) { return(false); } /* * Console.WriteLine("after Pass1 ================================="); * Console.WriteLine("trackInfoList.Count={0}", m_trackInfoList.Count); * for (int i = 0; i < m_trackInfoList.Count; ++i) { * Console.WriteLine("trackInfo {0}", i); * m_trackInfoList[i].Debug(); * } */ // Pass 2の処理 for (int i = 0; i < mTrackInfoList.Count - 1; ++i) { CueSheetTrackInfo cur = mTrackInfoList[i]; CueSheetTrackInfo next = mTrackInfoList[i + 1]; if (0 == string.CompareOrdinal(cur.path, next.path) && cur.endTick < 0) { cur.endTick = next.startTick; } if (0 <= cur.endTick && 0 <= cur.startTick && cur.endTick < cur.startTick) { Console.WriteLine("track {0}: startTick{1} points newer time than endTick{2}", cur.trackId, cur.startTick, cur.endTick); return(false); } } /* * Console.WriteLine("after Pass2 ================================="); * Console.WriteLine("trackInfoList.Count={0}", m_trackInfoList.Count); * for (int i = 0; i < m_trackInfoList.Count; ++i) { * Console.WriteLine("trackInfo {0}", i); * m_trackInfoList[i].Debug(); * } */ return(true); }
public void AddTrackInfo(CueSheetTrackInfo a) { m_trackInfoList.Add(a); }
/// <summary> /// if file read is failed IOException or ArgumentException or UnauthrizedAccessException occurs /// </summary> public bool ReadFromFile(string path) { // 2パス処理する。 // パス1…ファイルから読み込んでm_trackInfoListに骨格を作る。 // パス2…m_trackInfoListを走査して、前後関係によって判明する情報を埋める。 // 現在のtrackInfoと1個後のトラックが同一ファイル名で // cur.endTickが埋まっていない場合 // cur.endTick←next.startTickする。 mTrackInfoList = new List<CueSheetTrackInfo>(); mDirPath = System.IO.Path.GetDirectoryName(path) + "\\"; mCurrentTrackInfo = new CueSheetTrackInfo(); mCurrentTrackInfo.Clear(); mAlbumTitle = string.Empty; mIsAlbumInfoParsing = true; // Pass 1の処理 bool result = false; using (StreamReader sr = new StreamReader(path, encoding)) { string line; int lineno = 0; while ((line = sr.ReadLine()) != null) { ++lineno; result = ParseOneLine(line, lineno); if (!result) { break; } } } if (!result) { return false; } /* Console.WriteLine("after Pass1 ================================="); Console.WriteLine("trackInfoList.Count={0}", m_trackInfoList.Count); for (int i = 0; i < m_trackInfoList.Count; ++i) { Console.WriteLine("trackInfo {0}", i); m_trackInfoList[i].Debug(); } */ // Pass 2の処理 for (int i = 0; i < mTrackInfoList.Count-1; ++i) { CueSheetTrackInfo cur = mTrackInfoList[i]; CueSheetTrackInfo next = mTrackInfoList[i+1]; if (0 == string.CompareOrdinal(cur.path, next.path) && cur.endTick < 0) { cur.endTick = next.startTick; } if (0 <= cur.endTick && 0 <= cur.startTick && cur.endTick < cur.startTick) { Console.WriteLine("track {0}: startTick{1} points newer time than endTick{2}", cur.trackId, cur.startTick, cur.endTick); return false; } } /* Console.WriteLine("after Pass2 ================================="); Console.WriteLine("trackInfoList.Count={0}", m_trackInfoList.Count); for (int i = 0; i < m_trackInfoList.Count; ++i) { Console.WriteLine("trackInfo {0}", i); m_trackInfoList[i].Debug(); } */ return true; }
private bool ParseOneLine(string line, int lineno) { line = line.Trim(); List<string> tokenList = Tokenize(line); if (tokenList.Count == 0) { return true; } switch (tokenList[0].ToUpperInvariant()) { case "PERFORMER": mCurrentTrackInfo.performer = string.Empty; if (2 <= tokenList.Count && 0 < tokenList[1].Trim().Length) { if (mIsAlbumInfoParsing) { mAlbumPerformer = tokenList[1]; } else { mCurrentTrackInfo.performer = tokenList[1]; } } break; case "TITLE": mCurrentTrackInfo.title = string.Empty; if (2 <= tokenList.Count && 0 < tokenList[1].Trim().Length) { if (mIsAlbumInfoParsing) { mAlbumTitle = tokenList[1]; } else { mCurrentTrackInfo.title = tokenList[1]; } } break; case "REM": if (2 <= tokenList.Count && 0 == string.Compare(tokenList[1], "KOKOMADE", StringComparison.OrdinalIgnoreCase)) { mCurrentTrackInfo.readSeparatorAfter = true; } break; case "FILE": if (tokenList.Count < 2) { Console.WriteLine("Error on line {0}: FILE directive error: filename is not specified", lineno); return true; } if (3 <= tokenList[1].Length && ((tokenList[1][0] == '\\' && tokenList[1][1] == '\\') || ((tokenList[1][1] == ':')))) { // フルパス。 mCurrentTrackInfo.path = tokenList[1]; } else { // 相対パス。 mCurrentTrackInfo.path = mDirPath + tokenList[1]; } // file tag has come; End album info. mIsAlbumInfoParsing = false; mCurrentTrackInfo.Debug(); break; case "TRACK": if (tokenList.Count < 2) { Console.WriteLine("Error on line {0}: track number is not specified", lineno); return true; } if (!int.TryParse(tokenList[1], out mCurrentTrackInfo.trackId)) { Console.WriteLine("Error on line {0}: track number TryParse failed", lineno); return true; } mCurrentTrackInfo.Debug(); break; case "INDEX": if (tokenList.Count < 3) { Console.WriteLine("Error on line {0}: index number tick format err", lineno); return true; } if (!int.TryParse(tokenList[1], out mCurrentTrackInfo.indexId)) { mCurrentTrackInfo.indexId = 1; } mCurrentTrackInfo.startTick = CueSheetTrackInfo.TickStrToInt(tokenList[2]); if (mCurrentTrackInfo.startTick < 0) { Console.WriteLine("Error on line {0}: index {1} time format error ({2})", lineno, mCurrentTrackInfo.indexId, tokenList[2]); return true; } if (mCurrentTrackInfo.indexId == 0 || mCurrentTrackInfo.indexId == 1) { CueSheetTrackInfo newTrackInfo = new CueSheetTrackInfo(); newTrackInfo.CopyFrom(mCurrentTrackInfo); mTrackInfoList.Add(newTrackInfo); mCurrentTrackInfo.Debug(); // 揮発要素はここでリセットする。 mCurrentTrackInfo.startTick = -1; mCurrentTrackInfo.readSeparatorAfter = false; mCurrentTrackInfo.performer = string.Empty; mCurrentTrackInfo.albumTitle = string.Empty; } break; default: Console.WriteLine("D: skipped {0}", tokenList[0]); break; } return true; }