You've already forked linux-packaging-mono
226 lines
5.2 KiB
C#
226 lines
5.2 KiB
C#
//
|
|
// System.Web.HttpPostedFile.cs
|
|
//
|
|
// Author:
|
|
// Dick Porter <dick@ximian.com>
|
|
// Ben Maurer <benm@ximian.com>
|
|
// Miguel de Icaza <miguel@novell.com>
|
|
//
|
|
// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
|
|
using System.IO;
|
|
using System.Security.Permissions;
|
|
|
|
namespace System.Web
|
|
{
|
|
// CAS - no InheritanceDemand here as the class is sealed
|
|
[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
|
|
public sealed class HttpPostedFile {
|
|
string name;
|
|
string content_type;
|
|
Stream stream;
|
|
|
|
class ReadSubStream : Stream {
|
|
Stream s;
|
|
long offset;
|
|
long end;
|
|
long position;
|
|
|
|
public ReadSubStream (Stream s, long offset, long length)
|
|
{
|
|
this.s = s;
|
|
this.offset = offset;
|
|
this.end = offset + length;
|
|
position = offset;
|
|
}
|
|
|
|
public override void Flush ()
|
|
{
|
|
}
|
|
|
|
public override int Read (byte [] buffer, int dest_offset, int count)
|
|
{
|
|
if (buffer == null)
|
|
throw new ArgumentNullException ("buffer");
|
|
|
|
if (dest_offset < 0)
|
|
throw new ArgumentOutOfRangeException ("dest_offset", "< 0");
|
|
|
|
if (count < 0)
|
|
throw new ArgumentOutOfRangeException ("count", "< 0");
|
|
|
|
int len = buffer.Length;
|
|
if (dest_offset > len)
|
|
throw new ArgumentException ("destination offset is beyond array size");
|
|
// reordered to avoid possible integer overflow
|
|
if (dest_offset > len - count)
|
|
throw new ArgumentException ("Reading would overrun buffer");
|
|
|
|
if (count > end - position)
|
|
count = (int) (end - position);
|
|
|
|
if (count <= 0)
|
|
return 0;
|
|
|
|
s.Position = position;
|
|
int result = s.Read (buffer, dest_offset, count);
|
|
if (result > 0)
|
|
position += result;
|
|
else
|
|
position = end;
|
|
|
|
return result;
|
|
}
|
|
|
|
public override int ReadByte ()
|
|
{
|
|
if (position >= end)
|
|
return -1;
|
|
|
|
s.Position = position;
|
|
int result = s.ReadByte ();
|
|
if (result < 0)
|
|
position = end;
|
|
else
|
|
position++;
|
|
|
|
return result;
|
|
}
|
|
|
|
public override long Seek (long d, SeekOrigin origin)
|
|
{
|
|
long real;
|
|
switch (origin) {
|
|
case SeekOrigin.Begin:
|
|
real = offset + d;
|
|
break;
|
|
case SeekOrigin.End:
|
|
real = end + d;
|
|
break;
|
|
case SeekOrigin.Current:
|
|
real = position + d;
|
|
break;
|
|
default:
|
|
throw new ArgumentException ();
|
|
}
|
|
|
|
long virt = real - offset;
|
|
if (virt < 0 || virt > Length)
|
|
throw new ArgumentException ();
|
|
|
|
position = s.Seek (real, SeekOrigin.Begin);
|
|
return position;
|
|
}
|
|
|
|
public override void SetLength (long value)
|
|
{
|
|
throw new NotSupportedException ();
|
|
}
|
|
|
|
public override void Write (byte [] buffer, int offset, int count)
|
|
{
|
|
throw new NotSupportedException ();
|
|
}
|
|
|
|
public override bool CanRead {
|
|
get { return true; }
|
|
}
|
|
public override bool CanSeek {
|
|
get { return true; }
|
|
}
|
|
public override bool CanWrite {
|
|
get { return false; }
|
|
}
|
|
|
|
public override long Length {
|
|
get { return end - offset; }
|
|
}
|
|
|
|
public override long Position {
|
|
get {
|
|
return position - offset;
|
|
}
|
|
set {
|
|
if (value > Length)
|
|
throw new ArgumentOutOfRangeException ();
|
|
|
|
position = Seek (value, SeekOrigin.Begin);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal HttpPostedFile (string name, string content_type, Stream base_stream, long offset, long length)
|
|
{
|
|
this.name = name;
|
|
this.content_type = content_type;
|
|
this.stream = new ReadSubStream (base_stream, offset, length);
|
|
}
|
|
|
|
public string ContentType {
|
|
get {
|
|
return (content_type);
|
|
}
|
|
}
|
|
|
|
public int ContentLength {
|
|
get {
|
|
return (int)stream.Length;
|
|
}
|
|
}
|
|
|
|
public string FileName
|
|
{
|
|
get {
|
|
return (name);
|
|
}
|
|
}
|
|
|
|
public Stream InputStream
|
|
{
|
|
get {
|
|
return (stream);
|
|
}
|
|
}
|
|
|
|
public void SaveAs (string filename)
|
|
{
|
|
byte [] buffer = new byte [16*1024];
|
|
long old_post = stream.Position;
|
|
|
|
try {
|
|
File.Delete (filename);
|
|
using (FileStream fs = File.Create (filename)){
|
|
stream.Position = 0;
|
|
int n;
|
|
|
|
while ((n = stream.Read (buffer, 0, 16*1024)) != 0){
|
|
fs.Write (buffer, 0, n);
|
|
}
|
|
}
|
|
} finally {
|
|
stream.Position = old_post;
|
|
}
|
|
}
|
|
}
|
|
}
|