public override void Close()
 {
     if(!finished) {
         Finish();
     }
     this.outStream.Close();
     currentEntry = null;
 }
Example #2
0
 public static void WriteArFile(string output, params string[] inputs)
 {
     using (var stream = new FileOutputStream(output))
         using (var ar = new ArArchiveOutputStream(stream))
         {
             foreach (var file in inputs)
             {
                 var info  = new FileInfo(file);
                 var name  = Path.GetFileName(file);
                 var entry = new ArArchiveEntry(name, info.Length);
                 ar.putArchiveEntry(entry);
                 using (var input = new FileInputStream(file))
                     IOUtils.copy(input, ar);
                 ar.closeArchiveEntry();
             }
         }
 }
        private long WriteEntryHeader(ArArchiveEntry pEntry)
        {
            long offset = 0;

            string longName = null;

            string n = pEntry.Name;
            if (n.Length > 16) {
                // BSD variant
                // Seems to be incorrect or not work on debian ar
                //longName = n;
                //n = "#1/" + n.Length;

                throw new IOException ("filename too long, > 16 chars: " + n);
            }
            offset += Write (n);

            offset = Fill (offset, 16, ' ');
            // TODO: Ojo tiempo .net
            //String m = "" + (pEntry.LastModified / 1000);
            String m = "1264026598";
            if (m.Length > 12) {
                throw new IOException ("modified too long");
            }
            offset += Write (m);

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

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

            offset = Fill (offset, 40, ' ');
            //String fm = "" + Integer.toString(pEntry.Mode, 8);
            String fm = "0100644";
            if (fm.Length > 8) {
                throw new IOException ("filemode too long");
            }
            offset += Write (fm);

            offset = Fill (offset, 48, ' ');
            String s = "" + pEntry.Size;
            if (s.Length > 10) {
                throw new IOException ("size too long");
            }
            offset += Write (s);

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

            offset += Write (ArArchiveEntry.TRAILER);
            if (longName != null)
            {
                offset += Write (longName);
            }
            return offset;
        }
        public override void PutArchiveEntry(ArchiveEntry pEntry)
        {
            if (finished) {
                throw new IOException ("Stream has already been finished");
            }

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

                if (haveUnclosedEntry) {
                    CloseArchiveEntry ();
                }
            }

            currentEntry = pArEntry;

            WriteEntryHeader (pArEntry);

            entryOffset = 0;
            haveUnclosedEntry = true;
        }
        public ArArchiveEntry GetNextArEntry()
        {
            // read to the end of current entry data
            if (currentEntry != null)
            {
                long iread = 0;
                do {
                    iread = this.Read (buffer, 0, buffer.Length);
                } while (iread > 0);
                currentEntry = null;
            }

            if (this.Position == 0)
            {
                // First entry
                // File header
                byte[] expected = new System.Text.ASCIIEncoding ().GetBytes (ArArchiveEntry.HEADER);
                byte[] realized = new byte[expected.Length];
                int read = inputStream.Read (realized, 0, expected.Length);
                this.Count (read);
                if (read != expected.Length)
                {
                    throw new IOException ("failed to read header. Occured at byte: " + this.Position);
                }
                for (int i = 0; i < expected.Length; i++)
                {
                    if (expected[i] != realized[i])
                    {
                        throw new IOException ("invalid header " + new System.Text.ASCIIEncoding ().GetString (realized));
                    }
                }

            }
            if (this.Position % 2 != 0)
            {
                if (inputStream.ReadByte () < 0)
                {
                    // hit eof
                    return null;
                }
                this.Count (1);

            }
            byte[] header = new byte[60];
            int rea = this.inputStream.Read (header, 0, header.Length);
            this.Count (rea);
            if (rea <= 0)
            {
                // Clean end of file;
                return null;
            }
            if (rea != header.Length)
            {
                throw new IOException ("invalid header");
            }
            if (header[58] != 0x60 || header[59] != 0x0A)
            {
                throw new IOException ("invalid magic tail on header");
            }
            string name = Utilidades.UtArrays.LeerTexto (header, 0, 16).Trim ();
            long size = long.Parse (Utilidades.UtArrays.LeerTexto (header, 48, 10).Trim ());

            if (name.EndsWith ("/"))
            {
                name = name.Substring (0, name.Length - 1);
            }
            // TODO Leer todos los campos de la cabecera
            currentEntry = new ArArchiveEntry (name, size);

            // GNU AR
            if (currentEntry.Name.Equals ("/"))
            {
                ReadGNUFilenamesEntry ();
                return GetNextArEntry ();
            }
            else if (currentEntry.Name.StartsWith ("/") && gnuNames.Count > 0)
            {
                currentEntry.name = (string)gnuNames[currentEntry.Name.Substring(1)];
            }

            // BSD AR
            if (currentEntry.Name.StartsWith ("#1/"))
            {
                string t = currentEntry.Name.Substring (3);
                int s = int.Parse (t);

                if (s > 2048) {
                    throw new IOException ("Filename too long (bsd)");
                }
                byte[] buffer2 = new byte[s];
                int l = this.inputStream.Read (buffer2, 0, buffer2.Length);
                if (l != s) {
                    throw new IOException ("Filename error (bsd)");
                }
                currentEntry.name = Utilidades.UtArrays.LeerTexto (buffer2, 0);
            }
            dataStream = new SizeLimiterStream (this.inputStream, currentEntry.Size);

            return currentEntry;
        }