private CpioArchiveEntry ReadOldAsciiEntry()
        {
            CpioArchiveEntry ret = new CpioArchiveEntry(CpioConstants.FORMAT_OLD_ASCII);

            ret.Device = ReadAsciiLong(6, 8);
            ret.Inode = ReadAsciiLong(6, 8);
            long mode = ReadAsciiLong(6, 8);
            if (mode != 0) {
                ret.Mode=mode;
            }
            ret.UID =ReadAsciiLong(6, 8);
            ret.GID=ReadAsciiLong(6, 8);
            ret.NumberOfLinks=ReadAsciiLong(6, 8);
            ret.RemoteDevice=ReadAsciiLong(6, 8);
            ret.Time=ReadAsciiLong(11, 8);
            long namesize = ReadAsciiLong(6, 8);
            ret.Size=ReadAsciiLong(11, 8);
            String name = ReadCString((int) namesize);
            ret.Name=name;
            if (mode == 0 && !name.Equals(CpioConstants.CPIO_TRAILER)){
                throw new IOException("Mode 0 only allowed in the trailer. Found entry: "+ name + " Occured at byte: " + Position);
            }

            return ret;
        }
        private CpioArchiveEntry ReadOldBinaryEntry(bool swapHalfWord)
        {
            CpioArchiveEntry ret = new CpioArchiveEntry (CpioConstants.FORMAT_OLD_BINARY);

            ret.Device = ReadBinaryLong (2, swapHalfWord);
            ret.Inode = ReadBinaryLong (2, swapHalfWord);
            long mode = ReadBinaryLong (2, swapHalfWord);
            if (mode != 0) {
                ret.Mode = mode;
            }
            ret.UID = ReadBinaryLong (2, swapHalfWord);
            ret.GID = ReadBinaryLong (2, swapHalfWord);
            ret.NumberOfLinks = ReadBinaryLong (2, swapHalfWord);
            ret.RemoteDevice = ReadBinaryLong (2, swapHalfWord);
            ret.Time = ReadBinaryLong (4, swapHalfWord);
            long namesize = ReadBinaryLong (2, swapHalfWord);
            ret.Size = ReadBinaryLong (4, swapHalfWord);
            String name = ReadCString ((int)namesize);
            ret.Name = name;
            if (mode == 0 && !name.Equals(CpioConstants.CPIO_TRAILER)){
                throw new IOException("Mode 0 only allowed in the trailer. Found entry: "+name + "Occured at byte: " + Position);
            }
            Skip(ret.HeaderPadCount);

            return ret;
        }
        /**
         * Reads the next CPIO file entry and positions stream at the beginning of
         * the entry data.
         *
         * @return the CPIOArchiveEntry just read
         * @throws IOException
         *             if an I/O error has occurred or if a CPIO file error has
         *             occurred
         */
        public CpioArchiveEntry GetNextCPIOEntry()
        {
            EnsureOpen ();
            if (this.currentEntry != null) {
                CloseEntry ();
            }
            byte[] magic = new byte[2];
            ReadFully (magic, 0, magic.Length);
            if (CpioUtil.ByteArray2long (magic, false) == CpioConstants.MAGIC_OLD_BINARY) {
                this.currentEntry = ReadOldBinaryEntry (false);
            } else if (CpioUtil.ByteArray2long (magic, true) == CpioConstants.MAGIC_OLD_BINARY) {
                this.currentEntry = ReadOldBinaryEntry (true);
            } else {
                byte[] more_magic = new byte[4];
                ReadFully (more_magic, 0, more_magic.Length);
                byte[] tmp = new byte[6];
                System.Array.Copy (magic, tmp, magic.Length);
                System.Array.Copy (more_magic, 0, tmp, magic.Length, more_magic.Length);
                //System.arraycopy(magic, 0, tmp, 0, magic.length);
                //System.arraycopy(more_magic, 0, tmp, magic.length,more_magic.length);
                String magicString = UtArrays.ToAsciiString (tmp);
                if (magicString.Equals (CpioConstants.MAGIC_NEW)) {
                    this.currentEntry = ReadNewEntry (false);
                } else if (magicString.Equals (CpioConstants.MAGIC_NEW_CRC)) {
                    this.currentEntry = ReadNewEntry (true);
                } else if (magicString.Equals (CpioConstants.MAGIC_OLD_ASCII)) {
                    this.currentEntry = ReadOldAsciiEntry ();
                } else {
                    string tmpString = "";
                    foreach (byte b in tmp) {
                        tmpString += b.ToString ("X") + ",";
                    }
                    throw new IOException ("Unknown magic [" + magicString + "][" + tmpString + "]. Occured at byte: " + Position + "/0x" + Position.ToString ("X"));
                }
            }

            this.entryBytesRead = 0;

            if (this.currentEntry.Name.Equals (CpioConstants.CPIO_TRAILER)) {
                int contador = 0;
                while (this.inputStream.ReadByte() >= 0){
                    contador++;
                }
                return null;
            }

            this.dataStream = new SizeLimiterStream (this.inputStream, this.currentEntry.Size);
            if (this.currentEntry.Format == CpioConstants.FORMAT_NEW_CRC) {
                this.dataStream = new ChecksumStream (dataStream, new CpioChecksum ());
            }

            return this.currentEntry;
        }
        private CpioArchiveEntry ReadNewEntry(bool hasCrc)
        {
            CpioArchiveEntry ret;
            if (hasCrc) {
                ret = new CpioArchiveEntry (CpioConstants.FORMAT_NEW_CRC);
            } else {
                ret = new CpioArchiveEntry (CpioConstants.FORMAT_NEW);
            }

            ret.Inode = ReadAsciiLong (8, 16);
            long mode = ReadAsciiLong (8, 16);
            if (mode != 0) {
                // mode is initialised to 0
                ret.Mode = mode;
            }
            ret.UID = ReadAsciiLong(8, 16);
            ret.GID = ReadAsciiLong(8, 16);
            ret.NumberOfLinks = ReadAsciiLong(8, 16);
            ret.Time = ReadAsciiLong(8, 16);
            ret.Size = ReadAsciiLong(8, 16);
            ret.DeviceMaj = ReadAsciiLong(8, 16);
            ret.DeviceMin = ReadAsciiLong(8, 16);
            ret.RemoteDeviceMaj  = ReadAsciiLong(8, 16);
            ret.RemoteDeviceMin = ReadAsciiLong(8, 16);
            long namesize = ReadAsciiLong(8, 16);
            ret.Chksum= ReadAsciiLong(8, 16);
            String name = ReadCString((int) namesize);
            ret.Name = name;
            if (mode == 0 && !name.Equals(CpioConstants.CPIO_TRAILER)){
                throw new IOException("Mode 0 only allowed in the trailer. Found entry name: "+name + " Occured at byte: " + Position);
            }
            Skip(ret.HeaderPadCount);

            return ret;
        }
 private void WriteOldAsciiEntry( CpioArchiveEntry entry)
 {
     WriteAsciiLong(entry.Device, 6, 8);
     WriteAsciiLong(entry.Inode, 6, 8);
     WriteAsciiLong(entry.Mode, 6, 8);
     WriteAsciiLong(entry.UID, 6, 8);
     WriteAsciiLong(entry.GID, 6, 8);
     WriteAsciiLong(entry.NumberOfLinks, 6, 8);
     WriteAsciiLong(entry.RemoteDevice, 6, 8);
     WriteAsciiLong(entry.Time, 11, 8);
     WriteAsciiLong(entry.Name.Length + 1, 6, 8);
     WriteAsciiLong(entry.Size, 11, 8);
     WriteCString(entry.Name);
 }
 private void WriteOldBinaryEntry(CpioArchiveEntry entry, bool swapHalfWord)
 {
     WriteBinaryLong(entry.Device, 2, swapHalfWord);
     WriteBinaryLong(entry.Inode, 2, swapHalfWord);
     WriteBinaryLong(entry.Mode, 2, swapHalfWord);
     WriteBinaryLong(entry.UID, 2, swapHalfWord);
     WriteBinaryLong(entry.GID, 2, swapHalfWord);
     WriteBinaryLong(entry.NumberOfLinks, 2, swapHalfWord);
     WriteBinaryLong(entry.RemoteDevice, 2, swapHalfWord);
     WriteBinaryLong(entry.Time, 4, swapHalfWord);
     WriteBinaryLong(entry.Name.Length + 1, 2, swapHalfWord);
     WriteBinaryLong(entry.Size, 4, swapHalfWord);
     WriteCString(entry.Name);
     Pad(entry.HeaderPadCount);
 }
 private void WriteNewEntry(CpioArchiveEntry entry)
 {
     WriteAsciiLong(entry.Inode, 8, 16);
     WriteAsciiLong(entry.Mode, 8, 16);
     WriteAsciiLong(entry.UID, 8, 16);
     WriteAsciiLong(entry.GID, 8, 16);
     WriteAsciiLong(entry.NumberOfLinks, 8, 16);
     WriteAsciiLong(entry.Time, 8, 16);
     WriteAsciiLong(entry.Size, 8, 16);
     WriteAsciiLong(entry.DeviceMaj, 8, 16);
     WriteAsciiLong(entry.DeviceMin, 8, 16);
     WriteAsciiLong(entry.RemoteDeviceMaj, 8, 16);
     WriteAsciiLong(entry.RemoteDeviceMin, 8, 16);
     WriteAsciiLong(entry.Name.Length + 1, 8, 16);
     WriteAsciiLong(entry.Chksum, 8, 16);
     WriteCString(entry.Name);
     Pad(entry.HeaderPadCount);
 }
 private void WriteHeader(CpioArchiveEntry e)
 {
     switch (e.Format) {
     case CpioConstants.FORMAT_NEW:
         this.Write (UtArrays.ToAsciiBytes (CpioConstants.MAGIC_NEW));
         WriteNewEntry (e);
         break;
     case CpioConstants.FORMAT_NEW_CRC:
         this.Write (UtArrays.ToAsciiBytes (CpioConstants.MAGIC_NEW_CRC));
         WriteNewEntry (e);
         break;
     case CpioConstants.FORMAT_OLD_ASCII:
         this.Write (UtArrays.ToAsciiBytes (CpioConstants.MAGIC_OLD_ASCII));
         WriteOldAsciiEntry (e);
         break;
     case CpioConstants.FORMAT_OLD_BINARY:
         bool swapHalfWord = true;
         WriteBinaryLong (CpioConstants.MAGIC_OLD_BINARY, 2, swapHalfWord);
         WriteOldBinaryEntry (e, swapHalfWord);
         break;
     }
 }
        public override void PutArchiveEntry(ArchiveEntry entry)
        {
            if (finished) {
                throw new IOException ("Stream has already been finished");
            }

            CpioArchiveEntry e = (CpioArchiveEntry)entry;
            EnsureOpen ();
            if (this.entry != null) {
                CloseArchiveEntry ();
                // close previous entry
            }
            if (e.Time == -1) {
                e.Time = DateUtils.CurrentUnixTimeMillis;
            }

            short format = e.Format;
            if (format != this.entryFormat) {
                throw new IOException ("Header format: " + format + " does not match existing format: " + this.entryFormat);
            }
            // TODO Comprobar duplicados
                        /*
               if (this.names.put(e.getName(), e) != null) {
                   throw new IOException("duplicate entry: " + e.getName());
               }
            */
            WriteHeader (e);
            this.entry = e;
            this.written = 0;
        }
        public override void Finish()
        {
            EnsureOpen();
            if (finished) {
                throw new IOException("This archive has already been finished");
            }

            if (this.entry != null) {
                throw new IOException("This archive contains unclosed entries.");
            }
            this.entry = new CpioArchiveEntry(this.entryFormat);
            this.entry.Name=CpioConstants.CPIO_TRAILER;
            this.entry.NumberOfLinks = 1;
            WriteHeader(this.entry);
            CloseArchiveEntry();

            finished = true;
        }
        public override void CloseArchiveEntry()
        {
            // TODO
            if (finished) {
                throw new IOException ("Stream has already been finished");
            }

            EnsureOpen ();

            if (entry == null) {
                throw new IOException ("Trying to close non-existent entry");
            }

            if (this.entry.Size != this.written) {
                throw new IOException ("invalid entry size (expected "
                        + this.entry.Size + " but got " + this.written
                        + " bytes)");
            }
            Pad (this.entry.DataPadCount);
            /*
             * TODO
               if (this.entry.Format == CpioConstants.FORMAT_NEW_CRC) {
                   if (this.crc != this.entry.Chksum) {
                       throw new IOException("CRC Error");
                   }
               }
            */
            this.entry = null;
            //this.crc = 0;
            this.written = 0;
        }