예제 #1
0
파일: DirCache.cs 프로젝트: ashmind/ngit
        /// <exception cref="System.IO.IOException"></exception>
        internal virtual void WriteTo(OutputStream os)
        {
            MessageDigest      foot = Constants.NewMessageDigest();
            DigestOutputStream dos  = new DigestOutputStream(os, foot);
            bool extended           = false;

            for (int i = 0; i < entryCnt; i++)
            {
                extended |= sortedEntries[i].IsExtended;
            }
            // Write the header.
            //
            byte[] tmp = new byte[128];
            System.Array.Copy(SIG_DIRC, 0, tmp, 0, SIG_DIRC.Length);
            NB.EncodeInt32(tmp, 4, extended ? 3 : 2);
            NB.EncodeInt32(tmp, 8, entryCnt);
            dos.Write(tmp, 0, 12);
            // Write the individual file entries.
            //
            if (snapshot == null)
            {
                // Write a new index, as no entries require smudging.
                //
                for (int i_1 = 0; i_1 < entryCnt; i_1++)
                {
                    sortedEntries[i_1].Write(dos);
                }
            }
            else
            {
                int smudge_s  = (int)(snapshot.LastModified() / 1000);
                int smudge_ns = ((int)(snapshot.LastModified() % 1000)) * 1000000;
                for (int i_1 = 0; i_1 < entryCnt; i_1++)
                {
                    DirCacheEntry e = sortedEntries[i_1];
                    if (e.MightBeRacilyClean(smudge_s, smudge_ns))
                    {
                        e.SmudgeRacilyClean();
                    }
                    e.Write(dos);
                }
            }
            if (tree != null)
            {
                TemporaryBuffer bb = new TemporaryBuffer.LocalFile();
                tree.Write(tmp, bb);
                bb.Close();
                NB.EncodeInt32(tmp, 0, EXT_TREE);
                NB.EncodeInt32(tmp, 4, (int)bb.Length());
                dos.Write(tmp, 0, 8);
                bb.WriteTo(dos, null);
            }
            os.Write(foot.Digest());
            os.Close();
        }
예제 #2
0
        /// <exception cref="System.IO.IOException"></exception>
        internal virtual void WriteTo(OutputStream os)
        {
            MessageDigest      foot = Constants.NewMessageDigest();
            DigestOutputStream dos  = new DigestOutputStream(os, foot);
            bool extended           = false;

            for (int i = 0; i < entryCnt; i++)
            {
                extended |= sortedEntries[i].IsExtended;
            }
            // Write the header.
            //
            byte[] tmp = new byte[128];
            System.Array.Copy(SIG_DIRC, 0, tmp, 0, SIG_DIRC.Length);
            NB.EncodeInt32(tmp, 4, extended ? 3 : 2);
            NB.EncodeInt32(tmp, 8, entryCnt);
            dos.Write(tmp, 0, 12);
            // Write the individual file entries.
            int smudge_s;
            int smudge_ns;

            if (myLock != null)
            {
                // For new files we need to smudge the index entry
                // if they have been modified "now". Ideally we'd
                // want the timestamp when we're done writing the index,
                // so we use the current timestamp as a approximation.
                myLock.CreateCommitSnapshot();
                snapshot  = myLock.GetCommitSnapshot();
                smudge_s  = (int)(snapshot.LastModified() / 1000);
                smudge_ns = ((int)(snapshot.LastModified() % 1000)) * 1000000;
            }
            else
            {
                // Used in unit tests only
                smudge_ns = 0;
                smudge_s  = 0;
            }
            // Check if tree is non-null here since calling updateSmudgedEntries
            // will automatically build it via creating a DirCacheIterator
            bool writeTree = tree != null;

            if (repository != null && entryCnt > 0)
            {
                UpdateSmudgedEntries();
            }
            for (int i_1 = 0; i_1 < entryCnt; i_1++)
            {
                DirCacheEntry e = sortedEntries[i_1];
                if (e.MightBeRacilyClean(smudge_s, smudge_ns))
                {
                    e.SmudgeRacilyClean();
                }
                e.Write(dos);
            }
            if (writeTree)
            {
                TemporaryBuffer bb = new TemporaryBuffer.LocalFile();
                tree.Write(tmp, bb);
                bb.Close();
                NB.EncodeInt32(tmp, 0, EXT_TREE);
                NB.EncodeInt32(tmp, 4, (int)bb.Length());
                dos.Write(tmp, 0, 8);
                bb.WriteTo(dos, null);
            }
            writeIndexChecksum = foot.Digest();
            os.Write(writeIndexChecksum);
            os.Close();
        }
예제 #3
0
        /// <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
                                                                          , Sharpen.Extensions.ValueOf(ver)));
                }
            }
            entryCnt = NB.DecodeInt32(hdr, 8);
            if (entryCnt < 0)
            {
                throw new CorruptObjectException(JGitText.Get().DIRCHasTooManyEntries);
            }
            snapshot = FileSnapshot.Save(liveFile);
            int smudge_s  = (int)(snapshot.LastModified() / 1000);
            int smudge_ns = ((int)(snapshot.LastModified() % 1000)) * 1000000;
            // 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, smudge_s, smudge_ns);
            }
            // 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), Sharpen.Extensions.ValueOf(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;
                }
                }
            }
            readIndexChecksum = md.Digest();
            if (!Arrays.Equals(readIndexChecksum, hdr))
            {
                throw new CorruptObjectException(JGitText.Get().DIRCChecksumMismatch);
            }
        }