Ignore:
Timestamp:
Jun 24, 2010, 4:18:03 PM (14 years ago)
Author:
george
Message:
  • Opravy a rozšíření funkčností některých tříd
File:
1 edited

Legend:

Unmodified
Added
Removed
  • BitStream/UBitStream.pas

    r30 r31  
    88
    99uses
    10   Classes, SysUtils, RtlConsts;
     10  Classes, SysUtils, RtlConsts, Math;
    1111
    1212type
     
    1717  TBitStream = class
    1818  private
     19    function GetBit(Index: Integer):Boolean; virtual;
    1920    function GetPosition: LongInt; virtual;
    2021    function GetSize: LongInt; virtual;
     22    procedure SetBit(Index: Integer;const AValue: Boolean); virtual;
    2123    procedure SetPosition(const AValue: LongInt); virtual;
    2224    procedure SetSize(const AValue: LongInt); virtual;
     
    3032    property Position: LongInt read GetPosition write SetPosition;
    3133    property Size: LongInt read GetSize write SetSize;
     34    property Bit[Index: Integer]: Boolean read GetBit write SetBit;
     35
     36    function ReadBit: Boolean;
     37    procedure WriteBit(AValue: Boolean);
     38    function ReadByte: Byte;
     39    procedure WriteByte(AValue: Byte);
    3240  end;
    3341
     
    4351    procedure SetPosition(const AValue: LongInt); override;
    4452    procedure SetSize(const AValue: LongInt); override;
     53    function WriteToByte(var Data: Byte; NewData, Pos, Count: Byte): Byte;
    4554  public
    4655    function Read(var Buffer; Count: Longint): Longint; override;
     
    5665{ TBitStream }
    5766
     67function TBitStream.GetBit(Index: Integer):Boolean;
     68begin
     69  Seek(Index, soBeginning);
     70  Read(Result, 1);
     71end;
     72
    5873function TBitStream.GetPosition:LongInt;
    5974begin
     
    6883  GetSize := Seek(0, soEnd);
    6984  Seek(p, soBeginning);
     85end;
     86
     87procedure TBitStream.SetBit(Index: Integer;const AValue: Boolean);
     88begin
     89  Seek(Index, soBeginning);
     90  Write(AValue, 1);
    7091end;
    7192
     
    123144end;
    124145
     146function TBitStream.ReadBit:Boolean;
     147begin
     148  Read(Result, 1);
     149  Result := Boolean(Integer(Result) and 1);
     150end;
     151
     152procedure TBitStream.WriteBit(AValue:Boolean);
     153begin
     154  Write(AValue, 1);
     155end;
     156
     157function TBitStream.ReadByte:Byte;
     158begin
     159  Read(Result, 8);
     160end;
     161
     162procedure TBitStream.WriteByte(AValue:Byte);
     163begin
     164  Write(AValue, 8);
     165end;
     166
    125167{ TMemoryBitStream }
    126168
     
    143185begin
    144186  FSize := AValue;
    145   Stream.Size := Trunc(AValue / 8) + 1;
     187  Stream.Size := Ceil(AValue / 8);
     188  if FPosition > FSize then FPosition := FSize;
     189end;
     190
     191function TMemoryBitStream.WriteToByte(var Data: Byte; NewData,Pos,Count:Byte):Byte;
     192begin
     193  Data := Byte(Data and not (((1 shl Count) - 1) shl Pos) // Make zero space for new data
     194     or ((NewData and ((1 shl Count) - 1)) shl Pos));  // Write new data
     195  Result := Count;
     196  if Result > (8 - Pos) then Result := 8 - Pos;
    146197end;
    147198
     
    153204  Data: Byte;
    154205begin
    155   if (FPosition + Count) > FSize then Count := FSize - FPosition;
    156   ByteCount := Trunc(Count / 8) + 1;
    157   BytePos := FPosition mod 8;
    158   Stream.Position := Trunc(FPosition / 8);
    159   Data := Stream.ReadByte;
    160   for I := 0 to ByteCount - 1 do begin
    161     TBytes(Buffer)[I] := (Data shr BytePos) and ((1 shl (8 - BytePos)) - 1);
    162     if I <> (ByteCount - 1) then
    163       Data := Stream.ReadByte;
    164     if BytePos > 0 then
    165       TBytes(Buffer)[I] := TBytes(Buffer)[I] or (Data and ((1 shl BytePos) - 1)) shl (8 - BytePos);
    166     if I = (ByteCount - 1) then
    167       TBytes(Buffer)[I] := TBytes(Buffer)[I] and ((1 shl (Count mod 8)) - 1);
    168   end;
    169   Inc(FPosition, Count);
    170   Result := Count;
     206  Result := 0;
     207  if (FSize > 0) and (FPosition < FSize) and (FPosition >= 0) then begin
     208    if (FPosition + Count) > FSize then Count := FSize - FPosition;
     209    ByteCount := Ceil(Count / 8);
     210    BytePos := FPosition mod 8;
     211    Stream.Position := Trunc(FPosition / 8);
     212    Data := Stream.ReadByte;
     213    for I := 0 to ByteCount - 1 do begin
     214      TBytes(Buffer)[I] := (Data shr BytePos) and ((1 shl (8 - BytePos)) - 1);
     215      if I <> (ByteCount - 1) then
     216        Data := Stream.ReadByte;
     217      if BytePos > 0 then
     218        TBytes(Buffer)[I] := TBytes(Buffer)[I] or (Data and ((1 shl BytePos) - 1)) shl (8 - BytePos);
     219      if (I = (ByteCount - 1)) and (BytePos > 0) then
     220        TBytes(Buffer)[I] := TBytes(Buffer)[I] and ((1 shl (Count mod 8)) - 1);
     221    end;
     222    Inc(FPosition, Count);
     223    Result := Count;
     224  end;
    171225end;
    172226
     
    174228var
    175229  ByteCount: LongInt;
     230  BitCount: LongInt;
    176231  I: LongInt;
    177232  BytePos: Byte;
    178233  Data: Byte;
    179 begin
    180   ByteCount := Trunc(Count / 8) + 1;
     234function Min(Value1, Value2: Integer): Integer;
     235begin
     236  if Value1 < Value2 then Result := Value1 else Result := Value2;
     237end;
     238
     239begin
     240  BitCount := Count;
     241  ByteCount := Ceil(Count / 8);
    181242  BytePos := FPosition mod 8;
    182243  Stream.Position := Trunc(FPosition / 8);
     
    186247  end else Data := 0;
    187248  for I := 0 to ByteCount - 1 do begin
    188     Data := (Data and ((1 shl BytePos) - 1)) or
    189       ((TBytes(Buffer)[I] and ((1 shl (8 - BytePos)) - 1)) shl BytePos);
    190     if I = (ByteCount - 1) then
    191       Data := Data and ((1 shl (Count mod 8)) - 1);
     249    Dec(BitCount, WriteToByte(Data, TBytes(Buffer)[I], BytePos, Min(8 - BytePos, BitCount)));
    192250    Stream.WriteByte(Data);
    193     Data := (TBytes(Buffer)[I] shr (8 - BytePos)) and ((1 shl BytePos) - 1);
     251    Data := 0;
     252    if (BitCount > 0) and (BytePos > 0) then begin
     253      if (I = (ByteCount - 1)) and (Stream.Position < Stream.Size) then begin
     254        Data := Stream.ReadByte;
     255        Stream.Position := Stream.Position - 1;
     256      end;
     257      Dec(BitCount, WriteToByte(Data, TBytes(Buffer)[I] shr (8 - BytePos), 0, Min(BytePos, BitCount)));
     258      if I = (ByteCount - 1) then
     259        Stream.WriteByte(Data);
     260    end;
    194261  end;
    195262  Inc(FPosition, Count);
     
    205272    soCurrent: FPosition := FPosition + Offset;
    206273  end;
    207   if FPosition > FSize then FPosition := FSize;
     274  //if FPosition > FSize then FPosition := FSize;
    208275  Result := FPosition;
    209276end;
Note: See TracChangeset for help on using the changeset viewer.