Beispiel #1
0
 /// <summary>Read the index from disk, if it has changed on disk.</summary>
 /// <remarks>
 /// Read the index from disk, if it has changed on disk.
 /// <p>
 /// This method tries to avoid loading the index if it has not changed since
 /// the last time we consulted it. A missing index file will be treated as
 /// though it were present but had no file entries in it.
 /// </remarks>
 /// <exception cref="System.IO.IOException">
 /// the index file is present but could not be read. This
 /// DirCache instance may not be populated correctly.
 /// </exception>
 /// <exception cref="NGit.Errors.CorruptObjectException">
 /// the index file is using a format or extension that this
 /// library does not support.
 /// </exception>
 public virtual void Read()
 {
     if (liveFile == null)
     {
         throw new IOException(JGitText.Get().dirCacheDoesNotHaveABackingFile);
     }
     if (!liveFile.Exists())
     {
         Clear();
     }
     else
     {
         if (snapshot == null || snapshot.IsModified(liveFile))
         {
             try
             {
                 FileInputStream inStream = new FileInputStream(liveFile);
                 try
                 {
                     Clear();
                     ReadFrom(inStream);
                 }
                 finally
                 {
                     try
                     {
                         inStream.Close();
                     }
                     catch (IOException)
                     {
                     }
                 }
             }
             catch (FileNotFoundException)
             {
                 // Ignore any close failures.
                 // Someone must have deleted it between our exists test
                 // and actually opening the path. That's fine, its empty.
                 //
                 Clear();
             }
             snapshot = FileSnapshot.Save(liveFile);
         }
     }
 }
Beispiel #2
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
                                                                          , 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);
            }
        }