예제 #1
0
        public void PutArchiveEntry(IArchiveEntry pEntry)
        {
            if (finished)
            {
                throw new IOException("Stream has already been finished");
            }

            ArArchiveEntry pArEntry = (ArArchiveEntry)pEntry;

            if (prevEntry == null)
            {
                WriteArchiveHeader();
            }
            else
            {
                if (prevEntry.GetLength() != entryOffset)
                {
                    throw new IOException("length does not match entry (" + prevEntry.GetLength() + " != " + entryOffset);
                }

                if (haveUnclosedEntry)
                {
                    CloseArchiveEntry();
                }
            }

            prevEntry = pArEntry;

            WriteEntryHeader(pArEntry);

            entryOffset       = 0;
            haveUnclosedEntry = true;
        }
예제 #2
0
        public override bool Equals(Object obj)
        {
            if (this == obj)
            {
                return(true);
            }
            if (obj == null || this.GetType() != obj.GetType())
            {
                return(false);
            }
            ArArchiveEntry other = (ArArchiveEntry)obj;

            if (Name == null)
            {
                if (other.Name != null)
                {
                    return(false);
                }
            }
            else if (!Name.Equals(other.Name))
            {
                return(false);
            }
            return(true);
        }
예제 #3
0
 /**
  * Calls finish if necessary, and then closes the OutputStream
  */
 public override void Close()
 {
     if(!finished) {
         Finish();
     }
     @out.Close();
     prevEntry = null;
 }
예제 #4
0
        /*
         * (non-Javadoc)
         *
         * @see java.io.InputStream#close()
         */

        public override void Close()
        {
            if (!closed)
            {
                closed = true;
                input.Close();
            }
            currentEntry = null;
        }
예제 #5
0
 /**
  * Calls finish if necessary, and then closes the OutputStream
  */
 public override void Close()
 {
     if (!finished)
     {
         Finish();
     }
     @out.Close();
     prevEntry = null;
 }
예제 #6
0
        /**
         * Returns the next AR entry in this stream.
         *
         * @return the next AR entry.
         * @throws IOException
         *             if the entry could not be read
         */
        public ArArchiveEntry GetNextArEntry()
        {
            if (currentEntry != null)
            {
                long entryEnd = entryOffset + currentEntry.GetLength();
                //IOUtils.skip(this, entryEnd - offset);
                Seek(entryEnd - offset, SeekOrigin.Current);
                currentEntry = null;
            }

            if (offset == 0)
            {
                byte[] expected = Encoding.ASCII.GetBytes(ArArchiveEntry.HEADER);
                byte[] realized = new byte[expected.Length];
                //int read = IOUtils.readFully(this, realized);
                int read = Read(realized, 0, expected.Length);
                if (read != expected.Length)
                {
                    throw new IOException("failed to read header. Occured at byte: " + GetBytesRead());
                }
                for (int i = 0; i < expected.Length; i++)
                {
                    if (expected[i] != realized[i])
                    {
                        throw new IOException("invalid header " + System.Text.Encoding.ASCII.GetString(realized));
                    }
                }
            }

            if (offset % 2 != 0 && Read() < 0)
            {
                // hit eof
                return(null);
            }

            if (input.available() == 0)
            {
                return(null);
            }

            Read(NAME_BUF, 0, NAME_BUF.Length);
            Read(LAST_MODIFIED_BUF, 0, LAST_MODIFIED_BUF.Length);
            Read(ID_BUF, 0, ID_BUF.Length);
            int userId = AsInt(ID_BUF, true);

            Read(ID_BUF, 0, ID_BUF.Length);
            Read(FILE_MODE_BUF, 0, FILE_MODE_BUF.Length);
            Read(LENGTH_BUF, 0, LENGTH_BUF.Length);

            {
                byte[] expected = Encoding.ASCII.GetBytes(ArArchiveEntry.TRAILER);
                byte[] realized = new byte[expected.Length];
                int    read     = Read(realized, 0, realized.Length);
                if (read != expected.Length)
                {
                    throw new IOException("failed to read entry trailer. Occured at byte: " + GetBytesRead());
                }
                for (int i = 0; i < expected.Length; i++)
                {
                    if (expected[i] != realized[i])
                    {
                        throw new IOException("invalid entry trailer. not read the content? Occured at byte: " + GetBytesRead());
                    }
                }
            }

            entryOffset = offset;

            //  GNU ar uses a '/' to mark the end of the filename; this allows for the use of spaces without the use of an extended filename.

            // entry name is stored as ASCII string
            String temp = System.Text.Encoding.ASCII.GetString(NAME_BUF).Trim();

            if (IsGNUStringTable(temp))
            {
                // GNU extended filenames entry
                currentEntry = ReadGNUStringTable(LENGTH_BUF);
                return(GetNextArEntry());
            }

            long len = AsLong(LENGTH_BUF);

            if (temp.EndsWith("/"))
            {
                // GNU terminator
                temp = temp.Substring(0, temp.Length - 1);
            }
            else if (IsGNULongName(temp))
            {
                int off = int.Parse(temp.Substring(1)); // get the offset
                temp = GetExtendedName(off);            // convert to the long name
            }
            else if (IsBSDLongName(temp))
            {
                temp = GetBSDLongName(temp);
                // entry length contained the length of the file name in
                // addition to the real length of the entry.
                // assume file name was ASCII, there is no "standard" otherwise
                int nameLen = temp.Length;
                len         -= nameLen;
                entryOffset += nameLen;
            }

            currentEntry = new ArArchiveEntry(temp, len, userId,
                                              AsInt(ID_BUF, true),
                                              AsInt(FILE_MODE_BUF, 8),
                                              AsLong(LAST_MODIFIED_BUF));
            return(currentEntry);
        }
