/// <summary> /// Adds a new or existing Tree with the specified name to this tree. /// Trees are added if necessary as the name may contain '/':s. /// </summary> /// <param name="s"> an array containing the name </param> /// <param name="offset"> when the name starts in the tree.</param> /// <returns>A <seealso cref="FileTreeEntry"/> for the added tree.</returns> /// <exception cref="IOException"></exception> public Tree AddTree(byte[] s, int offset) { int slash; for (slash = offset; slash < s.Length && s[slash] != '/'; slash++) { // search for path component terminator } EnsureLoaded(); int p = BinarySearch(_contents, s, (byte)'/', offset, slash); if (p >= 0 && slash < s.Length && _contents[p] is Tree) { return(((Tree)_contents[p]).AddTree(s, slash + 1)); } byte[] newName = SubString(s, offset, slash); if (p >= 0) { throw new EntryExistsException(RawParseUtils.decode(newName)); } Tree t = new Tree(this, newName); InsertEntry(p, t); return(slash == s.Length ? t : t.AddTree(s, slash + 1)); }
public Entry(byte[] raw, int pos) { oldId = ObjectId.FromString(raw, pos); pos += Constants.OBJECT_ID_STRING_LENGTH; if (raw[pos++] != ' ') { throw new ArgumentException("Raw log message does not parse as log entry"); } newId = ObjectId.FromString(raw, pos); pos += Constants.OBJECT_ID_STRING_LENGTH; if (raw[pos++] != ' ') { throw new ArgumentException("Raw log message does not parse as log entry"); } who = RawParseUtils.parsePersonIdentOnly(raw, pos); int p0 = RawParseUtils.next(raw, pos, (byte)'\t'); if (p0 == -1) { throw new ArgumentException("Raw log message does not parse as log entry"); } int p1 = RawParseUtils.nextLF(raw, p0); if (p1 == -1) { throw new ArgumentException("Raw log message does not parse as log entry"); } comment = RawParseUtils.decode(raw, p0, p1 - 1); }
/// <summary> /// The constructor from commit and path /// </summary> /// <param name="base">The base configuration file</param> /// <param name="commit">The commit that contains the object</param> /// <param name="path">The path within the tree of the commit</param> /// <exception cref="FileNotFoundException"> /// the path does not exist in the commit's tree. /// </exception> /// <exception cref="IOException"> /// the tree and/or blob cannot be accessed. /// </exception> /// <exception cref="ConfigInvalidException"> /// the blob is not a valid configuration format. /// </exception> public BlobBasedConfig(Config @base, Commit commit, string path) : base(@base) { if (commit == null) { throw new System.ArgumentNullException("commit"); } ObjectId treeId = commit.TreeId; Repository r = commit.Repository; TreeWalk.TreeWalk tree = TreeWalk.TreeWalk.ForPath(r, path, treeId); if (tree == null) { throw new FileNotFoundException("Entry not found by path: " + path); } ObjectId blobId = tree.getObjectId(0); ObjectLoader loader = tree.Repository.OpenBlob(blobId); if (loader == null) { throw new IOException("Blob not found: " + blobId + " for path: " + path); } fromText(RawParseUtils.decode(loader.Bytes)); }
public string ReadString() { int len = ReadLength(); if (len == 0) { return(END); } len -= 4; // length header (4 bytes) if (len == 0) { return(string.Empty); } byte[] raw = new byte[len]; IO.ReadFully(ins, raw, 0, len); if (raw[len - 1] == '\n') { len--; } return(RawParseUtils.decode(Constants.CHARSET, raw, 0, len)); }
private void AssertFormatted(string name) { fmt.format(memoryStream, file, a, b); string exp = RawParseUtils.decode(ReadFile(name)); Assert.AreEqual(exp, RawParseUtils.decode(memoryStream.ToArray())); }
public string ReadString() { int len = ReadLength(); if (len == 0) { return(string.Empty); } len -= 4; // length header (4 bytes) if (len <= 0) { return(string.Empty); } byte[] raw = new byte[len]; try { IO.ReadFully(ins, raw, 0, len); } catch (IOException e) { throw invalidHeader(lenbuffer, e); } if (raw[len - 1] == '\n') { len--; } return(RawParseUtils.decode(Constants.CHARSET, raw, 0, len)); }
public static string pathOf(AbstractTreeIterator t) { if (t == null) { throw new ArgumentNullException("t"); } return(RawParseUtils.decode(Constants.CHARSET, t.Path, 0, t.PathLen)); }
/** * Get the current entry's name within its parent tree. * <para /> * This method is not very efficient and is primarily meant for debugging * and output generation. Applications should try to avoid calling it, * and if invoked do so only once per interesting entry, where the name is * absolutely required for correct function. * * @return name of the current entry within the parent tree (or directory). * The name never includes a '/'. */ public string getNameString() { AbstractTreeIterator t = _currentHead; int off = t.PathOffset; int end = t.PathLen; return(RawParseUtils.decode(Constants.CHARSET, t.Path, off, end)); }
public void testWriteLine2() { var a = new RawText(Constants.encodeASCII("foo-a\nfoo-b")); var o = new MemoryStream(); a.writeLine(o, 1); byte[] r = o.ToArray(); Assert.AreEqual("foo-b", RawParseUtils.decode(r)); }
public void testWriteLine3() { var a = new RawText(Constants.encodeASCII("a\n\nb\n")); var o = new MemoryStream(); a.writeLine(o, 1); byte[] r = o.ToArray(); Assert.AreEqual(string.Empty, RawParseUtils.decode(r)); }
/// <summary> * The constructor from object identifier /// </summary> /// <param name="base">the base configuration file </param> /// <param name="r">the repository</param> /// <param name="objectid">the object identifier</param> /// <exception cref="IOException"> /// the blob cannot be read from the repository. </exception> /// <exception cref="ConfigInvalidException"> /// the blob is not a valid configuration format. /// </exception> public BlobBasedConfig(Config @base, Repository r, ObjectId objectid) : base(@base) { ObjectLoader loader = r.OpenBlob(objectid); if (loader == null) { throw new IOException("Blob not found: " + objectid); } fromText(RawParseUtils.decode(loader.Bytes)); }
/// <summary> /// Parse the complete commit message and decode it to a string. /// <para /> /// This method parses and returns the message portion of the commit buffer, /// After taking the commit's character set into account and decoding the /// buffer using that character set. This method is a fairly expensive /// operation and produces a new string on each invocation. /// </summary> /// <returns> /// Decoded commit message as a string. Never null. /// </returns> public string getFullMessage() { byte[] raw = _buffer; int msgB = RawParseUtils.commitMessage(raw, 0); if (msgB < 0) { return(string.Empty); } Encoding enc = RawParseUtils.parseEncoding(raw); return(RawParseUtils.decode(enc, raw, msgB, raw.Length)); }
public void testFreakingHugePathName() { int n = AbstractTreeIterator.DEFAULT_PATH_SIZE * 4; var b = new StringBuilder(n); for (int i = 0; i < n; i++) { b.Append('q'); } string name = b.ToString(); ctp.reset(Entry(m644, name, hash_a)); Assert.IsFalse(ctp.eof()); Assert.AreEqual(name, RawParseUtils.decode(Constants.CHARSET, ctp.Path, ctp.PathOffset, ctp.PathLen)); }
/// <summary> * The constructor from object identifier /// </summary> /// <param name="base">the base configuration file </param> /// <param name="repo">the repository</param> /// <param name="objectid">the object identifier</param> /// <exception cref="IOException"> /// the blob cannot be read from the repository. </exception> /// <exception cref="ConfigInvalidException"> /// the blob is not a valid configuration format. /// </exception> public BlobBasedConfig(Config @base, Repository repo, ObjectId objectid) : base(@base) { if (repo == null) { throw new System.ArgumentNullException("repo"); } ObjectLoader loader = repo.OpenBlob(objectid); if (loader == null) { throw new IOException("Blob not found: " + objectid); } fromText(RawParseUtils.decode(loader.Bytes)); }
private static string readFirstLine(FileInfo head) { try { byte[] buf = IO.ReadFully(head, 4096); int n = buf.Length; if (n == 0) return null; if (buf[n - 1] == '\n') n--; return RawParseUtils.decode(buf, 0, n); } catch (IOException) { return null; } }
public string ReadStringRaw() { int len = ReadLength(); if (len == 0) { return(END); } len -= 4; // length header (4 bytes) byte[] raw = new byte[len]; IO.ReadFully(ins, raw, 0, len); return(RawParseUtils.decode(Constants.CHARSET, raw, 0, len)); }
private static string ReadLine(FileInfo file) { byte[] buf = IO.ReadFully(file, 4096); int n = buf.Length; // remove trailing whitespaces while (n > 0 && char.IsWhiteSpace((char)buf[n - 1])) { n--; } if (n == 0) { return(null); } return(RawParseUtils.decode(buf, 0, n)); }
private string readLine(byte[] hdrbuf) { long mark = _bin.Position; int cnt = _bin.Read(hdrbuf, 0, hdrbuf.Length); int lf = 0; while (lf < cnt && hdrbuf[lf] != '\n') { lf++; } _bin.Position = mark; IO.skipFully(_bin, lf); if (lf < cnt && hdrbuf[lf] == '\n') { IO.skipFully(_bin, 1); } return(RawParseUtils.decode(Constants.CHARSET, hdrbuf, 0, lf)); }
/// <summary> /// Parse the commit message and return the first "line" of it. /// <para /> /// The first line is everything up to the first pair of LFs. This is the /// "oneline" format, suitable for output in a single line display. /// <para /> /// This method parses and returns the message portion of the commit buffer, /// after taking the commit's character set into account and decoding the /// buffer using that character set. This method is a fairly expensive /// operation and produces a new string on each invocation. /// </summary> /// <returns> /// Decoded commit message as a string. Never null. The returned /// string does not contain any LFs, even if the first paragraph /// spanned multiple lines. Embedded LFs are converted to spaces. /// </returns> public string getShortMessage() { byte[] raw = _buffer; int msgB = RawParseUtils.commitMessage(raw, 0); if (msgB < 0) { return(string.Empty); } Encoding enc = RawParseUtils.parseEncoding(raw); int msgE = RawParseUtils.endOfParagraph(raw, msgB); string str = RawParseUtils.decode(enc, raw, msgB, msgE); if (hasLF(raw, msgB, msgE)) { str = str.Replace('\n', ' '); } return(str); }
private string ParseName(String expect, int ptr, int end) { if (ptr == end) { return(expect); } string r; if (Buffer[ptr] == '"') { // New style GNU diff format // r = QuotedString.GitPathStyle.GIT_PATH.dequote(Buffer, ptr, end - 1); } else { // Older style GNU diff format, an optional tab ends the name. // int tab = end; while (ptr < tab && Buffer[tab - 1] != '\t') { tab--; } if (ptr == tab) { tab = end; } r = RawParseUtils.decode(Constants.CHARSET, Buffer, ptr, tab - 1); } if (r.Equals(DEV_NULL)) { r = DEV_NULL; } return(r); }
private string[] ExtractFileLines(Encoding[] csGuess) { var tmp = new TemporaryBuffer[ParentCount + 1]; try { for (int i = 0; i < tmp.Length; i++) { tmp[i] = new TemporaryBuffer(); } foreach (HunkHeader h in Hunks) { h.extractFileLines(tmp); } var r = new String[tmp.Length]; for (int i = 0; i < tmp.Length; i++) { Encoding cs = (csGuess != null ? csGuess[i] : null) ?? Constants.CHARSET; r[i] = RawParseUtils.decode(cs, tmp[i].ToArray()); } return(r); } catch (IOException ioe) { throw new Exception("Cannot convert script to text", ioe); } finally { foreach (TemporaryBuffer b in tmp) { if (b != null) { b.destroy(); } } } }
public void parseCanonical(RevWalk walk, byte[] rawTag) { var pos = new MutableInteger { value = 53 }; int oType = Constants.decodeTypeString(this, rawTag, (byte)'\n', pos); walk.IdBuffer.FromString(rawTag, 7); _object = walk.lookupAny(walk.IdBuffer, oType); int p = pos.value += 4; // "tag " int nameEnd = RawParseUtils.nextLF(rawTag, p) - 1; _tagName = RawParseUtils.decode(Constants.CHARSET, rawTag, p, nameEnd); if (walk.isRetainBody()) { _buffer = rawTag; } Flags |= PARSED; }
/// <summary> /// Adds a new or existing file with the specified name to this tree. /// Trees are added if necessary as the name may contain '/':s. /// </summary> /// <param name="s"> an array containing the name </param> /// <param name="offset"> when the name starts in the tree. /// </param> /// <returns>A <seealso cref="FileTreeEntry"/> for the added file.</returns> /// <exception cref="IOException"></exception> public FileTreeEntry AddFile(byte[] s, int offset) { int slash; for (slash = offset; slash < s.Length && s[slash] != '/'; slash++) { // search for path component terminator // [henon] body is empty by intention! } EnsureLoaded(); byte xlast = slash < s.Length ? (byte)'/' : (byte)0; int p = BinarySearch(_contents, s, xlast, offset, slash); if (p >= 0 && slash < s.Length && _contents[p] is Tree) { return(((Tree)_contents[p]).AddFile(s, slash + 1)); } byte[] newName = SubString(s, offset, slash); if (p >= 0) { throw new EntryExistsException(RawParseUtils.decode(newName)); } if (slash < s.Length) { Tree t = new Tree(this, newName); InsertEntry(p, t); return(t.AddFile(s, slash + 1)); } FileTreeEntry f = new FileTreeEntry(this, null, newName, false); InsertEntry(p, f); return(f); }
/// <summary> /// /// Extract the email address (if present) from the footer. /// <para /> /// If there is an email address looking string inside of angle brackets /// (e.g. "<a@b>"), the return value is the part extracted from inside the /// brackets. If no brackets are found, then <see cref="Value"/> is returned /// if the value contains an '@' sign. Otherwise, null. /// </summary> /// <returns>email address appearing in the value of this footer, or null.</returns> public string getEmailAddress() { int lt = RawParseUtils.nextLF(_buffer, _valStart, (byte)'<'); if (_valEnd <= lt) { int at = RawParseUtils.nextLF(_buffer, _valStart, (byte)'@'); if (_valStart < at && at < _valEnd) { return(Value); } return(null); } int gt = RawParseUtils.nextLF(_buffer, lt, (byte)'>'); if (_valEnd < gt) { return(null); } return(RawParseUtils.decode(_enc, _buffer, lt, gt - 1)); }
public virtual void load() { try { fromText(RawParseUtils.decode(IO.ReadFully(getFile()))); } catch (FileNotFoundException) { clear(); } catch (DirectoryNotFoundException) { clear(); } catch (IOException e) { var e2 = new IOException("Cannot read " + getFile(), e); throw e2; } catch (ConfigInvalidException e) { throw new ConfigInvalidException("Cannot read " + getFile(), e); } }
private string readString(int len) { byte[] raw = new byte[len]; IO.ReadFully(ins, raw, 0, len); return(RawParseUtils.decode(Constants.CHARSET, raw, 0, len)); }
/// <summary> /// The constructor from a byte array /// </summary> /// <param name="base">the base configuration file </param> /// <param name="blob">the byte array, should be UTF-8 encoded text. </param> /// <exception cref="ConfigInvalidException"> /// The byte array is not a valid configuration format. /// </exception> public BlobBasedConfig(Config @base, byte[] blob) : base(@base) { fromText(RawParseUtils.decode(blob)); }
private static string NameOf(AbstractTreeIterator i) { return(RawParseUtils.decode(Constants.CHARSET, i.Path, 0, i.PathLen)); }
/// <summary> /// Line of the patch script the error appears on. /// </summary> /// <returns></returns> public string getLineText() { int eol = RawParseUtils.nextLF(_buf, _offset); return(RawParseUtils.decode(Constants.CHARSET, _buf, _offset, eol)); }
/// <summary> /// Parse a "diff --git" or "diff --cc" line. /// </summary> /// <param name="ptr"> /// first character After the "diff --git " or "diff --cc " part. /// </param> /// <param name="end"> /// one past the last position to parse. /// </param> /// <returns> /// first character After the LF at the end of the line; -1 on error. /// </returns> public int parseGitFileName(int ptr, int end) { int eol = RawParseUtils.nextLF(Buffer, ptr); int bol = ptr; if (eol >= end) { return(-1); } // buffer[ptr..eol] looks like "a/foo b/foo\n". After the first // A regex to match this is "^[^/]+/(.*?) [^/+]+/\1\n$". There // is only one way to split the line such that text to the left // of the space matches the text to the right, excluding the part // before the first slash. // int aStart = RawParseUtils.nextLF(Buffer, ptr, (byte)'/'); if (aStart >= eol) { return(eol); } while (ptr < eol) { int sp = RawParseUtils.nextLF(Buffer, ptr, (byte)' '); if (sp >= eol) { // We can't split the header, it isn't valid. // This may be OK if this is a rename patch. // return(eol); } int bStart = RawParseUtils.nextLF(Buffer, sp, (byte)'/'); if (bStart >= eol) { return(eol); } // If buffer[aStart..sp - 1] = buffer[bStart..eol - 1] // we have a valid split. // if (Eq(aStart, sp - 1, bStart, eol - 1)) { if (Buffer[bol] == '"') { // We're a double quoted name. The region better end // in a double quote too, and we need to decode the // characters before reading the name. // if (Buffer[sp - 2] != '"') { return(eol); } oldName = QuotedString.GitPathStyle.GIT_PATH.dequote(Buffer, bol, sp - 1); oldName = P1(oldName); } else { oldName = RawParseUtils.decode(Constants.CHARSET, Buffer, aStart, sp - 1); } newName = oldName; return(eol); } // This split wasn't correct. Move past the space and try // another split as the space must be part of the file name. // ptr = sp; } return(eol); }