public PackObject GetObjectWithOffset(GitPackReader reader) { Debug.WriteLine("Fetching object with offset: {0}".FormatWith(reader.Position)); // Read first byte, it contains the type and 4 bits of object length byte buffer = reader.ReadByte(); ObjectType type = (ObjectType)((buffer >> 4) & 7); long size = buffer & 0xf; // Read byte while 8th bit is 1. int bitCount = 4; while ((buffer & 0x80) != 0) // >> 7 == 1); { buffer = reader.ReadByte(); size |= ((long)buffer & 0x7f) << bitCount; bitCount += 7; } if (type == ObjectType.RefDelta) { return new REFDelta(size, type, reader); } else if (type == ObjectType.OFSDelta) { return new OFSDelta(size, type, reader); } else { using (MemoryStream inflated = reader.UncompressToLength(size)) { return new Undeltified(size, type, inflated.ToArray()); } } }
public PackObject GetObjectWithOffset(long offset) { using (GitPackReader reader = new GitPackReader(File.OpenRead(Path))) { // Set stream position to offset reader.Position = offset; // Read first byte, it contains the type and 4 bits of object length byte buffer = reader.ReadByte(); ObjectType type = (ObjectType)((buffer >> 4) & 7); long size = buffer & 0xf; // Read byte while 8th bit is 1. int bitCount = 4; do { buffer = reader.ReadByte(); size |= ((long)buffer & 0x7f) << bitCount; bitCount += 7; } while (buffer >> 7 == 1); if (type == ObjectType.RefDelta) { return(new REFDelta(size, type, reader)); } else if (type == ObjectType.OFSDelta) { return(new OFSDelta(size, type, reader)); } else { using (MemoryStream inflated = reader.UncompressToLength(size)) { return(new Undeltified(size, type, inflated.ToArray())); } } } }
public PackObject GetObjectWithOffset(long offset) { using (GitPackReader reader = new GitPackReader(File.OpenRead(Path))) { // Set stream position to offset reader.Position = offset; // Read first byte, it contains the type and 4 bits of object length byte buffer = reader.ReadByte(); ObjectType type = (ObjectType)((buffer >> 4) & 7); long size = buffer & 0xf; // Read byte while 8th bit is 1. int bitCount = 4; do { buffer = reader.ReadByte(); size |= ((long)buffer & 0x7f) << bitCount; bitCount += 7; } while (buffer >> 7 == 1); if (type == ObjectType.RefDelta) { return new REFDelta(size, type, reader); } else if (type == ObjectType.OFSDelta) { return new OFSDelta(size, type, reader); } else { using (MemoryStream inflated = reader.UncompressToLength(size)) { return new Undeltified(size, type, inflated.ToArray()); } } } }
private void VerifyPack() { using (GitPackReader reader = new GitPackReader(File.OpenRead(Path))) { string header; int version, numberOfObjects; header = reader.ReadBytes(4).GetString(); version = reader.ReadBytes(4).Sum(b => b); numberOfObjects = reader.ReadBytes(4).Sum(b => b); if (Version != version) { throw new PackFileException(String.Format("Bad version number {0}. Was expecting {1}", version, Version), Path); } if (HEADER != header) { throw new PackFileException("Invalid header for pack-file. Needs to be: 'PACK'", Path); } } }
private void Load() { string magicNumber; int version; using (GitPackReader reader = new GitPackReader(File.OpenRead(Path))) { magicNumber = reader.ReadBytes(4).GetString(); version = reader.ReadBytes(4).Sum(b => b); if (Version != version) { throw new PackFileException(String.Format("Bad version number {0}. Was expecting {1}", version, Version), Path); } if (MAGIC_NUMBER != magicNumber) { throw new PackFileException("Invalid header for pack-file. Needs to be: 'PACK'", Path); } #region Fanout Table fanout = new int[FANOUT]; shas = new int[FANOUT][]; offsets = new byte[FANOUT][]; crcs = new byte[FANOUT][]; // one big read, faster as 256 small 4 byte read statements ? byte[] fanoutRaw = new byte[FANOUT * 4]; fanoutRaw = reader.ReadBytes(FANOUT * 4); for (int idx = 0; idx < FANOUT; idx++) { fanout[idx] = System.Net.IPAddress.HostToNetworkOrder(BitConverter.ToInt32(fanoutRaw, idx * 4)); } #endregion NumberOfObjects = fanout[FANOUT - 1]; #region SHA's for (int idx = 0; idx < FANOUT; idx++) { int bucketCount; if (idx == 0) { bucketCount = fanout[idx]; } else { bucketCount = fanout[idx] - fanout[idx - 1]; } if (bucketCount == 0) { shas[idx] = new int[] { }; crcs[idx] = new byte[] { }; offsets[idx] = new byte[] { }; continue; } int recordLength = bucketCount * 20; int[] bin = new int[recordLength >> 2]; byte[] rawRecord = reader.ReadBytes(recordLength); for (int i = 0; i < bin.Length; i++) { bin[i] = System.Net.IPAddress.HostToNetworkOrder(BitConverter.ToInt32(rawRecord, i << 2)); } shas[idx] = bin; offsets[idx] = new byte[bucketCount * 4]; crcs[idx] = new byte[bucketCount * 4]; } #endregion #region CRC32 for (int idx = 0; idx < FANOUT; idx++) { crcs[idx] = reader.ReadBytes(crcs[idx].Length); } #endregion #region 32 bit offset table for (int idx = 0; idx < FANOUT; idx++) { offsets[idx] = reader.ReadBytes(offsets[idx].Length); } #endregion // TODO: Support 64 bit tables string packChecksum = reader.ReadBytes(20).GetString(); string idxChecksum = reader.ReadBytes(20).GetString(); } }
private void Load() { string magicNumber; int version; using (GitPackReader reader = new GitPackReader(File.OpenRead(Path))) { magicNumber = reader.ReadBytes(4).GetString(); version = reader.ReadBytes(4).Sum(b => b); if (Version != version) throw new PackFileException(String.Format("Bad version number {0}. Was expecting {1}", version, Version), Path); if (MAGIC_NUMBER != magicNumber) throw new PackFileException("Invalid header for pack-file. Needs to be: 'PACK'", Path); #region Fanout Table fanout = new int[FANOUT]; shas = new int[FANOUT][]; offsets = new byte[FANOUT][]; crcs = new byte[FANOUT][]; // one big read, faster as 256 small 4 byte read statements ? byte[] fanoutRaw = new byte[FANOUT * 4]; fanoutRaw = reader.ReadBytes(FANOUT * 4); for (int idx = 0; idx < FANOUT; idx++) fanout[idx] = System.Net.IPAddress.HostToNetworkOrder(BitConverter.ToInt32(fanoutRaw, idx * 4)); #endregion NumberOfObjects = fanout[FANOUT - 1]; #region SHA's for (int idx = 0; idx < FANOUT; idx++) { int bucketCount; if (idx == 0) bucketCount = fanout[idx]; else bucketCount = fanout[idx] - fanout[idx - 1]; if (bucketCount == 0) { shas[idx] = new int[] { }; crcs[idx] = new byte[] { }; offsets[idx] = new byte[] { }; continue; } int recordLength = bucketCount * 20; int[] bin = new int[recordLength >> 2]; byte[] rawRecord = reader.ReadBytes(recordLength); for (int i = 0; i < bin.Length; i++) { bin[i] = System.Net.IPAddress.HostToNetworkOrder(BitConverter.ToInt32(rawRecord, i << 2)); } shas[idx] = bin; offsets[idx] = new byte[bucketCount * 4]; crcs[idx] = new byte[bucketCount * 4]; } #endregion #region CRC32 for (int idx = 0; idx < FANOUT; idx++) crcs[idx] = reader.ReadBytes(crcs[idx].Length); #endregion #region 32 bit offset table for (int idx = 0; idx < FANOUT; idx++) offsets[idx] = reader.ReadBytes(offsets[idx].Length); #endregion // TODO: Support 64 bit tables string packChecksum = reader.ReadBytes(20).GetString(); string idxChecksum = reader.ReadBytes(20).GetString(); } }
public override IStorableObject GetObject(string sha) { Debug.WriteLine("Fetching object with sha: {0}".FormatWith(sha)); try { if (Index != null) { long packFileOffset = Index.GetPackFileOffset(new Sha(sha)); using (GitPackReader reader = new GitPackReader(File.OpenRead(PackFilePath))) { reader.Position = packFileOffset; PackObject obj = Pack.GetObjectWithOffset(reader); if (obj is Undeltified) { return ((Undeltified)obj).ToGitObject(Repo, sha); } else if (obj is Deltified) { List<Deltified> deltas = new List<Deltified>(); deltas.Add((Deltified)obj); while (obj is Deltified) { if (obj is REFDelta) { string baseSha = ((REFDelta)obj).BaseSHA; packFileOffset = Index.GetPackFileOffset(new Sha(baseSha)); } else { packFileOffset -= ((OFSDelta)obj).BackwardsBaseOffset; } reader.Position = packFileOffset; obj = Pack.GetObjectWithOffset(reader); if (obj is Deltified) deltas.Add((Deltified)obj); } for (int i = deltas.Count - 1; i >= 0; i--) { ((Undeltified)obj).ApplyDelta(deltas[i]); } return ((Undeltified)obj).ToGitObject(Repo, sha); } else { throw new ApplicationException("Don't know what to do with: {0}".FormatWith(obj.GetType().FullName)); } } } else { return Pack.GetObject(sha); } } catch (Exception ex) { throw new PackFileException("Something went wrong while fetching object: {0}".FormatWith(sha), PackFilePath, ex); } }
private void VerifyPack() { using (GitPackReader reader = new GitPackReader(File.OpenRead(Path))) { string header; int version, numberOfObjects; header = reader.ReadBytes(4).GetString(); version = reader.ReadBytes(4).Sum(b => b); numberOfObjects = reader.ReadBytes(4).Sum(b => b); if (Version != version) throw new PackFileException(String.Format("Bad version number {0}. Was expecting {1}", version, Version), Path); if (HEADER != header) throw new PackFileException("Invalid header for pack-file. Needs to be: 'PACK'", Path); } }