public Task <Errorable <CommitID> > ResolvePartialID(CommitID.Partial id)
 {
     FileInfo[] fis = system.getPathsByPartialID(id);
     if (fis.Length == 1)
     {
         return(Task.FromResult(CommitID.TryParse(id.ToString().Substring(0, 2) + fis[0].Name)));
     }
     if (fis.Length == 0)
     {
         return(Task.FromResult((Errorable <CommitID>) new CommitIDPartialNoResolutionError(id)));
     }
     return(Task.FromResult((Errorable <CommitID>) new CommitIDPartialAmbiguousResolutionError(id, fis.SelectAsArray(f => CommitID.TryParse(id.ToString().Substring(0, 2) + f.Name).Value))));
 }
        private async Task <Errorable <Ref> > getRefByName(RefName refName)
        {
            FileInfo fiTracker = system.getRefPathByRefName(refName);

            if (!fiTracker.Exists)
            {
                return(new RefNameDoesNotExistError(refName));
            }

            byte[] buf;
            int    nr = 0;

            using (var fs = new FileStream(fiTracker.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();
                }
            }

            // Parse the CommitID:
            using (var ms = new MemoryStream(buf, 0, nr, false))
                using (var sr = new StreamReader(ms, Encoding.UTF8))
                {
                    string line = sr.ReadLine();
                    if (line == null)
                    {
                        return(new RefNameDoesNotExistError(refName));
                    }

                    var ecid = CommitID.TryParse(line);
                    if (ecid.HasErrors)
                    {
                        return(ecid.Errors);
                    }

                    return((Ref) new Ref.Builder(refName, ecid.Value));
                }
        }
Ejemplo n.º 3
0
        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);
        }
        private async Task <Errorable <Commit> > getCommit(CommitID id)
        {
            FileInfo fi = system.getPathByID(id);

            if (!fi.Exists)
            {
                return(null);
            }

            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 commit you have!
                    throw new NotSupportedException();
                }
            }

            Commit.Builder cb = new Commit.Builder()
            {
                Parents = new List <CommitID>()
            };

            // Parse the Commit:
            using (var ms = new MemoryStream(buf, 0, nr, false))
                using (var sr = new StreamReader(ms, Encoding.UTF8))
                {
                    string line;

                    // Read the list of parent CommitIDs:
                    while ((line = sr.ReadLine()) != null)
                    {
                        if (!line.StartsWith("parent "))
                        {
                            break;
                        }

                        string parent_commitid = line.Substring("parent ".Length);
                        var    ecid            = CommitID.TryParse(parent_commitid);
                        if (ecid.HasErrors)
                        {
                            return(ecid.Errors);
                        }
                        cb.Parents.Add(ecid.Value);
                    }

                    // Set TreeID:
                    if (line == null || !line.StartsWith("tree "))
                    {
                        return(new CommitParseExpectedTreeError());
                    }
                    var etrid = TreeID.TryParse(line.Substring("tree ".Length));
                    if (etrid.HasErrors)
                    {
                        return(etrid.Errors);
                    }
                    cb.TreeID = etrid.Value;

                    // Set Committer:
                    line = sr.ReadLine();
                    if (line == null || !line.StartsWith("committer "))
                    {
                        return(new CommitParseExpectedCommitterError());
                    }
                    cb.Committer = line.Substring("committer ".Length);

                    // Set DateCommitted:
                    line = sr.ReadLine();
                    if (line == null || !line.StartsWith("date "))
                    {
                        return(new CommitParseExpectedDateError());
                    }

                    // 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 CommitParseBadDateFormatError());
                    }
                    cb.DateCommitted = tmpDate;

                    // Skip empty line:
                    line = sr.ReadLine();
                    if (line == null || line.Length != 0)
                    {
                        return(new CommitParseExpectedBlankLineError());
                    }

                    // Set Message:
                    cb.Message = sr.ReadToEnd();
                }

            // Create the immutable Commit from the Builder:
            Commit cm = cb;

            // Validate the computed CommitID:
            if (cm.ID != id)
            {
                return(new ComputedCommitIDMismatchError(cm.ID, id));
            }

            return(cm);
        }