예제 #7
0
        /**
         * Returns the next AR entry in this stream.
         *
         * @return the next AR entry.
         * @throws IOException
         *             if the entry could not be read
         */
        public ArArchiveEntry GetNextArEntry()
        {
            if (currentEntry != null)
            {
                long entryEnd = entryOffset + currentEntry.GetLength();
                //IOUtils.skip(this, entryEnd - offset);
                Seek(entryEnd - offset, SeekOrigin.Current);
                currentEntry = null;
            }

            if (offset == 0)
            {
                byte[] expected =  Encoding.ASCII.GetBytes(ArArchiveEntry.HEADER);
                byte[] realized = new byte[expected.Length];
                //int read = IOUtils.readFully(this, realized);
                int read = Read(realized, 0, expected.Length);
                if (read != expected.Length) {
                    throw new IOException("failed to read header. Occured at byte: " + GetBytesRead());
                }
                for (int i = 0; i < expected.Length; i++)
                {
                    if (expected[i] != realized[i])
                    {
                        throw new IOException("invalid header " + System.Text.Encoding.ASCII.GetString(realized));
                    }
                }
            }

            if (offset % 2 != 0 && Read() < 0)
            {
                // hit eof
                return null;
            }

            if (input.available() == 0) {
                return null;
            }

            Read(NAME_BUF, 0, NAME_BUF.Length);
            Read(LAST_MODIFIED_BUF, 0, LAST_MODIFIED_BUF.Length);
            Read(ID_BUF, 0, ID_BUF.Length);
            int userId = AsInt(ID_BUF, true);
            Read(ID_BUF, 0, ID_BUF.Length);
            Read(FILE_MODE_BUF, 0, FILE_MODE_BUF.Length);
            Read(LENGTH_BUF, 0, LENGTH_BUF.Length);

            {
                byte[] expected = Encoding.ASCII.GetBytes(ArArchiveEntry.TRAILER);
                byte[] realized = new byte[expected.Length];
                int read = Read(realized, 0, realized.Length);
                if (read != expected.Length)
                {
                    throw new IOException("failed to read entry trailer. Occured at byte: " + GetBytesRead());
                }
                for (int i = 0; i < expected.Length; i++)
                {
                    if (expected[i] != realized[i])
                    {
                        throw new IOException("invalid entry trailer. not read the content? Occured at byte: " + GetBytesRead());
                    }
                }
            }

            entryOffset = offset;

            //  GNU ar uses a '/' to mark the end of the filename; this allows for the use of spaces without the use of an extended filename.

            // entry name is stored as ASCII string
            String temp = System.Text.Encoding.ASCII.GetString(NAME_BUF).Trim();
            if (IsGNUStringTable(temp)) {
                // GNU extended filenames entry
                currentEntry = ReadGNUStringTable(LENGTH_BUF);
                return GetNextArEntry();
            }

            long len = AsLong(LENGTH_BUF);
            if (temp.EndsWith("/"))
            {
                // GNU terminator
                temp = temp.Substring(0, temp.Length - 1);
            }
            else if (IsGNULongName(temp))
            {
                int off = int.Parse(temp.Substring(1));// get the offset
                temp = GetExtendedName(off); // convert to the long name
            }
            else if (IsBSDLongName(temp))
            {
                temp = GetBSDLongName(temp);
                // entry length contained the length of the file name in
                // addition to the real length of the entry.
                // assume file name was ASCII, there is no "standard" otherwise
                int nameLen = temp.Length;
                len -= nameLen;
                entryOffset += nameLen;
            }

            currentEntry = new ArArchiveEntry(temp, len, userId,
                                              AsInt(ID_BUF, true),
                                              AsInt(FILE_MODE_BUF, 8),
                                              AsLong(LAST_MODIFIED_BUF));
            return currentEntry;
        }
예제 #8
0
 /*
  * (non-Javadoc)
  *
  * @see java.io.InputStream#close()
  */
 public override void Close()
 {
     if (!closed) {
         closed = true;
         input.Close();
     }
     currentEntry = null;
 }
