예제 #1
0
 /// <exception cref="NGit.Errors.CorruptObjectException"></exception>
 /// <exception cref="System.IO.IOException"></exception>
 internal PackIndexV1(InputStream fd, byte[] hdr)
 {
     byte[] fanoutTable = new byte[IDX_HDR_LEN];
     System.Array.Copy(hdr, 0, fanoutTable, 0, hdr.Length);
     IOUtil.ReadFully(fd, fanoutTable, hdr.Length, IDX_HDR_LEN - hdr.Length);
     idxHeader = new long[256];
     // really unsigned 32-bit...
     for (int k = 0; k < idxHeader.Length; k++)
     {
         idxHeader[k] = NB.DecodeUInt32(fanoutTable, k * 4);
     }
     idxdata = new byte[idxHeader.Length][];
     for (int k_1 = 0; k_1 < idxHeader.Length; k_1++)
     {
         int n;
         if (k_1 == 0)
         {
             n = (int)(idxHeader[k_1]);
         }
         else
         {
             n = (int)(idxHeader[k_1] - idxHeader[k_1 - 1]);
         }
         if (n > 0)
         {
             idxdata[k_1] = new byte[n * (Constants.OBJECT_ID_LENGTH + 4)];
             IOUtil.ReadFully(fd, idxdata[k_1], 0, idxdata[k_1].Length);
         }
     }
     objectCnt    = idxHeader[255];
     packChecksum = new byte[20];
     IOUtil.ReadFully(fd, packChecksum, 0, packChecksum.Length);
 }
예제 #2
0
        /// <exception cref="System.IO.IOException"></exception>
        private void OnOpenPack()
        {
            PackIndex idx = Idx();

            byte[] buf = new byte[20];
            fd.Seek(0);
            fd.ReadFully(buf, 0, 12);
            if (RawParseUtils.Match(buf, 0, Constants.PACK_SIGNATURE) != 4)
            {
                throw new IOException(JGitText.Get().notAPACKFile);
            }
            long vers    = NB.DecodeUInt32(buf, 4);
            long packCnt = NB.DecodeUInt32(buf, 8);

            if (vers != 2 && vers != 3)
            {
                throw new IOException(MessageFormat.Format(JGitText.Get().unsupportedPackVersion,
                                                           Sharpen.Extensions.ValueOf(vers)));
            }
            if (packCnt != idx.GetObjectCount())
            {
                throw new PackMismatchException(MessageFormat.Format(JGitText.Get().packObjectCountMismatch
                                                                     , Sharpen.Extensions.ValueOf(packCnt), Sharpen.Extensions.ValueOf(idx.GetObjectCount
                                                                                                                                           ()), GetPackFile()));
            }
            fd.Seek(length - 20);
            fd.ReadFully(buf, 0, 20);
            if (!Arrays.Equals(buf, packChecksum))
            {
                throw new PackMismatchException(MessageFormat.Format(JGitText.Get().packObjectCountMismatch
                                                                     , ObjectId.FromRaw(buf).Name, ObjectId.FromRaw(idx.packChecksum).Name, GetPackFile
                                                                         ()));
            }
        }
예제 #3
0
        /// <exception cref="NGit.Errors.MissingObjectException"></exception>
        internal override long FindCRC32(AnyObjectId objId)
        {
            int levelOne = objId.FirstByte;
            int levelTwo = BinarySearchLevelTwo(objId, levelOne);

            if (levelTwo == -1)
            {
                throw new MissingObjectException(objId.Copy(), "unknown");
            }
            return(NB.DecodeUInt32(crc32[levelOne], levelTwo << 2));
        }
예제 #4
0
        public override long FindCRC32(AnyObjectId objId)
        {
            int levelOne = objId.GetFirstByte();
            int levelTwo = BinarySearchLevelTwo(objId, levelOne);

            if (levelTwo == -1)
            {
                throw new MissingObjectException(objId.Copy(), ObjectType.Unknown);
            }

            return(NB.DecodeUInt32(_crc32[levelOne], levelTwo << 2));
        }
예제 #5
0
        // p * 5
        internal override long FindOffset(AnyObjectId objId)
        {
            int levelOne = objId.FirstByte;
            int levelTwo = BinarySearchLevelTwo(objId, levelOne);

            if (levelTwo == -1)
            {
                return(-1);
            }
            long p = NB.DecodeUInt32(offset32[levelOne], levelTwo << 2);

            if ((p & IS_O64) != 0)
            {
                return(NB.DecodeUInt64(offset64, (8 * (int)(p & ~IS_O64))));
            }
            return(p);
        }
