Changeset 31 for BitStream/UBitStream.pas
- Timestamp:
- Jun 24, 2010, 4:18:03 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
BitStream/UBitStream.pas
r30 r31 8 8 9 9 uses 10 Classes, SysUtils, RtlConsts ;10 Classes, SysUtils, RtlConsts, Math; 11 11 12 12 type … … 17 17 TBitStream = class 18 18 private 19 function GetBit(Index: Integer):Boolean; virtual; 19 20 function GetPosition: LongInt; virtual; 20 21 function GetSize: LongInt; virtual; 22 procedure SetBit(Index: Integer;const AValue: Boolean); virtual; 21 23 procedure SetPosition(const AValue: LongInt); virtual; 22 24 procedure SetSize(const AValue: LongInt); virtual; … … 30 32 property Position: LongInt read GetPosition write SetPosition; 31 33 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); 32 40 end; 33 41 … … 43 51 procedure SetPosition(const AValue: LongInt); override; 44 52 procedure SetSize(const AValue: LongInt); override; 53 function WriteToByte(var Data: Byte; NewData, Pos, Count: Byte): Byte; 45 54 public 46 55 function Read(var Buffer; Count: Longint): Longint; override; … … 56 65 { TBitStream } 57 66 67 function TBitStream.GetBit(Index: Integer):Boolean; 68 begin 69 Seek(Index, soBeginning); 70 Read(Result, 1); 71 end; 72 58 73 function TBitStream.GetPosition:LongInt; 59 74 begin … … 68 83 GetSize := Seek(0, soEnd); 69 84 Seek(p, soBeginning); 85 end; 86 87 procedure TBitStream.SetBit(Index: Integer;const AValue: Boolean); 88 begin 89 Seek(Index, soBeginning); 90 Write(AValue, 1); 70 91 end; 71 92 … … 123 144 end; 124 145 146 function TBitStream.ReadBit:Boolean; 147 begin 148 Read(Result, 1); 149 Result := Boolean(Integer(Result) and 1); 150 end; 151 152 procedure TBitStream.WriteBit(AValue:Boolean); 153 begin 154 Write(AValue, 1); 155 end; 156 157 function TBitStream.ReadByte:Byte; 158 begin 159 Read(Result, 8); 160 end; 161 162 procedure TBitStream.WriteByte(AValue:Byte); 163 begin 164 Write(AValue, 8); 165 end; 166 125 167 { TMemoryBitStream } 126 168 … … 143 185 begin 144 186 FSize := AValue; 145 Stream.Size := Trunc(AValue / 8) + 1; 187 Stream.Size := Ceil(AValue / 8); 188 if FPosition > FSize then FPosition := FSize; 189 end; 190 191 function TMemoryBitStream.WriteToByte(var Data: Byte; NewData,Pos,Count:Byte):Byte; 192 begin 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; 146 197 end; 147 198 … … 153 204 Data: Byte; 154 205 begin 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; 171 225 end; 172 226 … … 174 228 var 175 229 ByteCount: LongInt; 230 BitCount: LongInt; 176 231 I: LongInt; 177 232 BytePos: Byte; 178 233 Data: Byte; 179 begin 180 ByteCount := Trunc(Count / 8) + 1; 234 function Min(Value1, Value2: Integer): Integer; 235 begin 236 if Value1 < Value2 then Result := Value1 else Result := Value2; 237 end; 238 239 begin 240 BitCount := Count; 241 ByteCount := Ceil(Count / 8); 181 242 BytePos := FPosition mod 8; 182 243 Stream.Position := Trunc(FPosition / 8); … … 186 247 end else Data := 0; 187 248 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))); 192 250 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; 194 261 end; 195 262 Inc(FPosition, Count); … … 205 272 soCurrent: FPosition := FPosition + Offset; 206 273 end; 207 if FPosition > FSize then FPosition := FSize;274 //if FPosition > FSize then FPosition := FSize; 208 275 Result := FPosition; 209 276 end;
Note:
See TracChangeset
for help on using the changeset viewer.