(*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *)

unit Thrift.Stream;

interface

uses
  Classes,
  SysUtils,
  SysConst,
  RTLConsts,
  Thrift.Utils,
  ActiveX;

type

  IThriftStream = interface
    ['{732621B3-F697-4D76-A1B0-B4DD5A8E4018}']
    procedure Write( const buffer: TBytes; offset: Integer; count: Integer);
    function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer;
    procedure Open;
    procedure Close;
    procedure Flush;
    function IsOpen: Boolean;
    function ToArray: TBytes;
  end;

  TThriftStreamImpl = class( TInterfacedObject, IThriftStream)
  private
    procedure CheckSizeAndOffset( const buffer: TBytes; offset: Integer; count: Integer);
  protected
    procedure Write( const buffer: TBytes; offset: Integer; count: Integer); virtual;
    function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; virtual;
    procedure Open; virtual; abstract;
    procedure Close; virtual; abstract;
    procedure Flush; virtual; abstract;
    function IsOpen: Boolean; virtual; abstract;
    function ToArray: TBytes; virtual; abstract;
  end;

  TThriftStreamAdapterDelphi = class( TThriftStreamImpl )
  private
    FStream : TStream;
    FOwnsStream : Boolean;
  protected
    procedure Write( const buffer: TBytes; offset: Integer; count: Integer); override;
    function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; override;
    procedure Open; override;
    procedure Close; override;
    procedure Flush; override;
    function IsOpen: Boolean; override;
    function ToArray: TBytes; override;
  public
    constructor Create( const AStream: TStream; AOwnsStream : Boolean);
    destructor Destroy; override;
  end;

  TThriftStreamAdapterCOM = class( TThriftStreamImpl)
  private
    FStream : IStream;
  protected
    procedure Write( const buffer: TBytes; offset: Integer; count: Integer); override;
    function Read( var buffer: TBytes; offset: Integer; count: Integer): Integer; override;
    procedure Open; override;
    procedure Close; override;
    procedure Flush; override;
    function IsOpen: Boolean; override;
    function ToArray: TBytes; override;
  public
    constructor Create( const AStream: IStream);
  end;

implementation

{ TThriftStreamAdapterCOM }

procedure TThriftStreamAdapterCOM.Close;
begin
  FStream := nil;
end;

constructor TThriftStreamAdapterCOM.Create( const AStream: IStream);
begin
  inherited Create;
  FStream := AStream;
end;

procedure TThriftStreamAdapterCOM.Flush;
begin
  if IsOpen then
  begin
    if FStream <> nil then
    begin
      FStream.Commit( STGC_DEFAULT );
    end;
  end;
end;

function TThriftStreamAdapterCOM.IsOpen: Boolean;
begin
  Result := FStream <> nil;
end;

procedure TThriftStreamAdapterCOM.Open;
begin

end;

function TThriftStreamAdapterCOM.Read( var buffer: TBytes; offset: Integer; count: Integer): Integer;
begin
  inherited;
  Result := 0;
  if FStream <> nil then
  begin
    if count > 0 then
    begin
      FStream.Read( @buffer[offset], count, @Result);
    end;
  end;
end;

function TThriftStreamAdapterCOM.ToArray: TBytes;
var
  statstg: TStatStg;
  len : Integer;
  NewPos : Int64;
  cbRead : Integer;
begin
  FillChar( statstg, SizeOf( statstg), 0);
  len := 0;
  if IsOpen then
  begin
    if Succeeded( FStream.Stat( statstg, STATFLAG_NONAME )) then
    begin
      len := statstg.cbSize;
    end;
  end;

  SetLength( Result, len );

  if len > 0 then
  begin
    if Succeeded( FStream.Seek( 0, STREAM_SEEK_SET, NewPos) ) then
    begin
      FStream.Read( @Result[0], len, @cbRead);
    end;
  end;
end;

procedure TThriftStreamAdapterCOM.Write( const buffer: TBytes; offset: Integer; count: Integer);
var
  nWritten : Integer;
begin
  inherited;
  if IsOpen then
  begin
    if count > 0 then
    begin
      FStream.Write( @buffer[0], count, @nWritten);
    end;
  end;
end;

{ TThriftStreamImpl }

procedure TThriftStreamImpl.CheckSizeAndOffset(const buffer: TBytes; offset,
  count: Integer);
var
  len : Integer;
begin
  if count > 0 then
  begin
    len := Length( buffer );
    if (offset < 0) or ( offset >= len) then
    begin
      raise ERangeError.Create( SBitsIndexError );
    end;
    if count > len then
    begin
      raise ERangeError.Create( SBitsIndexError );
    end;
  end;
end;

function TThriftStreamImpl.Read(var buffer: TBytes; offset,
  count: Integer): Integer;
begin
  Result := 0;
  CheckSizeAndOffset( buffer, offset, count );
end;

procedure TThriftStreamImpl.Write(const buffer: TBytes; offset, count: Integer);
begin
  CheckSizeAndOffset( buffer, offset, count );
end;

{ TThriftStreamAdapterDelphi }

procedure TThriftStreamAdapterDelphi.Close;
begin
  FStream.Free;
  FStream := nil;
  FOwnsStream := False;
end;

constructor TThriftStreamAdapterDelphi.Create( const AStream: TStream; AOwnsStream: Boolean);
begin
  inherited Create;
  FStream := AStream;
  FOwnsStream := AOwnsStream;
end;

destructor TThriftStreamAdapterDelphi.Destroy;
begin
  if FOwnsStream then
  begin
    FStream.Free;
  end;
  inherited;
end;

procedure TThriftStreamAdapterDelphi.Flush;
begin

end;

function TThriftStreamAdapterDelphi.IsOpen: Boolean;
begin
  Result := FStream <> nil;
end;

procedure TThriftStreamAdapterDelphi.Open;
begin

end;

function TThriftStreamAdapterDelphi.Read(var buffer: TBytes; offset,
  count: Integer): Integer;
begin
  inherited;
  Result := 0;
  if count > 0 then
  begin
    Result := FStream.Read( Pointer(@buffer[offset])^, count)
  end;
end;

function TThriftStreamAdapterDelphi.ToArray: TBytes;
var
  OrgPos : Integer;
  len : Integer;
begin
  len := 0;
  if FStream <> nil then
  begin
    len := FStream.Size;
  end;

  SetLength( Result, len );

  if len > 0 then
  begin
    OrgPos := FStream.Position;
    try
      FStream.Position := 0;
      FStream.ReadBuffer( Pointer(@Result[0])^, len );
    finally
      FStream.Position := OrgPos;
    end;
  end
end;

procedure TThriftStreamAdapterDelphi.Write(const buffer: TBytes; offset,
  count: Integer);
begin
  inherited;
  if count > 0 then
  begin
    FStream.Write( Pointer(@buffer[offset])^, count)
  end;
end;

end.