예제 #6
0
 public override PackIndex.MutableEntry Next()
 {
     for (; this.levelOne < this._enclosing.idxdata.Length; this.levelOne++)
     {
         if (this._enclosing.idxdata[this.levelOne] == null)
         {
             continue;
         }
         if (this.levelTwo < this._enclosing.idxdata[this.levelOne].Length)
         {
             this.entry.offset = NB.DecodeUInt32(this._enclosing.idxdata[this.levelOne], this.
                                                 levelTwo);
             this.levelTwo += Constants.OBJECT_ID_LENGTH + 4;
             this.returnedNumber++;
             return(this.entry);
         }
         this.levelTwo = 0;
     }
     throw new NoSuchElementException();
 }
예제 #7
0
            protected override MutableEntry InnerNext(MutableEntry entry)
            {
                for (; _levelOne < _index._idxdata.Length; _levelOne++)
                {
                    if (_index._idxdata[_levelOne] == null)
                    {
                        continue;
                    }

                    if (_levelTwo < _index._idxdata[_levelOne].Length)
                    {
                        entry.Offset = NB.DecodeUInt32(_index._idxdata[_levelOne], _levelTwo);
                        _levelTwo   += AnyObjectId.ObjectIdLength + 4;
                        ReturnedNumber++;
                        return(entry);
                    }

                    _levelTwo = 0;
                }
                throw new IndexOutOfRangeException();
            }
예제 #8
0
 public override PackIndex.MutableEntry Next()
 {
     for (; this.levelOne < this._enclosing.names.Length; this.levelOne++)
     {
         if (this.levelTwo < this._enclosing.names[this.levelOne].Length)
         {
             int  idx    = this.levelTwo / (Constants.OBJECT_ID_LENGTH / 4) * 4;
             long offset = NB.DecodeUInt32(this._enclosing.offset32[this.levelOne], idx);
             if ((offset & PackIndexV2.IS_O64) != 0)
             {
                 idx    = (8 * (int)(offset & ~PackIndexV2.IS_O64));
                 offset = NB.DecodeUInt64(this._enclosing.offset64, idx);
             }
             this.entry.offset = offset;
             this.levelTwo    += Constants.OBJECT_ID_LENGTH / 4;
             this.returnedNumber++;
             return(this.entry);
         }
         this.levelTwo = 0;
     }
     throw new NoSuchElementException();
 }
예제 #9
0
        private void ReadPackHeader()
        {
            int hdrln = Constants.PACK_SIGNATURE.Length + 4 + 4;
            int p     = FillFromInput(hdrln);

            for (int k = 0; k < Constants.PACK_SIGNATURE.Length; k++)
            {
                if (_buffer[p + k] != Constants.PACK_SIGNATURE[k])
                {
                    throw new IOException("Not a PACK file.");
                }
            }

            long vers = NB.DecodeUInt32(_buffer, p + 4);

            if (vers != 2 && vers != 3)
            {
                throw new IOException("Unsupported pack version " + vers + ".");
            }

            _objectCount = NB.decodeUInt32(_buffer, p + 8);
            Use(hdrln);
        }
예제 #10
0
            protected override MutableEntry InnerNext(MutableEntry entry)
            {
                for (; _levelOne < _index._names.Length; _levelOne++)
                {
                    if (_levelTwo < _index._names[_levelOne].Length)
                    {
                        int  idx    = _levelTwo / (Constants.OBJECT_ID_LENGTH / 4) * 4;
                        long offset = NB.DecodeUInt32(_index._offset32[_levelOne], idx);
                        if ((offset & IS_O64) != 0)
                        {
                            idx    = (8 * (int)(offset & ~IS_O64));
                            offset = NB.DecodeUInt64(_index._offset64, idx);
                        }
                        entry.Offset = offset;

                        _levelTwo += Constants.OBJECT_ID_LENGTH / 4;
                        ReturnedNumber++;
                        return(entry);
                    }
                    _levelTwo = 0;
                }

                throw new IndexOutOfRangeException();
            }
