Стартовый пул
This commit is contained in:
@@ -0,0 +1,401 @@
|
||||
(* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corpotation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Takanori Itou <necottie@nesitive.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** *)
|
||||
unit nsStream;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
nsXPCOM, Classes,nsTypes;
|
||||
|
||||
function NS_NewByteArrayInputStream(out stream: nsIInputStream; const Buffer: Pointer; Size: Longword): nsresult;
|
||||
function NS_NewInputStreamFromTStream(input: TStream; own: Boolean=False): nsIInputStream;
|
||||
function NS_NewOutputStreamFromTStream(output: TStream; own: Boolean=False): nsIOutputStream;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
Math, nsMemory, nsError, SysUtils;
|
||||
|
||||
type
|
||||
nsByteArrayInputStream = class(TInterfacedObject,
|
||||
nsIInputStream)
|
||||
FBuffer: PByte;
|
||||
FNBytes: Longword;
|
||||
FPos: Longword;
|
||||
|
||||
constructor Create(const Buffer: Pointer; nBytes: Longword);
|
||||
destructor Destroy; override;
|
||||
|
||||
procedure Close(); safecall;
|
||||
function Available(): PRUint32; safecall;
|
||||
function Read(aBuf: PAnsiChar; aCount: Longword): PRUint32; safecall;
|
||||
function ReadSegments(aWriter: nsWriteSegmentFun; aClosure: Pointer; aCount: Longword): PRUint32; safecall;
|
||||
function IsNonBlocking(): PRBool; safecall;
|
||||
end;
|
||||
|
||||
constructor nsByteArrayInputStream.Create(const Buffer: Pointer; nBytes: Longword);
|
||||
begin
|
||||
inherited Create;
|
||||
FBuffer := PByte(Buffer);
|
||||
FNBytes := nBytes;
|
||||
FPos := 0;
|
||||
end;
|
||||
|
||||
destructor nsByteArrayInputStream.Destroy;
|
||||
begin
|
||||
if Assigned(FBuffer) then
|
||||
nsMemory.Free(FBuffer);
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function nsByteArrayInputStream.Available(): PRUint32;
|
||||
begin
|
||||
if (FNBytes=0) or not Assigned(FBuffer) then
|
||||
Result := 0
|
||||
else
|
||||
Result := FNBytes - FPos;
|
||||
end;
|
||||
|
||||
procedure CopyMemory(var ADst; const ASrc; ASize: Integer); register; forward;
|
||||
|
||||
function nsByteArrayInputStream.Read(aBuf: PAnsiChar;
|
||||
aCount: Longword): PRUint32;
|
||||
begin
|
||||
if (aCount=0) or (FPos = FNBytes) then
|
||||
Result := 0
|
||||
else
|
||||
begin
|
||||
Assert(Assigned(FBuffer), 'Stream buffer has been released - there''s an ownership problem somewhere!');
|
||||
if not Assigned(FBuffer) then
|
||||
Result := 0
|
||||
else
|
||||
if aCount > (FNBytes - FPos) then
|
||||
begin
|
||||
Result := FNBytes - FPos;
|
||||
CopyMemory(aBuf^, FBuffer^, Result);
|
||||
FPos := FNBytes;
|
||||
end else
|
||||
begin
|
||||
Result := aCount;
|
||||
CopyMemory(aBuf^, FBuffer^, Result);
|
||||
Inc(FPos, aCount);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function nsByteArrayInputStream.ReadSegments(aWriter: nsWriteSegmentFun;
|
||||
aClosure: Pointer;
|
||||
aCount: Longword): PRUint32;
|
||||
var
|
||||
readCount: Longword;
|
||||
rv: Longword;
|
||||
newPtr: PByte;
|
||||
begin
|
||||
if FNBytes=0 then
|
||||
raise EInvalidArgument.Create('nsIInputStream.ReadSegments');
|
||||
|
||||
if (aCount=0) or (FNBytes = FPos) then
|
||||
Result := 0
|
||||
else
|
||||
begin
|
||||
Assert(Assigned(FBuffer), 'Stream buffer has been released - there''s an ownership problem somewhere!');
|
||||
readCount := Min(aCount, FNBytes - FPos);
|
||||
if not Assigned(FBuffer) then
|
||||
Result := 0
|
||||
else
|
||||
begin
|
||||
newPtr := FBuffer;
|
||||
Inc(newPtr, FPos);
|
||||
rv := aWriter(Self, aClosure, PChar(newPtr), FPos, readCount, Result);
|
||||
if NS_SUCCEEDED(rv) then
|
||||
Inc(FPos, readCount);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function nsByteArrayInputStream.IsNonBlocking(): PRBool;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure nsByteArrayInputStream.Close;
|
||||
begin
|
||||
if Assigned(FBuffer) then
|
||||
begin
|
||||
nsMemory.Free(FBuffer);
|
||||
FBuffer := nil;
|
||||
FNBytes := 0;
|
||||
end else
|
||||
raise Exception.Create('nsIInputStream.Close')
|
||||
end;
|
||||
|
||||
function NS_NewByteArrayInputStream(out stream: nsIInputStream; const Buffer: Pointer; Size: Longword): nsresult;
|
||||
begin
|
||||
try
|
||||
stream := nsByteArrayInputStream.Create(Buffer, Size);
|
||||
except
|
||||
Result := NS_ERROR_OUT_OF_MEMORY;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result := NS_OK;
|
||||
end;
|
||||
|
||||
type
|
||||
TInputStream = class(TInterfacedObject,
|
||||
nsIInputStream)
|
||||
FStream: TStream;
|
||||
FOwn: Boolean;
|
||||
constructor Create(stream: TStream; own: Boolean);
|
||||
destructor Destroy; override;
|
||||
|
||||
// nsIInputStream
|
||||
procedure Close(); safecall;
|
||||
function Available(): PRUint32; safecall;
|
||||
function Read(aBuf: PAnsiChar; aCount: PRUint32): PRUint32; safecall;
|
||||
function ReadSegments(aWriter: nsWriteSegmentFun; aClosure: Pointer; aCount: PRUint32): PRUint32; safecall;
|
||||
function IsNonBlocking(): PRBool; safecall;
|
||||
end;
|
||||
|
||||
constructor TInputStream.Create(stream: TStream; own: Boolean);
|
||||
begin
|
||||
inherited Create;
|
||||
FStream := stream;
|
||||
FOwn := own;
|
||||
end;
|
||||
|
||||
destructor TInputStream.Destroy;
|
||||
begin
|
||||
if FOwn then
|
||||
FStream.Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TInputStream.Close;
|
||||
begin
|
||||
if FOwn then
|
||||
begin
|
||||
FStream.Free;
|
||||
FOwn := False;
|
||||
end;
|
||||
FStream := nil;
|
||||
end;
|
||||
|
||||
function TInputStream.Available: PRUint32;
|
||||
var
|
||||
size, pos: Int64;
|
||||
begin
|
||||
size := FStream.Size;
|
||||
pos := FStream.Position;
|
||||
if size>0 then
|
||||
begin
|
||||
Result := PRUint32(size-pos);
|
||||
end else
|
||||
begin
|
||||
Result := High(PRUint32);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TInputStream.Read(aBuf: PAnsiChar; aCount: PRUint32): PRUint32;
|
||||
begin
|
||||
Result := FStream.Read(aBuf^, aCount);
|
||||
end;
|
||||
|
||||
function TInputStream.ReadSegments(aWriter: nsWriteSegmentFun;
|
||||
aClosure: Pointer; aCount: PRUint32): PRUint32;
|
||||
type
|
||||
nsWriteSegmentFunc = function (aInStream: nsIInputStream;
|
||||
aClosure: Pointer;
|
||||
const aFromSegment: Pointer;
|
||||
aToOffset: PRUint32;
|
||||
aCount: PRUint32
|
||||
): PRUint32; safecall;
|
||||
|
||||
var
|
||||
data: Pointer;
|
||||
begin
|
||||
data := nsMemory.Alloc(aCount);
|
||||
try
|
||||
aCount := FStream.Read(data^, aCount);
|
||||
Result := nsWriteSegmentFunc(aWriter)(
|
||||
Self, aClosure, data, FStream.Position, aCount);
|
||||
finally
|
||||
nsMemory.Free(data);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TInputStream.IsNonBlocking: PRBool;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function NS_NewInputStreamFromTStream(input: TStream; own: Boolean): nsIInputStream;
|
||||
begin
|
||||
Result := TInputStream.Create(input, own);
|
||||
end;
|
||||
|
||||
type
|
||||
TOutputStream = class(TInterfacedObject,
|
||||
nsIOutputStream)
|
||||
FStream: TStream;
|
||||
FOwn: Boolean;
|
||||
|
||||
constructor Create(output: TStream; own: Boolean);
|
||||
destructor Destroy; override;
|
||||
|
||||
procedure Close(); safecall;
|
||||
procedure Flush(); safecall;
|
||||
function Write(const aBuf: PAnsiChar; aCount: PRUint32): PRUint32; safecall;
|
||||
function WriteFrom(aFromStream: nsIInputStream; aCount: PRUint32): PRUint32; safecall;
|
||||
function WriteSegments(aReader: nsReadSegmentFun; aClosure: Pointer; aCount: PRUint32): PRUint32; safecall;
|
||||
function IsNonBlocking(): PRBool; safecall;
|
||||
end;
|
||||
|
||||
constructor TOutputStream.Create(output: TStream; own: Boolean);
|
||||
begin
|
||||
inherited Create;
|
||||
FStream := output;
|
||||
FOwn := own;
|
||||
end;
|
||||
|
||||
destructor TOutputStream.Destroy;
|
||||
begin
|
||||
if FOwn then
|
||||
FStream.Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TOutputStream.Close;
|
||||
begin
|
||||
if FOwn then
|
||||
begin
|
||||
FStream.Free;
|
||||
FOwn := False;
|
||||
end;
|
||||
FStream := nil;
|
||||
end;
|
||||
|
||||
procedure TOutputStream.Flush;
|
||||
begin
|
||||
end;
|
||||
|
||||
function TOutputStream.Write(const aBuf: PAnsiChar; aCount: PRUint32): PRUint32;
|
||||
begin
|
||||
Result := FStream.Write(aBuf^, aCount);
|
||||
end;
|
||||
|
||||
function TOutputStream.WriteFrom(aFromStream: nsIInputStream; aCount: PRUint32): PRUint32;
|
||||
var
|
||||
data: Pointer;
|
||||
begin
|
||||
data := nsMemory.Alloc(aCount);
|
||||
try
|
||||
aCount := aFromStream.Read(data, aCount);
|
||||
Result := FStream.Write(data^, aCount);
|
||||
finally
|
||||
nsMemory.Free(data);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TOutputStream.WriteSegments(aReader: nsReadSegmentFun;
|
||||
aClosure: Pointer; aCount: PRUint32): PRUint32;
|
||||
type
|
||||
nsReadSegmentFunc = function (aOutStream: nsIOutputStream;
|
||||
aClosure: Pointer;
|
||||
aToSegment: Pointer;
|
||||
aFromOffset: PRUint32;
|
||||
aCount: PRUint32
|
||||
): PRUint32; safecall;
|
||||
var
|
||||
data: Pointer;
|
||||
begin
|
||||
data := nsMemory.Alloc(aCount);
|
||||
try
|
||||
aCount := nsReadSegmentFunc(aReader)
|
||||
(Self, aClosure, data, FStream.Position, aCount);
|
||||
Result := FStream.Write(data^, aCount);
|
||||
finally
|
||||
nsMemory.Free(data);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TOutputStream.IsNonBlocking: PRBool;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function NS_NewOutputStreamFromTStream(output: TStream; own: Boolean): nsIOutputStream;
|
||||
begin
|
||||
Result := TOutputStream.Create(output, own);
|
||||
end;
|
||||
|
||||
|
||||
{$IFDEF CPU386} //Should be defined with both Delphi and Intel FPC.
|
||||
procedure CopyMemory(var ADst; const ASrc; ASize: Integer);
|
||||
asm
|
||||
push edi
|
||||
push esi
|
||||
pushf
|
||||
|
||||
mov edi, eax
|
||||
mov esi, edx
|
||||
mov edx, ecx
|
||||
shr ecx, 2
|
||||
cld
|
||||
test ecx, ecx
|
||||
jz @@no4
|
||||
|
||||
rep movsd
|
||||
@@no4:
|
||||
and edx, 3
|
||||
test edx, edx
|
||||
jz @@no1
|
||||
mov ecx, edx
|
||||
rep movsb
|
||||
@@no1:
|
||||
popf
|
||||
pop esi
|
||||
pop edi
|
||||
end;
|
||||
{$ELSE}
|
||||
procedure CopyMemory(var ADst; const ASrc; ASize: Integer);
|
||||
begin
|
||||
Move(ASrc, ADst, ASize);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
end.
|
Reference in New Issue
Block a user