2014-08-13 10:39:27 +01:00
|
|
|
|
// ZipStream.cs created with MonoDevelop
|
|
|
|
|
// User: alan at 15:16 20/10/2008
|
|
|
|
|
//
|
|
|
|
|
// To change standard headers go to Edit->Preferences->Coding->Standard Headers
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
|
|
|
|
namespace zipsharp
|
|
|
|
|
{
|
|
|
|
|
class ZipStream : Stream
|
|
|
|
|
{
|
|
|
|
|
const int ZLIB_FILEFUNC_SEEK_CUR = 1;
|
|
|
|
|
const int ZLIB_FILEFUNC_SEEK_END = 2;
|
|
|
|
|
const int ZLIB_FILEFUNC_SEEK_SET = 0;
|
|
|
|
|
|
|
|
|
|
bool canRead;
|
|
|
|
|
bool canSeek;
|
|
|
|
|
bool canWrite;
|
|
|
|
|
|
|
|
|
|
public override bool CanRead {
|
|
|
|
|
get { return canRead; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool CanSeek {
|
|
|
|
|
get { return canSeek; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool CanWrite {
|
|
|
|
|
get { return canWrite; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool CanTimeout {
|
|
|
|
|
get { return false; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Stream DataStream {
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
public ZlibFileFuncDef32 IOFunctions32 {
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ZlibFileFuncDef64 IOFunctions64 {
|
2014-08-13 10:39:27 +01:00
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override long Length {
|
|
|
|
|
get { return DataStream.Length; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool OwnsStream {
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override long Position {
|
|
|
|
|
get { return DataStream.Position; }
|
|
|
|
|
set { DataStream.Position = value; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ZipStream (Stream dataStream, bool ownsStream)
|
|
|
|
|
{
|
|
|
|
|
// FIXME: Not necessarily true
|
|
|
|
|
canRead = true;
|
|
|
|
|
canSeek = true;
|
|
|
|
|
canWrite = true;
|
|
|
|
|
|
|
|
|
|
DataStream = dataStream;
|
|
|
|
|
OwnsStream = ownsStream;
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
ZlibFileFuncDef32 f32 = new ZlibFileFuncDef32 ();
|
|
|
|
|
f32.opaque = IntPtr.Zero;
|
|
|
|
|
f32.zclose_file = CloseFile_Native;
|
|
|
|
|
f32.zerror_file = TestError_Native;
|
|
|
|
|
f32.zopen_file = OpenFile_Native;
|
|
|
|
|
f32.zread_file = ReadFile_Native32;
|
|
|
|
|
f32.zseek_file = SeekFile_Native32;
|
|
|
|
|
f32.ztell_file = TellFile_Native32;
|
|
|
|
|
f32.zwrite_file = WriteFile_Native32;
|
|
|
|
|
IOFunctions32 = f32;
|
|
|
|
|
|
|
|
|
|
ZlibFileFuncDef64 f64 = new ZlibFileFuncDef64 ();
|
|
|
|
|
f64.opaque = IntPtr.Zero;
|
|
|
|
|
f64.zclose_file = CloseFile_Native;
|
|
|
|
|
f64.zerror_file = TestError_Native;
|
|
|
|
|
f64.zopen_file = OpenFile_Native;
|
|
|
|
|
f64.zread_file = ReadFile_Native64;
|
|
|
|
|
f64.zseek_file = SeekFile_Native64;
|
|
|
|
|
f64.ztell_file = TellFile_Native64;
|
|
|
|
|
f64.zwrite_file = WriteFile_Native64;
|
|
|
|
|
IOFunctions64 = f64;
|
2014-08-13 10:39:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Dispose(bool disposing)
|
|
|
|
|
{
|
|
|
|
|
if (!disposing)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
DataStream.Flush ();
|
|
|
|
|
if (OwnsStream)
|
|
|
|
|
DataStream.Dispose ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Flush()
|
|
|
|
|
{
|
|
|
|
|
DataStream.Flush ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int Read(byte[] buffer, int offset, int count)
|
|
|
|
|
{
|
|
|
|
|
return DataStream.Read (buffer, offset, count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override long Seek(long offset, SeekOrigin origin)
|
|
|
|
|
{
|
|
|
|
|
DataStream.Seek (offset, origin);
|
|
|
|
|
return DataStream.Position;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void SetLength(long value)
|
|
|
|
|
{
|
|
|
|
|
DataStream.SetLength (value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Write(byte[] buffer, int offset, int count)
|
|
|
|
|
{
|
|
|
|
|
DataStream.Write (buffer, offset, count);
|
|
|
|
|
Flush ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int CloseFile_Native (IntPtr opaque, IntPtr stream)
|
|
|
|
|
{
|
|
|
|
|
Close ();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IntPtr OpenFile_Native (IntPtr opaque, string filename, int mode)
|
|
|
|
|
{
|
|
|
|
|
// always success. The stream is opened in managed code
|
|
|
|
|
return new IntPtr (1);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
unsafe uint ReadFile_Native32 (IntPtr opaque, IntPtr stream, IntPtr buffer, uint size)
|
2014-08-13 10:39:27 +01:00
|
|
|
|
{
|
2017-04-10 11:41:01 +00:00
|
|
|
|
return (uint) ReadFile_Native64 (opaque, stream, buffer, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsafe ulong ReadFile_Native64 (IntPtr opaque, IntPtr stream, IntPtr buffer, ulong size)
|
|
|
|
|
{
|
|
|
|
|
int count = (int) size;
|
2014-08-13 10:39:27 +01:00
|
|
|
|
byte[] b = new byte[count];
|
|
|
|
|
int read;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
read = Math.Max (0, Read (b, 0, count));
|
|
|
|
|
byte* ptrBuffer = (byte*) buffer.ToPointer ();
|
|
|
|
|
for (int i = 0; i < count && i < read; i ++)
|
|
|
|
|
ptrBuffer[i] = b[i];
|
|
|
|
|
} catch {
|
|
|
|
|
read = -1;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
return (ulong) read;
|
2014-08-13 10:39:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
int SeekFile_Native32 (IntPtr opaque, IntPtr stream, uint offset, int origin)
|
|
|
|
|
{
|
|
|
|
|
return (int) SeekFile_Native64 (opaque, stream, offset, origin);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long SeekFile_Native64 (IntPtr opaque, IntPtr stream, ulong offset, int origin)
|
2014-08-13 10:39:27 +01:00
|
|
|
|
{
|
|
|
|
|
SeekOrigin seek;
|
|
|
|
|
if (origin == ZipStream.ZLIB_FILEFUNC_SEEK_CUR)
|
|
|
|
|
seek = SeekOrigin.Current;
|
|
|
|
|
else if (origin == ZLIB_FILEFUNC_SEEK_END)
|
|
|
|
|
seek = SeekOrigin.End;
|
|
|
|
|
else if (origin == ZLIB_FILEFUNC_SEEK_SET)
|
|
|
|
|
seek = SeekOrigin.Begin;
|
|
|
|
|
else
|
2017-04-10 11:41:01 +00:00
|
|
|
|
return -1;
|
2014-08-13 10:39:27 +01:00
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
Seek ((long) offset, seek);
|
2014-08-13 10:39:27 +01:00
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
return 0;
|
2014-08-13 10:39:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
int TellFile_Native32 (IntPtr opaque, IntPtr stream)
|
2014-08-13 10:39:27 +01:00
|
|
|
|
{
|
2017-04-10 11:41:01 +00:00
|
|
|
|
return (int) TellFile_Native64 (opaque, stream);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long TellFile_Native64 (IntPtr opaque, IntPtr stream)
|
|
|
|
|
{
|
|
|
|
|
return Position;
|
2014-08-13 10:39:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TestError_Native (IntPtr opaque, IntPtr stream)
|
|
|
|
|
{
|
|
|
|
|
// No errors here.
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
unsafe uint WriteFile_Native32 (IntPtr opaque, IntPtr stream, IntPtr buffer, /* ulong */ uint size)
|
|
|
|
|
{
|
|
|
|
|
return (uint) WriteFile_Native64 (opaque, stream, buffer, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsafe ulong WriteFile_Native64 (IntPtr opaque, IntPtr stream, IntPtr buffer, /* ulong */ ulong size)
|
2014-08-13 10:39:27 +01:00
|
|
|
|
{
|
2017-04-10 11:41:01 +00:00
|
|
|
|
int count = (int) size;
|
2014-08-13 10:39:27 +01:00
|
|
|
|
byte[] b = new byte[count];
|
|
|
|
|
|
|
|
|
|
byte* ptrBuffer = (byte*) buffer.ToPointer ();
|
|
|
|
|
for (int i = 0; i < count; i ++)
|
|
|
|
|
b[i] = ptrBuffer[i];
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
Write (b, 0, count);
|
|
|
|
|
} catch {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
return (ulong) count;
|
2014-08-13 10:39:27 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|