예제 #11
0
        /// <exception cref="System.IO.IOException"></exception>
        internal PackIndexV2(InputStream fd)
        {
            byte[] fanoutRaw = new byte[4 * FANOUT];
            IOUtil.ReadFully(fd, fanoutRaw, 0, fanoutRaw.Length);
            fanoutTable = new long[FANOUT];
            for (int k = 0; k < FANOUT; k++)
            {
                fanoutTable[k] = NB.DecodeUInt32(fanoutRaw, k * 4);
            }
            objectCnt = fanoutTable[FANOUT - 1];
            names     = new int[FANOUT][];
            offset32  = new byte[FANOUT][];
            crc32     = new byte[FANOUT][];
            // Object name table. The size we can permit per fan-out bucket
            // is limited to Java's 2 GB per byte array limitation. That is
            // no more than 107,374,182 objects per fan-out.
            //
            for (int k_1 = 0; k_1 < FANOUT; k_1++)
            {
                long bucketCnt;
                if (k_1 == 0)
                {
                    bucketCnt = fanoutTable[k_1];
                }
                else
                {
                    bucketCnt = fanoutTable[k_1] - fanoutTable[k_1 - 1];
                }
                if (bucketCnt == 0)
                {
                    names[k_1]    = NO_INTS;
                    offset32[k_1] = NO_BYTES;
                    crc32[k_1]    = NO_BYTES;
                    continue;
                }
                long nameLen = bucketCnt * Constants.OBJECT_ID_LENGTH;
                if (nameLen > int.MaxValue)
                {
                    throw new IOException(JGitText.Get().indexFileIsTooLargeForJgit);
                }
                int    intNameLen = (int)nameLen;
                byte[] raw        = new byte[intNameLen];
                int[]  bin        = new int[(int)(((uint)intNameLen) >> 2)];
                IOUtil.ReadFully(fd, raw, 0, raw.Length);
                for (int i = 0; i < bin.Length; i++)
                {
                    bin[i] = NB.DecodeInt32(raw, i << 2);
                }
                names[k_1]    = bin;
                offset32[k_1] = new byte[(int)(bucketCnt * 4)];
                crc32[k_1]    = new byte[(int)(bucketCnt * 4)];
            }
            // CRC32 table.
            for (int k_2 = 0; k_2 < FANOUT; k_2++)
            {
                IOUtil.ReadFully(fd, crc32[k_2], 0, crc32[k_2].Length);
            }
            // 32 bit offset table. Any entries with the most significant bit
            // set require a 64 bit offset entry in another table.
            //
            int o64cnt = 0;

            for (int k_3 = 0; k_3 < FANOUT; k_3++)
            {
                byte[] ofs = offset32[k_3];
                IOUtil.ReadFully(fd, ofs, 0, ofs.Length);
                for (int p = 0; p < ofs.Length; p += 4)
                {
                    if (((sbyte)ofs[p]) < 0)
                    {
                        o64cnt++;
                    }
                }
            }
            // 64 bit offset table. Most objects should not require an entry.
            //
            if (o64cnt > 0)
            {
                offset64 = new byte[o64cnt * 8];
                IOUtil.ReadFully(fd, offset64, 0, offset64.Length);
            }
            else
            {
                offset64 = NO_BYTES;
            }
            packChecksum = new byte[20];
            IOUtil.ReadFully(fd, packChecksum, 0, packChecksum.Length);
        }
예제 #12
0
        public PackIndexV2(Stream fd)
        {
            var fanoutRaw = new byte[4 * FANOUT];

            IO.ReadFully(fd, fanoutRaw, 0, fanoutRaw.Length);
            _fanoutTable = new long[FANOUT];
            for (int k = 0; k < FANOUT; k++)
            {
                _fanoutTable[k] = NB.DecodeUInt32(fanoutRaw, k * 4);
            }
            ObjectCount = _fanoutTable[FANOUT - 1];

            _names    = new int[FANOUT][];
            _offset32 = new byte[FANOUT][];
            _crc32    = new byte[FANOUT][];

            // object name table. The size we can permit per fan-out bucket
            // is limited to Java's 2 GB per byte array limitation. That is
            // no more than 107,374,182 objects per fan-out.
            //
            for (int k = 0; k < FANOUT; k++)
            {
                long bucketCnt;
                if (k == 0)
                {
                    bucketCnt = _fanoutTable[k];
                }
                else
                {
                    bucketCnt = _fanoutTable[k] - _fanoutTable[k - 1];
                }

                if (bucketCnt == 0)
                {
                    _names[k]    = NoInts;
                    _offset32[k] = NoBytes;
                    _crc32[k]    = NoBytes;
                    continue;
                }

                long nameLen = bucketCnt * Constants.OBJECT_ID_LENGTH;
                if (nameLen > int.MaxValue)
                {
                    throw new IOException("Index file is too large");
                }

                var intNameLen = (int)nameLen;
                var raw        = new byte[intNameLen];
                var bin        = new int[intNameLen >> 2];
                IO.ReadFully(fd, raw, 0, raw.Length);
                for (int i = 0; i < bin.Length; i++)
                {
                    bin[i] = NB.DecodeInt32(raw, i << 2);
                }

                _names[k]    = bin;
                _offset32[k] = new byte[(int)(bucketCnt * 4)];
                _crc32[k]    = new byte[(int)(bucketCnt * 4)];
            }

            // CRC32 table.
            for (int k = 0; k < FANOUT; k++)
            {
                IO.ReadFully(fd, _crc32[k], 0, _crc32[k].Length);
            }

            // 32 bit offset table. Any entries with the most significant bit
            // set require a 64 bit offset entry in another table.
            //
            int o64cnt = 0;

            for (int k = 0; k < FANOUT; k++)
            {
                byte[] ofs = _offset32[k];
                IO.ReadFully(fd, ofs, 0, ofs.Length);
                for (int p = 0; p < ofs.Length; p += 4)
                {
                    if (NB.ConvertUnsignedByteToSigned(ofs[p]) < 0)
                    {
                        o64cnt++;
                    }
                }
            }

            // 64 bit offset table. Most objects should not require an entry.
            //
            if (o64cnt > 0)
            {
                _offset64 = new byte[o64cnt * 8];
                IO.ReadFully(fd, _offset64, 0, _offset64.Length);
            }
            else
            {
                _offset64 = NoBytes;
            }

            PackChecksum = new byte[20];
            IO.ReadFully(fd, PackChecksum, 0, PackChecksum.Length);
        }
 /// <exception cref="System.IO.IOException"></exception>
 internal virtual long ReadUInt32()
 {
     ReadFully(intbuf, 0, 4);
     return(NB.DecodeUInt32(intbuf, 0));
 }
