source: branches/CpuSingleSize/Memory.pas

Last change on this file was 240, checked in by chronos, 10 months ago
File size: 3.1 KB
Line 
1unit Memory;
2
3interface
4
5uses
6 Classes, SysUtils, Cpu;
7
8type
9
10 { TMemory }
11
12 TMemory = class
13 private
14 FCapacity: Integer;
15 FSize: Integer;
16 function GetItem(Index: Integer): TInteger;
17 procedure SetCapacity(AValue: Integer);
18 procedure SetItem(Index: Integer; AValue: TInteger);
19 procedure SetSize(AValue: Integer);
20 procedure UpdateCapacity(ASize: Integer);
21 public
22 Data: array of TInteger;
23 Position: Integer;
24 procedure Write(Value: TInteger);
25 procedure WriteString(Value: string);
26 procedure WriteMemory(Memory: TMemory);
27 function Read: TInteger;
28 procedure Assign(Source: TMemory);
29 procedure SaveToFile(FileName: string);
30 property Size: Integer read FSize write SetSize;
31 property Capacity: Integer read FCapacity write SetCapacity;
32 property Items[Index: Integer]: TInteger read GetItem write SetItem; default;
33 end;
34
35
36implementation
37
38{ TMemory }
39
40procedure TMemory.SetCapacity(AValue: Integer);
41begin
42 if FCapacity = AValue then Exit;
43 FCapacity := AValue;
44 SetLength(Data, FCapacity);
45 if FSize > FCapacity then FSize := FCapacity;
46end;
47
48function TMemory.GetItem(Index: Integer): TInteger;
49begin
50 Result := Data[Index];
51end;
52
53procedure TMemory.SetItem(Index: Integer; AValue: TInteger);
54begin
55 Data[Index] := AValue;
56end;
57
58procedure TMemory.SetSize(AValue: Integer);
59begin
60 if FSize = AValue then Exit;
61 UpdateCapacity(AValue);
62 FSize := AValue;
63end;
64
65procedure TMemory.UpdateCapacity(ASize: Integer);
66const
67 MinStep = 1000;
68begin
69 if ASize > FSize then begin // Grow
70 if (ASize > Capacity) then begin
71 if ((ASize - Size) < MinStep) then Capacity := Capacity + MinStep
72 else Capacity := ASize;
73 end;
74 end else
75 if ASize < FSize then begin // Shrink
76 if (Capacity - ASize) > MinStep then
77 Capacity := ASize;
78 end;
79end;
80
81procedure TMemory.Write(Value: TInteger);
82begin
83 if Position + 1 > FSize then Size := Position + 1;
84 Data[Position] := Value;
85 Inc(Position);
86end;
87
88procedure TMemory.WriteString(Value: string);
89var
90 I: Integer;
91begin
92 if Length(Value) > 0 then begin
93 if Position + Length(Value) > FSize then Size := Position + Length(Value);
94 for I := 0 to Length(Value) - 1 do
95 Data[Position + I] := Ord(Value[I + 1]);
96 Inc(Position, Length(Value));
97 end;
98end;
99
100procedure TMemory.WriteMemory(Memory: TMemory);
101begin
102 if Memory.Size > 0 then begin
103 if Position + Memory.Size > FSize then Size := Position + Memory.Size;
104 Move(Memory.Data[0], Data[Position], Memory.Size * SizeOf(TInteger));
105 Inc(Position, Memory.Size);
106 end;
107end;
108
109function TMemory.Read: TInteger;
110begin
111 Result := Data[Position];
112 Inc(Position);
113end;
114
115procedure TMemory.Assign(Source: TMemory);
116begin
117 Size := Source.Size;
118 if Size > 0 then
119 Move(Source.Data[0], Data[0], Size * SizeOf(TInteger));
120 Position := Source.Position;
121end;
122
123procedure TMemory.SaveToFile(FileName: string);
124var
125 F: TFileStream;
126begin
127 if FileExists(FileName) then
128 F := TFileStream.Create(FileName, fmOpenWrite)
129 else F := TFileStream.Create(FileName, fmCreate);
130 try
131 if Size > 0 then F.Write(Data[0], Size * SizeOf(TInteger));
132 finally
133 F.Free;
134 end;
135end;
136
137end.
138
Note: See TracBrowser for help on using the repository browser.