{ $Project$ $Workfile$ $Revision$ $DateUTC$ $Id$ This file is part of the Indy (Internet Direct) project, and is offered under the dual-licensing agreement described on the Indy website. (http://www.indyproject.org/) Copyright: (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. } { $Log$ } { Rev 1.0 27-03-05 10:04:24 MterWoord Second import, first time the filenames weren't prefixed with Id Rev 1.0 27-03-05 09:08:58 MterWoord Created } unit IdSocketStream; interface uses System.IO, System.Net.Sockets, IdStack, System.Collections, IdGlobal; type TIdSocketStream = class(System.IO.Stream) private FInternalSocket: Socket; public function get_CanRead: Boolean; override; function get_CanSeek: Boolean; override; function get_CanWrite: Boolean; override; function get_Length: Int64; override; function get_Position: Int64; override; procedure set_Position(Value: Int64); override; { Private Declarations } public constructor Create(const AInternalSocket: Socket); reintroduce; destructor Destroy; override; procedure Close; override; function Read(ABuffer: array of byte; AOffset: Integer; ACount: Integer) : Integer; override; function ReadByte : Integer; override; function Seek(AOffset: Int64; AOrigin: SeekOrigin) : Int64; override; procedure SetLength(ALength: Int64); override; procedure Write(ABuffer: array of byte; AOffset: integer; ACount: Integer); override; procedure WriteByte(AInput: byte); override; procedure Flush; override; property CanRead: Boolean read get_CanRead; property CanWrite: Boolean read get_CanWrite; property CanSeek: Boolean read get_CanSeek; property Length: Int64 read get_Length; property Position: Int64 read get_Position write set_Position; property InternalSocket: Socket read FInternalSocket; end; implementation procedure TIdSocketStream.Close; begin inherited; end; constructor TIdSocketStream.Create(const AInternalSocket: Socket); begin inherited Create; FInternalSocket := AInternalSocket; end; function TIdSocketStream.get_Length: Int64; begin Result := 0; if FInternalSocket.Poll(1, SelectMode.SelectRead) then Result := FInternalSocket.Available; end; function TIdSocketStream.get_CanSeek: Boolean; begin Result := False; end; function TIdSocketStream.get_CanRead: Boolean; begin Result := True; end; function TIdSocketStream.get_CanWrite: Boolean; begin Result := True; end; function TIdSocketStream.get_Position: Int64; begin Result := 0; end; procedure TIdSocketStream.set_Position(Value: Int64); begin raise NotSupportedException.Create; end; procedure TIdSocketStream.Write(ABuffer: array of byte; AOffset, ACount: Integer); begin try GStack.Send(FInternalSocket, ABuffer, AOffset, ACount); except on E: Exception do begin Console.WriteLine('TIdSocketStream.Write: ' + E.ToString); raise; end; end; end; function TIdSocketStream.ReadByte: Integer; var TempBuff: array[0..1] of byte; begin Result := -1; if Length > 0 then begin if Read(TempBuff, 0, 1) <> 0 then Result := TempBuff[0]; end; end; procedure TIdSocketStream.SetLength(ALength: Int64); begin raise NotSupportedException.Create; end; procedure TIdSocketStream.WriteByte(AInput: byte); begin Write([AInput], 0, 1); end; procedure TIdSocketStream.Flush; begin end; function TIdSocketStream.Seek(AOffset: Int64; AOrigin: SeekOrigin): Int64; begin raise NotSupportedException.Create; end; function TIdSocketStream.Read(ABuffer: array of byte; AOffset, ACount: Integer): Integer; var I: Integer; TempArray: ArrayList; TempBytesToRead: Integer; TempBuff: TIdBytes; BytesRead: Integer; begin try i := 0; TempArray := ArrayList.Create; while i < ACount do begin TempBytesToRead := Math.Min(50, ACount - i); TempBuff := ToBytes(System.&String.Create(#0, TempBytesToRead)); if CanRead then begin BytesRead := GStack.Receive(FInternalSocket, TempBuff); if BytesRead <> 0 then begin &Array.Copy(TempBuff, 0, ABuffer, i + AOffset, BytesRead); Inc(i, BytesRead); if BytesRead <> 50 then Break; end else Break; end else Break; end; Result := i; except on E: Exception do begin Console.WriteLine('Exception "{0}". I = {1}, BytesRead = {2}, AOffset = {3}, ACount = {4}, TempBytesToRead = {5}', [E.GetType().FullName + ': ' + E.Message, I, BytesRead, AOffset, ACount, TempBytesToRead]); raise; end; end; end; destructor TIdSocketStream.Destroy; begin FInternalSocket := nil; inherited; end; end.