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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }