public static Errorable<Tag.Builder> FromJSON(this TagRequest tgm) { // Do conversions on the strings and detect any errors: var maybecommitid = CommitID.TryParse(tgm.commitid ?? String.Empty); if (maybecommitid.HasErrors) return maybecommitid.Errors; Tag.Builder tg = new Tag.Builder( pName: (TagName)tgm.name, pCommitID: maybecommitid.Value, pTagger: tgm.tagger ?? String.Empty, pDateTagged: String.IsNullOrWhiteSpace(tgm.date_tagged) ? DateTimeOffset.Now : ToDate(tgm.date_tagged), pMessage: tgm.message ?? String.Empty ); return tg; }
private async Task<Errorable<Tag>> getTag(TagID id) { FileInfo fi = system.getPathByID(id); if (!fi.Exists) return new TagIDRecordDoesNotExistError(id); byte[] buf; int nr = 0; using (var fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, 16384, true)) { // TODO: implement an async buffered Stream: buf = new byte[16384]; nr = await fs.ReadAsync(buf, 0, 16384).ConfigureAwait(continueOnCapturedContext: false); if (nr >= 16384) { // My, what a large tag you have! throw new NotSupportedException(); } } Tag.Builder tb = new Tag.Builder(); // Parse the Tag: using (var ms = new MemoryStream(buf, 0, nr, false)) using (var sr = new StreamReader(ms, Encoding.UTF8)) { string line = sr.ReadLine(); // Set CommitID: if (line == null || !line.StartsWith("commit ")) return new TagParseExpectedCommitError(); var ecid = CommitID.TryParse(line.Substring("commit ".Length)); if (ecid.HasErrors) return ecid.Errors; tb.CommitID = ecid.Value; // Set Name: line = sr.ReadLine(); if (line == null || !line.StartsWith("name ")) return new TagParseExpectedNameError(); tb.Name = (TagName)line.Substring("name ".Length); // Set Tagger: line = sr.ReadLine(); if (line == null || !line.StartsWith("tagger ")) return new TagParseExpectedTaggerError(); tb.Tagger = line.Substring("tagger ".Length); // Set DateTagged: line = sr.ReadLine(); if (line == null || !line.StartsWith("date ")) return new TagParseExpectedDateError(); // NOTE: date parsing will result in an inexact DateTimeOffset from what was created with, but it // is close enough because the SHA-1 hash is calculated using the DateTimeOffset.ToString(), so // only the ToString() representations of the DateTimeOffsets need to match. DateTimeOffset tmpDate; if (!DateTimeOffset.TryParse(line.Substring("date ".Length), out tmpDate)) return new TagParseBadDateFormatError(); tb.DateTagged = tmpDate; // Skip empty line: line = sr.ReadLine(); if (line == null || line.Length != 0) return new TagParseExpectedBlankLineError(); // Set Message: tb.Message = sr.ReadToEnd(); } // Create the immutable Tag from the Builder: Tag tg = tb; // Validate the computed TagID: if (tg.ID != id) return new ComputedTagIDMismatchError(tg.ID, id); return tg; }