| 1 | unit IntMemory;
|
|---|
| 2 |
|
|---|
| 3 | interface
|
|---|
| 4 |
|
|---|
| 5 | uses
|
|---|
| 6 | Classes, SysUtils, Int, Channel, Device;
|
|---|
| 7 |
|
|---|
| 8 | type
|
|---|
| 9 |
|
|---|
| 10 | { TMemory }
|
|---|
| 11 |
|
|---|
| 12 | TMemory = class(TChannelDevice)
|
|---|
| 13 | private
|
|---|
| 14 | FSize: TInt;
|
|---|
| 15 | FData: PByte;
|
|---|
| 16 | function GetSize: TInt;
|
|---|
| 17 | procedure SetSize(AValue: TInt);
|
|---|
| 18 | procedure CheckGrow(Address: Integer);
|
|---|
| 19 | public
|
|---|
| 20 | Position: TInt;
|
|---|
| 21 | Grow: Boolean;
|
|---|
| 22 | procedure Assign(Source: TMemory);
|
|---|
| 23 | function Read(Address: TInt; ASize: TIntSize): TInt;
|
|---|
| 24 | function ReadPos(ASize: Byte): TInt;
|
|---|
| 25 | procedure Write(Address: TInt; ASize: TIntSize; Value: TInt);
|
|---|
| 26 | procedure WritePos(ASize: Byte; Value: TInt);
|
|---|
| 27 | procedure WriteStringPos(Value: string);
|
|---|
| 28 | procedure WriteMemoryPos(Memory: TMemory);
|
|---|
| 29 | procedure SetChannel(Channel: TChannel); override;
|
|---|
| 30 | procedure SaveToFile(FileName: string);
|
|---|
| 31 | procedure LoadFromFile(FileName: string);
|
|---|
| 32 | procedure FillZero;
|
|---|
| 33 | procedure Clear;
|
|---|
| 34 | function ToString: string; override;
|
|---|
| 35 | property Size: TInt read FSize write SetSize;
|
|---|
| 36 | constructor Create;
|
|---|
| 37 | destructor Destroy; override;
|
|---|
| 38 | end;
|
|---|
| 39 |
|
|---|
| 40 |
|
|---|
| 41 | implementation
|
|---|
| 42 |
|
|---|
| 43 | resourcestring
|
|---|
| 44 | SOutOfRange = 'Address out of range.';
|
|---|
| 45 |
|
|---|
| 46 | { TMemory }
|
|---|
| 47 |
|
|---|
| 48 | function TMemory.GetSize: TInt;
|
|---|
| 49 | begin
|
|---|
| 50 | Result := MemSize(FData);
|
|---|
| 51 | end;
|
|---|
| 52 |
|
|---|
| 53 | procedure TMemory.SetSize(AValue: TInt);
|
|---|
| 54 | begin
|
|---|
| 55 | FSize := AValue;
|
|---|
| 56 | FData := ReAllocMem(FData, AValue);
|
|---|
| 57 | end;
|
|---|
| 58 |
|
|---|
| 59 | procedure TMemory.CheckGrow(Address: Integer);
|
|---|
| 60 | begin
|
|---|
| 61 | if Grow and (Size < Address) then Size := Address;
|
|---|
| 62 | end;
|
|---|
| 63 |
|
|---|
| 64 | procedure TMemory.Assign(Source: TMemory);
|
|---|
| 65 | begin
|
|---|
| 66 | Size := Source.Size;
|
|---|
| 67 | if FSize > 0 then
|
|---|
| 68 | Move(Source.FData[0], FData[0], FSize);
|
|---|
| 69 | Position := Source.Position;
|
|---|
| 70 | end;
|
|---|
| 71 |
|
|---|
| 72 | function TMemory.Read(Address: TInt; ASize: TIntSize): TInt;
|
|---|
| 73 | begin
|
|---|
| 74 | if Address + ASize > FSize then raise Exception.Create(SOutOfRange);
|
|---|
| 75 | case ASize of
|
|---|
| 76 | 1: Result := PByte(FData + Integer(Address))^;
|
|---|
| 77 | 2: Result := PWord(FData + Integer(Address))^;
|
|---|
| 78 | 4: Result := PDWord(FData + Integer(Address))^;
|
|---|
| 79 | 8: Result := PQWord(FData + Integer(Address))^;
|
|---|
| 80 | end;
|
|---|
| 81 | end;
|
|---|
| 82 |
|
|---|
| 83 | function TMemory.ReadPos(ASize: Byte): TInt;
|
|---|
| 84 | begin
|
|---|
| 85 | Result := Read(Position, ASize);
|
|---|
| 86 | Inc(Position, ASize);
|
|---|
| 87 | end;
|
|---|
| 88 |
|
|---|
| 89 | procedure TMemory.Write(Address: TInt; ASize: TIntSize; Value: TInt);
|
|---|
| 90 | begin
|
|---|
| 91 | if Address + ASize > FSize then raise Exception.Create(SOutOfRange);
|
|---|
| 92 | case ASize of
|
|---|
| 93 | 1: PByte(FData + Integer(Address))^ := Value;
|
|---|
| 94 | 2: PWord(FData + Integer(Address))^ := Value;
|
|---|
| 95 | 4: PDWord(FData + Integer(Address))^ := Value;
|
|---|
| 96 | 8: PQWord(FData + Integer(Address))^ := Value;
|
|---|
| 97 | end;
|
|---|
| 98 | end;
|
|---|
| 99 |
|
|---|
| 100 | procedure TMemory.WritePos(ASize: Byte; Value: TInt);
|
|---|
| 101 | begin
|
|---|
| 102 | CheckGrow(Position + ASize);
|
|---|
| 103 | Write(Position, ASize, Value);
|
|---|
| 104 | Inc(Position, ASize);
|
|---|
| 105 | end;
|
|---|
| 106 |
|
|---|
| 107 | procedure TMemory.WriteStringPos(Value: string);
|
|---|
| 108 | var
|
|---|
| 109 | I: Integer;
|
|---|
| 110 | begin
|
|---|
| 111 | CheckGrow(Position + Length(Value));
|
|---|
| 112 | if Length(Value) > 0 then begin
|
|---|
| 113 | if Position + Length(Value) > FSize then Size := Position + Length(Value);
|
|---|
| 114 | for I := 0 to Length(Value) - 1 do
|
|---|
| 115 | Write(Position + I, 1, Ord(Value[I + 1]));
|
|---|
| 116 | Inc(Position, Length(Value));
|
|---|
| 117 | end;
|
|---|
| 118 | end;
|
|---|
| 119 |
|
|---|
| 120 | procedure TMemory.WriteMemoryPos(Memory: TMemory);
|
|---|
| 121 | begin
|
|---|
| 122 | CheckGrow(Position + Memory.Size);
|
|---|
| 123 | if Memory.Size > 0 then begin
|
|---|
| 124 | if Position + Memory.Size > FSize then Size := Position + Memory.Size;
|
|---|
| 125 | Move(Memory.FData[0], FData[Position], Memory.Size);
|
|---|
| 126 | Inc(Position, Memory.Size);
|
|---|
| 127 | end;
|
|---|
| 128 | end;
|
|---|
| 129 |
|
|---|
| 130 | procedure TMemory.SetChannel(Channel: TChannel);
|
|---|
| 131 | begin
|
|---|
| 132 | Channel.Read := Read;
|
|---|
| 133 | Channel.Write := Write;
|
|---|
| 134 | Channel.GetSize := GetSize;
|
|---|
| 135 | end;
|
|---|
| 136 |
|
|---|
| 137 | procedure TMemory.FillZero;
|
|---|
| 138 | begin
|
|---|
| 139 | FillChar(FData^, FSize, 0);
|
|---|
| 140 | end;
|
|---|
| 141 |
|
|---|
| 142 | procedure TMemory.Clear;
|
|---|
| 143 | begin
|
|---|
| 144 | Size := 0;
|
|---|
| 145 | Position := 0;
|
|---|
| 146 | end;
|
|---|
| 147 |
|
|---|
| 148 | function TMemory.ToString: string;
|
|---|
| 149 | var
|
|---|
| 150 | I: Integer;
|
|---|
| 151 | begin
|
|---|
| 152 | Result := '';
|
|---|
| 153 | for I := 0 to FSize - 1 do
|
|---|
| 154 | Result := Result + ', ' + IntToStr(FData[I]);
|
|---|
| 155 | Delete(Result, 1, 2);
|
|---|
| 156 | end;
|
|---|
| 157 |
|
|---|
| 158 | constructor TMemory.Create;
|
|---|
| 159 | begin
|
|---|
| 160 | FSize := 0;
|
|---|
| 161 | end;
|
|---|
| 162 |
|
|---|
| 163 | destructor TMemory.Destroy;
|
|---|
| 164 | begin
|
|---|
| 165 | Size := 0;
|
|---|
| 166 | inherited;
|
|---|
| 167 | end;
|
|---|
| 168 |
|
|---|
| 169 | procedure TMemory.SaveToFile(FileName: string);
|
|---|
| 170 | var
|
|---|
| 171 | F: TFileStream;
|
|---|
| 172 | begin
|
|---|
| 173 | if FileExists(FileName) then
|
|---|
| 174 | F := TFileStream.Create(FileName, fmOpenWrite)
|
|---|
| 175 | else F := TFileStream.Create(FileName, fmCreate);
|
|---|
| 176 | try
|
|---|
| 177 | if FSize > 0 then F.Write(FData[0], FSize);
|
|---|
| 178 | finally
|
|---|
| 179 | F.Free;
|
|---|
| 180 | end;
|
|---|
| 181 | end;
|
|---|
| 182 |
|
|---|
| 183 | procedure TMemory.LoadFromFile(FileName: string);
|
|---|
| 184 | var
|
|---|
| 185 | F: TFileStream;
|
|---|
| 186 | begin
|
|---|
| 187 | F := TFileStream.Create(FileName, fmOpenRead);
|
|---|
| 188 | try
|
|---|
| 189 | if FSize < F.Size then Size := F.Size;
|
|---|
| 190 | F.Read(FData[0], FSize);
|
|---|
| 191 | finally
|
|---|
| 192 | F.Free;
|
|---|
| 193 | end;
|
|---|
| 194 | end;
|
|---|
| 195 |
|
|---|
| 196 | end.
|
|---|
| 197 |
|
|---|