예제 #9
0
        private long WriteEntryHeader( ArArchiveEntry pEntry )
        {
            long offset = 0;
            bool mustAppendName = false;

            string n = pEntry.GetName();
            if (LONGFILE_ERROR == longFileMode && n.Length > 16)
            {
                throw new IOException("filename too long, > 16 chars: "+n);
            }
            if (LONGFILE_BSD == longFileMode &&
                (n.Length > 16 || n.IndexOf(" ") > -1))
            {
                mustAppendName = true;
                offset += Write(ArArchiveInputStream.BSD_LONGNAME_PREFIX
                                + string.ValueOf(n.Length));
            } else {
                offset += Write(n);
            }

            offset = Fill(offset, 16, ' ');
            string m = "" + pEntry.GetLastModifiedDate();
            if (m.Length > 12)
            {
                throw new IOException("modified too long");
            }
            offset += Write(m);

            offset = Fill(offset, 28, ' ');
            String u = "" + pEntry.GetUserId();
            if (u.Length > 6)
            {
                throw new IOException("userid too long");
            }
            offset += Write(u);

            offset = Fill(offset, 34, ' ');
            String g = "" + pEntry.GetGroupId();
            if (g.Length > 6)
            {
                throw new IOException("groupid too long");
            }
            offset += Write(g);

            offset = Fill(offset, 40, ' ');
            string fm = "" + int.ToString(pEntry.GetMode(), 8);
            if (fm.Length > 8)
            {
                throw new IOException("filemode too long");
            }
            offset += Write(fm);

            offset = Fill(offset, 48, ' ');
            string s =
                string.ValueOf(pEntry.GetLength()
                               + (mustAppendName ? n.Length : 0));
            if (s.Length > 10)
            {
                throw new IOException("size too long");
            }
            offset += Write(s);

            offset = Fill(offset, 58, ' ');

            offset += Write(ArArchiveEntry.TRAILER);

            if (mustAppendName) {
                offset += Write(n);
            }

            return offset;
        }
예제 #10
0
        public void PutArchiveEntry(IArchiveEntry pEntry )
        {
            if(finished) {
                throw new IOException("Stream has already been finished");
            }

            ArArchiveEntry pArEntry = (ArArchiveEntry)pEntry;
            if (prevEntry == null)
            {
                WriteArchiveHeader();
            } else
            {
                if (prevEntry.GetLength() != entryOffset)
                {
                    throw new IOException("length does not match entry (" + prevEntry.GetLength() + " != " + entryOffset);
                }

                if (haveUnclosedEntry)
                {
                    CloseArchiveEntry();
                }
            }

            prevEntry = pArEntry;

            WriteEntryHeader(pArEntry);

            entryOffset = 0;
            haveUnclosedEntry = true;
        }
예제 #11
0
        private long WriteEntryHeader(ArArchiveEntry pEntry)
        {
            long offset         = 0;
            bool mustAppendName = false;

            string n = pEntry.GetName();

            if (LONGFILE_ERROR == longFileMode && n.Length > 16)
            {
                throw new IOException("filename too long, > 16 chars: " + n);
            }
            if (LONGFILE_BSD == longFileMode &&
                (n.Length > 16 || n.IndexOf(" ") > -1))
            {
                mustAppendName = true;
                offset        += Write(ArArchiveInputStream.BSD_LONGNAME_PREFIX
                                       + string.ValueOf(n.Length));
            }
            else
            {
                offset += Write(n);
            }

            offset = Fill(offset, 16, ' ');
            string m = "" + pEntry.GetLastModifiedDate();

            if (m.Length > 12)
            {
                throw new IOException("modified too long");
            }
            offset += Write(m);

            offset = Fill(offset, 28, ' ');
            String u = "" + pEntry.GetUserId();

            if (u.Length > 6)
            {
                throw new IOException("userid too long");
            }
            offset += Write(u);

            offset = Fill(offset, 34, ' ');
            String g = "" + pEntry.GetGroupId();

            if (g.Length > 6)
            {
                throw new IOException("groupid too long");
            }
            offset += Write(g);

            offset = Fill(offset, 40, ' ');
            string fm = "" + int.ToString(pEntry.GetMode(), 8);

            if (fm.Length > 8)
            {
                throw new IOException("filemode too long");
            }
            offset += Write(fm);

            offset = Fill(offset, 48, ' ');
            string s =
                string.ValueOf(pEntry.GetLength()
                               + (mustAppendName ? n.Length : 0));

            if (s.Length > 10)
            {
                throw new IOException("size too long");
            }
            offset += Write(s);

            offset = Fill(offset, 58, ' ');

            offset += Write(ArArchiveEntry.TRAILER);

            if (mustAppendName)
            {
                offset += Write(n);
            }

            return(offset);
        }