Mercurial > hg > ucis.core
annotate Util/TapeArchive.cs @ 54:ba4e2cb031e0
Added general purpose tar archive reader class
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Wed, 02 Oct 2013 21:17:30 +0200 |
parents | |
children |
rev | line source |
---|---|
54
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
1 ???using System; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
2 using System.Collections; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
3 using System.Collections.Generic; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
4 using System.IO; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
5 using System.Text; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
6 |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
7 namespace UCIS.Util { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
8 public class TarchiveReader : IDisposable, IEnumerator<TarchiveEntry>, IEnumerable<TarchiveEntry> { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
9 public Stream Source { get; private set; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
10 public TarchiveEntry CurrentEntry { get; private set; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
11 private Int64 SourceOffsetBase = 0; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
12 private Int64 SourceOffset = 0; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
13 private Boolean CanSeek = false; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
14 public TarchiveReader(String tarFile) : this(File.OpenRead(tarFile)) { } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
15 public TarchiveReader(Type type, String resource) : this(type.Assembly.GetManifestResourceStream(type, resource)) { } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
16 public TarchiveReader(Stream tar) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
17 this.Source = tar; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
18 CanSeek = Source.CanSeek; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
19 if (CanSeek) SourceOffset = SourceOffsetBase = Source.Position; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
20 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
21 public void Dispose() { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
22 Source.Dispose(); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
23 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
24 private static String ReadString(Byte[] header, int offset, int maxlength) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
25 int end = Array.IndexOf<Byte>(header, 0, offset, maxlength); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
26 int length = (end == -1) ? maxlength : end - offset; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
27 return Encoding.UTF8.GetString(header, offset, length); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
28 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
29 private void SeekForward(Int64 position) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
30 if (CanSeek) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
31 Source.Seek(position, SeekOrigin.Begin); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
32 SourceOffset = position; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
33 } else { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
34 if (position < SourceOffset) throw new ArgumentOutOfRangeException("Can not seek backwards"); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
35 Byte[] buffer = new Byte[1024]; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
36 while (position > SourceOffset) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
37 int read = Source.Read(buffer, 0, (int)Math.Min(1024, position - SourceOffset)); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
38 if (read <= 0) throw new EndOfStreamException(); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
39 SourceOffset += read; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
40 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
41 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
42 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
43 private Int32 GetPaddedSize(Int32 size) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
44 int padding = size % 512; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
45 if (padding != 0) padding = 512 - padding; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
46 return size + padding; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
47 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
48 private Byte[] ReadAll(int length) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
49 Byte[] buffer = new Byte[length]; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
50 int offset = 0; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
51 while (length > 0) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
52 int read = Source.Read(buffer, offset, length); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
53 if (read <= 0) throw new EndOfStreamException(); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
54 offset += read; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
55 length -= read; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
56 SourceOffset += read; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
57 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
58 return buffer; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
59 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
60 private Boolean IsAllZero(Byte[] header, int offset, int length) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
61 length += offset; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
62 for (int i = offset; i < length; i++) if (header[i] != 0) return false; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
63 return true; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
64 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
65 public TarchiveEntry ReadNext() { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
66 if (CurrentEntry != null) SeekForward(CurrentEntry.Offset + 512 + GetPaddedSize(CurrentEntry.Size)); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
67 CurrentEntry = null; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
68 Byte[] header = ReadAll(512); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
69 if (IsAllZero(header, 0, header.Length)) return null; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
70 Boolean ustar = (ReadString(header, 257, 6) == "ustar"); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
71 String fname = ReadString(header, 0, 100); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
72 String fsizes = ReadString(header, 124, 11); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
73 Int32 fsize = Convert.ToInt32(fsizes, 8); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
74 if (ustar) fname = ReadString(header, 345, 155) + fname; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
75 String ffname = fname.StartsWith("./") ? (fname.Length == 2 ? "/" : fname.Substring(2)) : fname; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
76 ffname = ffname.TrimEnd('/'); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
77 TarchiveEntry entry = new TarchiveEntry() { Reader = this, OriginalName = fname, Offset = SourceOffset - 512, Size = fsize, Name = ffname }; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
78 if (ustar) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
79 entry.IsDirectory = header[156] == '5'; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
80 entry.IsDirectory = header[156] == '0' || header[156] == 0; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
81 } else { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
82 entry.IsDirectory = fname.EndsWith("/"); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
83 entry.IsFile = !entry.IsDirectory && header[156] == '0'; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
84 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
85 return CurrentEntry = entry; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
86 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
87 public int ReadEntryData(TarchiveEntry entry, int fileoffset, Byte[] buffer, int bufferoffset, int count) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
88 if (entry.Reader != this) throw new ArgumentException("The specified entry is not part of this archive"); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
89 if (count < 0) throw new ArgumentOutOfRangeException("count", "Count is negative"); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
90 if (count == 0) return 0; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
91 if (!entry.IsFile) throw new ArgumentException("entry", "Specified entry is not a file"); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
92 if (fileoffset > entry.Size) throw new ArgumentOutOfRangeException("fileoffset", "File offset exceeds file size"); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
93 if (fileoffset == entry.Size) return 0; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
94 if (bufferoffset < 0) throw new ArgumentOutOfRangeException("bufferoffset", "Buffer offset is negative"); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
95 if (bufferoffset + count > buffer.Length) throw new ArgumentOutOfRangeException("count", "Buffer offset and count exceed buffer dimensions"); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
96 SeekForward(entry.Offset + 512 + fileoffset); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
97 int read = Source.Read(buffer, bufferoffset, Math.Min(count, entry.Size - fileoffset)); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
98 if (read > 0) SourceOffset += read; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
99 return read; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
100 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
101 public void SeekToEntry(TarchiveEntry entry) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
102 if (entry.Reader != this) throw new ArgumentException("The specified entry is not part of this archive"); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
103 SeekForward(entry.Offset); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
104 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
105 public Stream GetFileStream(TarchiveEntry entry) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
106 if (entry.Reader != this) throw new ArgumentException("The specified entry is not part of this archive"); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
107 return new ReaderStream(this, entry); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
108 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
109 TarchiveEntry IEnumerator<TarchiveEntry>.Current { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
110 get { return CurrentEntry; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
111 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
112 object IEnumerator.Current { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
113 get { return CurrentEntry; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
114 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
115 bool IEnumerator.MoveNext() { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
116 return ReadNext() != null; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
117 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
118 void IEnumerator.Reset() { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
119 SeekForward(SourceOffsetBase); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
120 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
121 IEnumerator<TarchiveEntry> IEnumerable<TarchiveEntry>.GetEnumerator() { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
122 return this; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
123 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
124 IEnumerator IEnumerable.GetEnumerator() { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
125 return this; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
126 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
127 |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
128 class ReaderStream : Stream { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
129 long position = 0; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
130 public TarchiveReader Source { get; private set; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
131 public TarchiveEntry File { get; private set; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
132 public ReaderStream(TarchiveReader source, TarchiveEntry entry) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
133 this.Source = source; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
134 this.File = entry; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
135 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
136 public override bool CanRead { get { return Source != null && Source.Source.CanRead && Position < Length; } } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
137 public override bool CanSeek { get { return Source != null && Source.Source.CanSeek; } } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
138 public override bool CanWrite { get { return false; } } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
139 protected override void Dispose(bool disposing) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
140 base.Dispose(disposing); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
141 Source = null; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
142 File = null; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
143 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
144 public override long Length { get { return File.Size; } } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
145 public override long Position { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
146 get { return position; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
147 set { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
148 if (value < 0 || value > Length) throw new ArgumentOutOfRangeException("value"); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
149 position = value; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
150 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
151 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
152 public override long Seek(long offset, SeekOrigin origin) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
153 switch (origin) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
154 case SeekOrigin.Begin: Position = offset; break; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
155 case SeekOrigin.Current: Position += offset; break; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
156 case SeekOrigin.End: Position = Length - offset; break; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
157 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
158 return position; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
159 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
160 public override int Read(byte[] buffer, int offset, int count) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
161 int read = Source.ReadEntryData(File, (int)position, buffer, offset, count); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
162 position += read; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
163 return read; |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
164 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
165 public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
166 public override void SetLength(long value) { throw new NotSupportedException(); } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
167 public override void Flush() { } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
168 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
169 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
170 public class TarchiveEntry { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
171 public TarchiveReader Reader { get; internal set; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
172 public String Name { get; internal set; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
173 public String OriginalName { get; internal set; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
174 public Boolean IsDirectory { get; internal set; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
175 public Boolean IsFile { get; internal set; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
176 public Int32 Size { get; internal set; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
177 public Int64 Offset { get; internal set; } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
178 |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
179 public int Read(int fileoffset, Byte[] buffer, int bufferoffset, int count) { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
180 return Reader.ReadEntryData(this, fileoffset, buffer, bufferoffset, count); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
181 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
182 |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
183 public Stream GetStream() { |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
184 return Reader.GetFileStream(this); |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
185 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
186 } |
ba4e2cb031e0
Added general purpose tar archive reader class
Ivo Smits <Ivo@UCIS.nl>
parents:
diff
changeset
|
187 } |