예제 #14
0
파일: DirCache.cs 프로젝트: ashmind/ngit
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="NGit.Errors.CorruptObjectException"></exception>
        private void ReadFrom(InputStream inStream)
        {
            BufferedInputStream @in = new BufferedInputStream(inStream);
            MessageDigest       md  = Constants.NewMessageDigest();

            // Read the index header and verify we understand it.
            //
            byte[] hdr = new byte[20];
            IOUtil.ReadFully(@in, hdr, 0, 12);
            md.Update(hdr, 0, 12);
            if (!Is_DIRC(hdr))
            {
                throw new CorruptObjectException(JGitText.Get().notADIRCFile);
            }
            int  ver      = NB.DecodeInt32(hdr, 4);
            bool extended = false;

            if (ver == 3)
            {
                extended = true;
            }
            else
            {
                if (ver != 2)
                {
                    throw new CorruptObjectException(MessageFormat.Format(JGitText.Get().unknownDIRCVersion
                                                                          , ver));
                }
            }
            entryCnt = NB.DecodeInt32(hdr, 8);
            if (entryCnt < 0)
            {
                throw new CorruptObjectException(JGitText.Get().DIRCHasTooManyEntries);
            }
            // Load the individual file entries.
            //
            int infoLength = DirCacheEntry.GetMaximumInfoLength(extended);

            byte[] infos = new byte[infoLength * entryCnt];
            sortedEntries = new DirCacheEntry[entryCnt];
            MutableInteger infoAt = new MutableInteger();

            for (int i = 0; i < entryCnt; i++)
            {
                sortedEntries[i] = new DirCacheEntry(infos, infoAt, @in, md);
            }
            snapshot = FileSnapshot.Save(liveFile);
            // After the file entries are index extensions, and then a footer.
            //
            for (; ;)
            {
                @in.Mark(21);
                IOUtil.ReadFully(@in, hdr, 0, 20);
                if (@in.Read() < 0)
                {
                    // No extensions present; the file ended where we expected.
                    //
                    break;
                }
                @in.Reset();
                md.Update(hdr, 0, 8);
                IOUtil.SkipFully(@in, 8);
                long sz = NB.DecodeUInt32(hdr, 4);
                switch (NB.DecodeInt32(hdr, 0))
                {
                case EXT_TREE:
                {
                    if (int.MaxValue < sz)
                    {
                        throw new CorruptObjectException(MessageFormat.Format(JGitText.Get().DIRCExtensionIsTooLargeAt
                                                                              , FormatExtensionName(hdr), sz));
                    }
                    byte[] raw = new byte[(int)sz];
                    IOUtil.ReadFully(@in, raw, 0, raw.Length);
                    md.Update(raw, 0, raw.Length);
                    tree = new DirCacheTree(raw, new MutableInteger(), null);
                    break;
                }

                default:
                {
                    if (hdr[0] >= 'A' && ((sbyte)hdr[0]) <= 'Z')
                    {
                        // The extension is optional and is here only as
                        // a performance optimization. Since we do not
                        // understand it, we can safely skip past it, after
                        // we include its data in our checksum.
                        //
                        SkipOptionalExtension(@in, md, hdr, sz);
                    }
                    else
                    {
                        // The extension is not an optimization and is
                        // _required_ to understand this index format.
                        // Since we did not trap it above we must abort.
                        //
                        throw new CorruptObjectException(MessageFormat.Format(JGitText.Get().DIRCExtensionNotSupportedByThisVersion
                                                                              , FormatExtensionName(hdr)));
                    }
                    break;
                }
                }
            }
            byte[] exp = md.Digest();
            if (!Arrays.Equals(exp, hdr))
            {
                throw new CorruptObjectException(JGitText.Get().DIRCChecksumMismatch);
            }
        }