Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

203 lines
4.1 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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;
}
public ZlibFileFuncDef IOFunctions {
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;
ZlibFileFuncDef f = new ZlibFileFuncDef();
f.opaque = IntPtr.Zero;
f.zclose_file = CloseFile_Native;
f.zerror_file = TestError_Native;
f.zopen_file = OpenFile_Native;
f.zread_file = ReadFile_Native;
f.zseek_file = SeekFile_Native;
f.ztell_file = TellFile_Native;
f.zwrite_file = WriteFile_Native;
IOFunctions = f;
}
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);
}
unsafe IntPtr ReadFile_Native (IntPtr opaque, IntPtr stream, IntPtr buffer, IntPtr size)
{
int count = size.ToInt32 ();
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;
}
return new IntPtr (read);
}
IntPtr SeekFile_Native (IntPtr opaque, IntPtr stream, IntPtr offset, int origin)
{
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
return new IntPtr (-1);
Seek (offset.ToInt64 (), seek);
return new IntPtr (0);
}
IntPtr TellFile_Native (IntPtr opaque, IntPtr stream)
{
if (IntPtr.Size == 4)
return new IntPtr ((int)Position);
else if (IntPtr.Size == 8)
return new IntPtr (Position);
else
return new IntPtr (-1);
}
int TestError_Native (IntPtr opaque, IntPtr stream)
{
// No errors here.
return 0;
}
unsafe IntPtr WriteFile_Native (IntPtr opaque, IntPtr stream, IntPtr buffer, /* ulong */ IntPtr size)
{
int count = size.ToInt32 ();
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 {
}
return new IntPtr (count);
}
}
}