SectionOrError(int targetPower, int duration, string desc, bool isError, int start, int length, string message, bool isLoop, int loopCount, SectionOrError loopSection) : base(targetPower, duration, desc) { IsError = isError; Start = start; Length = length; Message = message; IsLoop = isLoop; LoopCount = loopCount; LoopSection = loopSection; }
SectionOrError ParseLine(int offset, string line, int depth = 0) { if (loopSectionList.Count < depth) { return(SectionOrError.GetError(0, line.Length, "Loop mark is too many.")); } if (line[0] == '#') { return(null); } int sectionHeadIdx = 0; while (line[sectionHeadIdx] == '%') { sectionHeadIdx = IndexOfNextNonWhiteSpace(line, sectionHeadIdx + 1); depth++; } if (loopSectionList.Count < depth) { return(SectionOrError.GetError(offset, line.Length, "Bad loop mark is found.")); } while (loopSectionList.Count > depth) { loopSectionList.RemoveAt(loopSectionList.Count - 1); } if (line.Substring(sectionHeadIdx).ToLower().IndexOf("loop") == 0) { int countIdx = IndexOfNextNonWhiteSpace(line, sectionHeadIdx + 4); if (countIdx == line.Length) { return(SectionOrError.GetError(offset, line.Length, "Loop header 'LOOP n' lacks 'n'.")); } try { var n = Int32.Parse(line.Substring(countIdx)); var section = SectionOrError.GetLoop(n); loopSectionList.Add(section); return(section); } catch (Exception) { return(SectionOrError.GetError(offset, line.Length, "Loop header 'LOOP n' don't have digits. 'n' must be digits.")); } } int targetPowerTailIdx = IndexOfNextWhiteSpace(line, sectionHeadIdx); if (targetPowerTailIdx == sectionHeadIdx) { return(SectionOrError.GetError(offset, 1, "Each lines of plan should start with # or number.")); } if (targetPowerTailIdx == line.Length) { return(SectionOrError.GetError(offset, line.Length, "No duration column and description.")); } char mayW = line[targetPowerTailIdx - 1]; int targetPowerTailAdj = 0; if (mayW == 'w' || mayW == 'W') { targetPowerTailAdj = -1; } int targetPower; var s = line.Substring(sectionHeadIdx, targetPowerTailIdx + targetPowerTailAdj - sectionHeadIdx); if (!Int32.TryParse(line.Substring(sectionHeadIdx, targetPowerTailIdx + targetPowerTailAdj - sectionHeadIdx), out targetPower) || targetPower < 0) { return(SectionOrError.GetError(offset, targetPowerTailIdx - sectionHeadIdx, "Target power column should be a natural number or zero.")); } int durationHeadIdx = IndexOfNextNonWhiteSpace(line, targetPowerTailIdx); if (durationHeadIdx == line.Length) { return(SectionOrError.GetError(offset + targetPowerTailIdx, durationHeadIdx - targetPowerTailIdx, "No duration column and description.")); } int durationTailIdx = IndexOfNextWhiteSpace(line, durationHeadIdx); if (durationTailIdx == line.Length) { return(SectionOrError.GetError(offset + durationHeadIdx, durationTailIdx - durationHeadIdx, "No description.")); } var durationOrError = ParseDuration(line.Substring(durationHeadIdx, durationTailIdx - durationHeadIdx)); if (durationOrError.IsError) { return(SectionOrError.GetError(offset + durationHeadIdx, durationTailIdx - durationHeadIdx, durationOrError.Message)); } int duration = durationOrError.Duration; int descHeadIdx = IndexOfNextNonWhiteSpace(line, durationTailIdx); if (descHeadIdx == line.Length) { return(SectionOrError.GetError(offset + durationTailIdx, descHeadIdx - durationTailIdx, "No description.")); } string desc = line.Substring(descHeadIdx).Trim(); if (desc.Length > 15) { return(SectionOrError.GetError(offset + descHeadIdx, line.Length - descHeadIdx, "Description should be under 15 characters.")); } if (!CheckDesc(desc)) { return(SectionOrError.GetError(offset + descHeadIdx, line.Length - descHeadIdx, "Description should be ASCII characters.")); } while (loopSectionList.Count > depth) { loopSectionList.RemoveAt(loopSectionList.Count - 1); } if (depth == 0) { return(SectionOrError.GetSection(targetPower, duration, desc)); } else { return(SectionOrError.GetSection(targetPower, duration, desc, loopSectionList[depth - 1])); } }
public static SectionOrError GetSection(int targetPower, int duration, string desc, SectionOrError loopSection) { return(new SectionOrError(targetPower, duration, desc, false, 0, 0, null, false, 0, loopSection)); }