//All code is copyright � 2007, InsomniaSoftware | Manuel Then, All rights reserved.
using System;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace InsomniaSoftware.Server.Sources
{
/// <summary>
/// Delegate for content source response handling
/// </summary>
/// <param name="subPath">The requested file's path relative to the MultiFileSource / The SingeFileSource's name</param>
/// <param name="request">The request which is to be answered</param>
/// <param name="userData">User defined data that was passed to AddSource</param>
/// <param name="source">Source output</param>
/// <returns>ObjectType of the object</returns>
public delegate ObjectType GetSourceCallback(string subPath, HttpRequest request, object userData, out Source source);
/// <summary>
/// Abstract base class for a source
/// </summary>
public abstract class Source : IDisposable
{
/// <summary>
/// Disposes the source
/// </summary>
public virtual void Dispose()
{ }
#region Content operations
/// <summary>
/// Gets the length of the source's content
/// </summary>
/// <returns>Content length</returns>
public abstract int GetLength();
/// <summary>
/// Moves current the position withing the source
/// </summary>
/// <param name="offset">Offset by which the location will move</param>
/// <param name="origin">Position to start moving at</param>
/// <returns>The absolute position within the data</returns>
public abstract int Seek(int offset, SeekOrigin origin);
/// <summary>
/// Reads a specified number of bytes into the given buffer
/// </summary>
/// <param name="buffer">Buffer to be filled</param>
/// <param name="offset">First position in the buffer to be filled</param>
/// <param name="count">Number of bytes to be read</param>
/// <returns>The actual number of bytes read</returns>
public abstract int Read(ref byte[] buffer, int offset, int count);
/// <summary>
/// Reads the next byte without advancing
/// </summary>
/// <returns></returns>
public int ReadByte()
{
byte[] buffer = new byte[1];
int readLength = Read(ref buffer, 0, 1);
if (readLength == 1)
return (int)buffer[0];
else
return -1;
}
#endregion
/// <summary>
/// Gets the content type of this source's content
/// </summary>
/// <returns>ContentType instance</returns>
public virtual ContentType GetContentType()
{
return ContentType.FromMIME("text/html");
}
/// <summary>
/// Gets the SourceInfo
/// </summary>
/// <returns>SourceInfo of this Source</returns>
public virtual SourceInfo GetInformation()
{
return new SourceInfo();
}
}
/// <summary>
/// Enumeration of types of objects returned by sources
/// </summary>
public enum ObjectType
{
/// <summary>
/// The requested object has not been found
/// </summary>
NotFound,
/// <summary>
/// The requested object is a file
/// </summary>
File,
/// <summary>
/// The requested object is a folder
/// </summary>
Folder
}
/// <summary>
/// Describes a cookie
/// </summary>
public struct CookieDescriptor
{
/// <summary>
/// The cookie's name
/// </summary>
public string name;
/// <summary>
/// Value of the cookie to be set
/// </summary>
public string value;
/// <summary>
/// Constructor
/// </summary>
/// <param name="name">The cookie's name</param>
/// <param name="value">Value of the cookie to be set</param>
public CookieDescriptor(string name, string value)
{
this.name = name;
this.value = value;
}
}
/// <summary>
/// Represents information about a source
/// </summary>
public class SourceInfo
{
/// <summary>
/// Status code of the response
/// </summary>
public HttpStatus status = HttpStatus.OK;
/// <summary>
/// Keep the connection alive after processing this request?
/// </summary>
public bool keepConnectionAlive = true;
/// <summary>
/// Additional headers to be added to the response
/// </summary>
public NameValueCollection additionalHeaders = null;
/// <summary>
/// Cookies to be sent to the client
/// </summary>
public LinkedList<CookieDescriptor> cookies = null;
/// <summary>
/// True, if the source allows to be resumed later or to be sent in parts (byte-ranges). False, if not.
/// </summary>
public bool allowResume = false;
/// <summary>
/// Last modification date of the source's content
/// </summary>
public DateTime lastModified = DateTime.Now;
/// <summary>
/// Tag of the source
/// </summary>
public string eTag = null;
/// <summary>
/// Constructor
/// </summary>
public SourceInfo() { }
/// <summary>
/// Constructor
/// </summary>
/// <param name="status">Status code of the response</param>
public SourceInfo(HttpStatus status)
{
this.status = status;
}
}
}