public void WriteBlock(int entryId, List <EntryVersion> vers) { sw.WriteLine(); sw.Write("# ID-"); sw.WriteLine(EntryId.IdToString(entryId)); for (int i = 0; i != vers.Count; ++i) { EntryVersion ver = vers[i]; sw.Write("# Ver "); sw.Write(formatDate(ver.Timestamp)); sw.Write(' '); sw.Write(ver.User); sw.Write(" Stat-"); if (ver.Status == EntryStatus.Neutral) { sw.Write("New"); } else if (ver.Status == EntryStatus.Approved) { sw.Write("Verif"); } else if (ver.Status == EntryStatus.Flagged) { sw.Write("Flagged"); } else { throw new Exception("Forgotten entry status: " + ver.Status); } sw.Write(' '); if (ver.BulkRef > 0) { sw.Write(ver.BulkRef.ToString("000")); } sw.Write('>'); string cmtEsc = ver.Comment; if (cmtEsc.Contains(@"\")) { cmtEsc = cmtEsc.Replace(@"\", @"\\"); } if (cmtEsc.Contains("\n")) { cmtEsc = cmtEsc.Replace("\n", "\\n"); } sw.WriteLine(cmtEsc); if (ver.Entry != null) { string entryStr = CedictWriter.Write(ver.Entry); if (i != vers.Count - 1) { sw.Write("# "); } sw.WriteLine(entryStr); } } }
/// <summary> /// Reads a block from stream with versioned entries. /// </summary> /// <param name="vers">Receives versions; oldest first.</param> /// <returns>Entry ID if succeeded, -1 if input is over.</returns> public int ReadBlock(List <EntryVersion> vers) { int id = -1; EntryVersion currVersion = null; string line; while ((line = sr.ReadLine()) != null) { // Still looking for block stating ID if (id == -1) { // Skip all lines that are *not* an ID if (!line.StartsWith("# ID-")) { continue; } line = line.Substring(5); id = EntryId.StringToId(line); } // We're inside block else { // Not a comment: this is block's last line, with current entry if (!line.StartsWith("#")) { currVersion.Entry = parser.ParseEntry(line, -1, null); vers.Add(currVersion); // Forward-propagate unchanged entries (null at this point) for (int i = 1; i < vers.Count; ++i) { if (vers[i].Entry == null) { vers[i].Entry = vers[i - 1].Entry; } } return(id); } // Commented lines are either version declarations, or past forms of entries following a version declaration // Entries are omitted if they didn't change from previous version if (line.StartsWith("# Ver")) { if (currVersion != null) { vers.Add(currVersion); } currVersion = parseVersion(line); } else { line = line.Substring(2); currVersion.Entry = parser.ParseEntry(line, -1, null); vers.Add(currVersion); currVersion = null; } } } // Forward-propagate unchanged entries (null at this point) for (int i = 1; i < vers.Count; ++i) { if (vers[i].Entry == null) { vers[i].Entry = vers[i - 1].Entry; } } // Done. return(id); }
private void toVersions(List <HistRec> recs, out List <EntryVersion> history, out int entryId) { entryId = recs[0].EntryId; history = new List <EntryVersion>(); // Sort records newest to oldest recs.Sort((x, y) => y.ModifTimeUtc.CompareTo(x.ModifTimeUtc)); // Resolve HW, TRG and STATUS for each version string[] verHw = new string[recs.Count]; string[] verTrg = new string[recs.Count]; EntryStatus[] verStatus = new EntryStatus[recs.Count]; for (int i = 0; i != recs.Count; ++i) { HistRec rec = recs[i]; // Newest: take entry, "propagate" all the way to oldest if (i == 0) { for (int j = 0; j != recs.Count; ++j) { verHw[j] = rec.EntryHw; verTrg[j] = rec.EntryTrg; verStatus[j] = rec.EntryStatus; } } // Change has "before" value: propagate to earlier versions if (rec.ModifHwBefore != null) { for (int j = i + 1; j < verHw.Length; ++j) { verHw[j] = rec.ModifHwBefore; } } if (rec.ModifTrgBefore != null) { for (int j = i + 1; j < verTrg.Length; ++j) { verTrg[j] = rec.ModifTrgBefore; } } if (rec.ModifStatusBefore != 99) { for (int j = i + 1; j < verStatus.Length; ++j) { verStatus[j] = (EntryStatus)rec.ModifStatusBefore; } } } // Moving now from oldest to newest, build history // First and last item are special: they always contain entry // First coz we must "anchor" entry; last because it's always present in non-commented form for (int i = recs.Count - 1; i >= 0; --i) { HistRec rec = recs[i]; CedictEntry entry = parser.ParseEntry(verHw[i] + " " + verTrg[i], -1, null); EntryVersion ev = new EntryVersion { Timestamp = rec.ModifTimeUtc, User = idToUserName[rec.ModifUserId], Status = verStatus[i], BulkRef = rec.ModifBulkRef, Comment = rec.ModifNote, Entry = null, }; // First and last version always get entry if (i == 0 || i == recs.Count - 1) { ev.Entry = entry; } // Also if HW or TRG changed from earlier (i + 1) version else if (verHw[i] != verHw[i + 1] || verTrg[i] != verTrg[i + 1]) { ev.Entry = entry; } // Append to history history.Add(ev); } }