1 | unit UDevice;
|
---|
2 |
|
---|
3 | {$mode delphi}
|
---|
4 |
|
---|
5 | interface
|
---|
6 |
|
---|
7 | uses
|
---|
8 | Classes, SysUtils, URouterboard, fgl;
|
---|
9 |
|
---|
10 | type
|
---|
11 | TContext = class;
|
---|
12 | TCommand = class;
|
---|
13 | TDevice = class;
|
---|
14 | TValue = class;
|
---|
15 | TValueDef = class;
|
---|
16 |
|
---|
17 | TValueType = (vtString, vtBool, vtInteger);
|
---|
18 |
|
---|
19 | { TValue }
|
---|
20 |
|
---|
21 | TValue = class
|
---|
22 | Def: TValueDef;
|
---|
23 | Context: TContext;
|
---|
24 | function GetValue: string; virtual;
|
---|
25 | procedure SetValue(NewValue: string); virtual;
|
---|
26 | end;
|
---|
27 |
|
---|
28 | { TValueString }
|
---|
29 |
|
---|
30 | TValueString = class(TValue)
|
---|
31 | Value: string;
|
---|
32 | function GetValue: string; override;
|
---|
33 | procedure SetValue(NewValue: string); override;
|
---|
34 | end;
|
---|
35 |
|
---|
36 | { TValueBool }
|
---|
37 |
|
---|
38 | TValueBool = class(TValue)
|
---|
39 | Value: Boolean;
|
---|
40 | function GetValue: string; override;
|
---|
41 | procedure SetValue(NewValue: string); override;
|
---|
42 | end;
|
---|
43 |
|
---|
44 | { TValueInteger }
|
---|
45 |
|
---|
46 | TValueInteger = class(TValue)
|
---|
47 | Value: Integer;
|
---|
48 | function GetValue: string; override;
|
---|
49 | procedure SetValue(NewValue: string); override;
|
---|
50 | end;
|
---|
51 |
|
---|
52 | TGetValueEvent = function (Value: TValue): string of object;
|
---|
53 | TSetValueEvent = procedure (Value: TValue; NewValue: string) of object;
|
---|
54 |
|
---|
55 | { TValueStringVirtual }
|
---|
56 |
|
---|
57 | TValueStringVirtual = class(TValue)
|
---|
58 | DefaultValue: string;
|
---|
59 | OnSetValue: TSetValueEvent;
|
---|
60 | OnGetValue: TGetValueEvent;
|
---|
61 | function GetValue: string; override;
|
---|
62 | procedure SetValue(NewValue: string); override;
|
---|
63 | end;
|
---|
64 |
|
---|
65 | TValueDefs = class;
|
---|
66 |
|
---|
67 | { TValues }
|
---|
68 |
|
---|
69 | TValues = class(TFPGObjectList<TValue>)
|
---|
70 | Context: TContext;
|
---|
71 | procedure Init(ValueDefs: TValueDefs);
|
---|
72 | function AllReadOnly: Boolean;
|
---|
73 | function AddString(Value: string): TValueString;
|
---|
74 | function AddBool(Value: Boolean): TValueBool;
|
---|
75 | function AddInteger(Value: Integer): TValueInteger;
|
---|
76 | end;
|
---|
77 |
|
---|
78 | TCommandEvent = function(Sender: TObject; Command: TCommand): string of object;
|
---|
79 |
|
---|
80 | TCommand = class
|
---|
81 | Name: string;
|
---|
82 | Description: string;
|
---|
83 | Context: TContext;
|
---|
84 | Execute: TCommandEvent;
|
---|
85 | IsContext: Boolean;
|
---|
86 | end;
|
---|
87 |
|
---|
88 | { TCommands }
|
---|
89 |
|
---|
90 | TCommands = class(TFPGObjectList<TCommand>)
|
---|
91 | Context: TContext;
|
---|
92 | procedure SortAll;
|
---|
93 | function AddNew(Name, Description: string): TCommand;
|
---|
94 | function SearchByName(Name: string): TCommand;
|
---|
95 | end;
|
---|
96 |
|
---|
97 | TValueDef = class
|
---|
98 | Name: string;
|
---|
99 | ReadOnly: Boolean;
|
---|
100 | //Context: TContext;
|
---|
101 | ValueType: TValueType;
|
---|
102 | end;
|
---|
103 |
|
---|
104 | TValueDefString = class(TValueDef)
|
---|
105 | DefaultValue: string;
|
---|
106 | end;
|
---|
107 |
|
---|
108 | TValueDefInteger = class(TValueDef)
|
---|
109 | DefaultValue: Integer;
|
---|
110 | end;
|
---|
111 |
|
---|
112 | TValueDefBool = class(TValueDef)
|
---|
113 | DefaultValue: Boolean;
|
---|
114 | end;
|
---|
115 |
|
---|
116 | { TValueDefs }
|
---|
117 |
|
---|
118 | TValueDefs = class(TFPGObjectList<TValueDef>)
|
---|
119 | function AddNew(Name: string; ValueType: TValueType): TValueDef;
|
---|
120 | function AddString(Name: string; DefaultValue: string; ReadOnly: Boolean = False): TValueDef;
|
---|
121 | function AddBool(Name: string; DefaultValue: Boolean; ReadOnly: Boolean = False): TValueDef;
|
---|
122 | function AddInteger(Name: string; DefaultValue: Integer; ReadOnly: Boolean = False): TValueDef;
|
---|
123 | function AllReadOnly: Boolean;
|
---|
124 | function SearchByName(Name: string): TValueDef;
|
---|
125 | end;
|
---|
126 |
|
---|
127 | { TContextItem }
|
---|
128 |
|
---|
129 | TContextItem = class
|
---|
130 | Values: TValues;
|
---|
131 | constructor Create;
|
---|
132 | destructor Destroy; override;
|
---|
133 | end;
|
---|
134 |
|
---|
135 | { TContextItems }
|
---|
136 |
|
---|
137 | TContextItems = class(TFPGObjectList<TContextItem>)
|
---|
138 | function AddNew(ValueDefs: TValueDefs): TContextItem;
|
---|
139 | end;
|
---|
140 |
|
---|
141 | TContexts = class;
|
---|
142 | TContextList = class;
|
---|
143 | TContextFields = class;
|
---|
144 |
|
---|
145 | { TContext }
|
---|
146 |
|
---|
147 | TContext = class
|
---|
148 | private
|
---|
149 | function CommandGoUp(Sender: TObject; Command: TCommand): string;
|
---|
150 | function CommandGoDown(Sender: TObject; Command: TCommand): string;
|
---|
151 | function CommandExport(Sender: TObject; Command: TCommand): string; virtual;
|
---|
152 | public
|
---|
153 | Device: TDevice;
|
---|
154 | Name: string;
|
---|
155 | Description: string;
|
---|
156 | Childs: TContexts;
|
---|
157 | Parent: TContext;
|
---|
158 | function GetCommands: TCommands; virtual;
|
---|
159 | function GetCommandsStartingWith(Text: string): TCommands;
|
---|
160 | function GetPath: string;
|
---|
161 | constructor Create; virtual;
|
---|
162 | destructor Destroy; override;
|
---|
163 | end;
|
---|
164 |
|
---|
165 | TContextClass = class of TContext;
|
---|
166 |
|
---|
167 | { TContextList }
|
---|
168 |
|
---|
169 | TContextList = class(TContext)
|
---|
170 | private
|
---|
171 | procedure ParseParams(Sender: TObject; Item: TContextItem);
|
---|
172 | public
|
---|
173 | ValueDefs: TValueDefs;
|
---|
174 | Items: TContextItems;
|
---|
175 | function CommandPrint(Sender: TObject; Command: TCommand): string;
|
---|
176 | function CommandExport(Sender: TObject; Command: TCommand): string; override;
|
---|
177 | function CommandSet(Sender: TObject; Command: TCommand): string;
|
---|
178 | function CommandGet(Sender: TObject; Command: TCommand): string;
|
---|
179 | function CommandAdd(Sender: TObject; Command: TCommand): string;
|
---|
180 | function CommandRemove(Sender: TObject; Command: TCommand): string;
|
---|
181 | function GetCommands: TCommands; override;
|
---|
182 | constructor Create; override;
|
---|
183 | destructor Destroy; override;
|
---|
184 | end;
|
---|
185 |
|
---|
186 | { TContextFields }
|
---|
187 |
|
---|
188 | TContextFields = class(TContext)
|
---|
189 | ValueDefs: TValueDefs;
|
---|
190 | Values: TValues;
|
---|
191 | function CommandPrint(Sender: TObject; Command: TCommand): string;
|
---|
192 | function CommandExport(Sender: TObject; Command: TCommand): string; override;
|
---|
193 | function CommandSet(Sender: TObject; Command: TCommand): string;
|
---|
194 | function CommandGet(Sender: TObject; Command: TCommand): string;
|
---|
195 | function GetCommands: TCommands; override;
|
---|
196 | constructor Create; override;
|
---|
197 | destructor Destroy; override;
|
---|
198 | end;
|
---|
199 |
|
---|
200 | { TContexts }
|
---|
201 |
|
---|
202 | TContexts = class(TFPGObjectList<TContext>)
|
---|
203 | Context: TContext;
|
---|
204 | function AddNew(Name, Description: string): TContext;
|
---|
205 | function AddCustom(Name, Description: string; ContextClass: TContextClass): TContext;
|
---|
206 | function AddList(Name, Description: string): TContextList;
|
---|
207 | function AddFields(Name, Description: string): TContextFields;
|
---|
208 | function SearchByName(Name: string): TContext;
|
---|
209 | end;
|
---|
210 |
|
---|
211 | { TDevice }
|
---|
212 |
|
---|
213 | TDevice = class
|
---|
214 | Routerboard: TRouterboard;
|
---|
215 | Identity: string;
|
---|
216 | RootContext: TContext;
|
---|
217 | function GetVariable(Value: TValue): string;
|
---|
218 | constructor Create; virtual;
|
---|
219 | destructor Destroy; override;
|
---|
220 | end;
|
---|
221 |
|
---|
222 |
|
---|
223 | implementation
|
---|
224 |
|
---|
225 | uses
|
---|
226 | UTerminal;
|
---|
227 |
|
---|
228 | { TContextItem }
|
---|
229 |
|
---|
230 | constructor TContextItem.Create;
|
---|
231 | begin
|
---|
232 | Values := TValues.Create;
|
---|
233 | end;
|
---|
234 |
|
---|
235 | destructor TContextItem.Destroy;
|
---|
236 | begin
|
---|
237 | FreeAndNil(Values);
|
---|
238 | inherited Destroy;
|
---|
239 | end;
|
---|
240 |
|
---|
241 | { TValueDefs }
|
---|
242 |
|
---|
243 | function TValueDefs.AddNew(Name: string; ValueType: TValueType): TValueDef;
|
---|
244 | begin
|
---|
245 | if ValueType = vtInteger then Result := AddInteger(Name, 0)
|
---|
246 | else if ValueType = vtString then Result := AddString(Name, '')
|
---|
247 | else if ValueType = vtBool then Result := AddBool(Name, False);
|
---|
248 | end;
|
---|
249 |
|
---|
250 | function TValueDefs.AddString(Name: string; DefaultValue: string;
|
---|
251 | ReadOnly: Boolean): TValueDef;
|
---|
252 | begin
|
---|
253 | Result := TValueDefString.Create;
|
---|
254 | Result.ValueType := vtString;
|
---|
255 | Result.Name := Name;
|
---|
256 | Result.ReadOnly := ReadOnly;
|
---|
257 | TValueDefString(Result).DefaultValue := DefaultValue;
|
---|
258 | Add(Result);
|
---|
259 | end;
|
---|
260 |
|
---|
261 | function TValueDefs.AddBool(Name: string; DefaultValue: Boolean;
|
---|
262 | ReadOnly: Boolean): TValueDef;
|
---|
263 | begin
|
---|
264 | Result := TValueDefBool.Create;
|
---|
265 | Result.ValueType := vtBool;
|
---|
266 | Result.Name := Name;
|
---|
267 | Result.ReadOnly := ReadOnly;
|
---|
268 | TValueDefBool(Result).DefaultValue := DefaultValue;
|
---|
269 | Add(Result);
|
---|
270 | end;
|
---|
271 |
|
---|
272 | function TValueDefs.AddInteger(Name: string; DefaultValue: Integer;
|
---|
273 | ReadOnly: Boolean): TValueDef;
|
---|
274 | begin
|
---|
275 | Result := TValueDefInteger.Create;
|
---|
276 | Result.ValueType := vtInteger;
|
---|
277 | Result.Name := Name;
|
---|
278 | Result.ReadOnly := ReadOnly;
|
---|
279 | TValueDefInteger(Result).DefaultValue := DefaultValue;
|
---|
280 | Add(Result);
|
---|
281 | end;
|
---|
282 |
|
---|
283 | function TValueDefs.AllReadOnly: Boolean;
|
---|
284 | var
|
---|
285 | I: Integer;
|
---|
286 | begin
|
---|
287 | Result := True;
|
---|
288 | for I := 0 to Count - 1 do
|
---|
289 | if not Items[I].ReadOnly then begin
|
---|
290 | Result := False;
|
---|
291 | Break;
|
---|
292 | end;
|
---|
293 | end;
|
---|
294 |
|
---|
295 | function TValueDefs.SearchByName(Name: string): TValueDef;
|
---|
296 | var
|
---|
297 | I: Integer;
|
---|
298 | begin
|
---|
299 | I := 0;
|
---|
300 | while (I < Count) and (Items[I].Name <> Name) do Inc(I);
|
---|
301 | if I < Count then Result := Items[I]
|
---|
302 | else Result := nil;
|
---|
303 | end;
|
---|
304 |
|
---|
305 | { TContextFields }
|
---|
306 |
|
---|
307 | function TContextFields.CommandPrint(Sender: TObject; Command: TCommand
|
---|
308 | ): string;
|
---|
309 | var
|
---|
310 | I: Integer;
|
---|
311 | Context: TContextFields;
|
---|
312 | begin
|
---|
313 | Context := TContextFields(Command.Context);
|
---|
314 | Result := '';
|
---|
315 | for I := 0 to Context.ValueDefs.Count - 1 do begin
|
---|
316 | Result := Result + Context.ValueDefs[I].Name + ': ' +
|
---|
317 | Context.Values[I].GetValue;
|
---|
318 | if I < Context.ValueDefs.Count - 1 then
|
---|
319 | Result := Result + LineEnding;
|
---|
320 | end;
|
---|
321 | end;
|
---|
322 |
|
---|
323 | function TContextFields.CommandExport(Sender: TObject; Command: TCommand
|
---|
324 | ): string;
|
---|
325 | var
|
---|
326 | I: Integer;
|
---|
327 | Values: string;
|
---|
328 | Context: TContextFields;
|
---|
329 | begin
|
---|
330 | Result := inherited;
|
---|
331 | if Result <> '' then Result := Result + LineEnding;
|
---|
332 | Context := TContextFields(Command.Context);
|
---|
333 | if Context.ValueDefs.Count > 0 then begin
|
---|
334 | Values := '';
|
---|
335 | for I := 0 to Context.ValueDefs.Count - 1 do
|
---|
336 | Values := Values + Context.ValueDefs[I].Name + '=' +
|
---|
337 | Context.Values[I].GetValue + ' ';
|
---|
338 | if Values <> '' then
|
---|
339 | Result := Result + Command.Context.GetPath + LineEnding +
|
---|
340 | 'set ' + Values;
|
---|
341 | end;
|
---|
342 | end;
|
---|
343 |
|
---|
344 | function TContextFields.CommandSet(Sender: TObject; Command: TCommand): string;
|
---|
345 | var
|
---|
346 | ParamName: string;
|
---|
347 | ParamValue: string;
|
---|
348 | ValueDef: TValueDef;
|
---|
349 | Index: Integer;
|
---|
350 | begin
|
---|
351 | Result := '';
|
---|
352 | if not (Sender is TTerminal) then Exit;
|
---|
353 |
|
---|
354 | Index := Pos('=', TTerminal(Sender).CommandLine);
|
---|
355 | if Index > 0 then begin
|
---|
356 | ParamName := Copy(TTerminal(Sender).CommandLine, 1, Index - 1);
|
---|
357 | ParamValue := Copy(TTerminal(Sender).CommandLine, Index + 1, Length(TTerminal(Sender).CommandLine));
|
---|
358 | ValueDef := TContextFields(Command.Context).ValueDefs.SearchByName(ParamName);
|
---|
359 | if Assigned(ValueDef) then begin
|
---|
360 | Values[ValueDefs.IndexOf(ValueDef)].SetValue(ParamValue);
|
---|
361 | end;
|
---|
362 | end else TTerminal(Sender).Write('Wrong parameter');
|
---|
363 | end;
|
---|
364 |
|
---|
365 | function TContextFields.CommandGet(Sender: TObject; Command: TCommand): string;
|
---|
366 | begin
|
---|
367 |
|
---|
368 | end;
|
---|
369 |
|
---|
370 | function TContextFields.GetCommands: TCommands;
|
---|
371 | begin
|
---|
372 | Result := inherited;
|
---|
373 | if ValueDefs.Count > 0 then begin
|
---|
374 | if not ValueDefs.AllReadOnly then begin
|
---|
375 | with Result.AddNew('set', 'Change item properties') do
|
---|
376 | Execute := CommandSet;
|
---|
377 | Result.AddNew('edit', '');
|
---|
378 | end;
|
---|
379 | Result.AddNew('get', 'Gets value of item''s property');
|
---|
380 | with Result.AddNew('print', 'Print values of item properties') do
|
---|
381 | Execute := CommandPrint;
|
---|
382 | end;
|
---|
383 | end;
|
---|
384 |
|
---|
385 | constructor TContextFields.Create;
|
---|
386 | begin
|
---|
387 | inherited;
|
---|
388 | ValueDefs := TValueDefs.Create();
|
---|
389 | Values := TValues.Create;
|
---|
390 | Values.Context := Self;
|
---|
391 | end;
|
---|
392 |
|
---|
393 | destructor TContextFields.Destroy;
|
---|
394 | begin
|
---|
395 | FreeAndNil(Values);
|
---|
396 | FreeAndNil(ValueDefs);
|
---|
397 | inherited;
|
---|
398 | end;
|
---|
399 |
|
---|
400 | { TContextList }
|
---|
401 |
|
---|
402 | procedure TContextList.ParseParams(Sender: TObject; Item: TContextItem);
|
---|
403 | var
|
---|
404 | Index: Integer;
|
---|
405 | Terminal: TTerminal;
|
---|
406 | Param: string;
|
---|
407 | ParamName: string;
|
---|
408 | ParamValue: string;
|
---|
409 | ValueDef: TValueDef;
|
---|
410 | begin
|
---|
411 | Terminal := TTerminal(Sender);
|
---|
412 | while True do begin
|
---|
413 | Index := Pos(' ', Terminal.CommandLine);
|
---|
414 | if Index > 0 then begin
|
---|
415 | Param := Copy(Terminal.CommandLine, 1, Index - 1);
|
---|
416 | Terminal.CommandLine := Trim(Copy(Terminal.CommandLine, Index + 1, MaxInt));
|
---|
417 | end else begin
|
---|
418 | Param := TTerminal(Sender).CommandLine;
|
---|
419 | Terminal.CommandLine := '';
|
---|
420 | end;
|
---|
421 | if Param <> '' then begin
|
---|
422 | Index := Pos('=', Param);
|
---|
423 | if Index > 0 then begin
|
---|
424 | ParamName := Copy(Param, 1, Index - 1);
|
---|
425 | ParamValue := Copy(Param, Index + 1, Length(Param));
|
---|
426 | ValueDef := ValueDefs.SearchByName(ParamName);
|
---|
427 | if Assigned(ValueDef) then begin
|
---|
428 | Item.Values[ValueDefs.IndexOf(ValueDef)].SetValue(ParamValue);
|
---|
429 | end else begin
|
---|
430 | TTerminal(Sender).Write('Unknown parameter ' + ParamName);
|
---|
431 | Break;
|
---|
432 | end;
|
---|
433 | end else begin
|
---|
434 | TTerminal(Sender).Write('Parameter without value');
|
---|
435 | Break;
|
---|
436 | end;
|
---|
437 | end else Break;
|
---|
438 | end;
|
---|
439 | end;
|
---|
440 |
|
---|
441 | function TContextList.CommandPrint(Sender: TObject; Command: TCommand): string;
|
---|
442 | var
|
---|
443 | I: Integer;
|
---|
444 | J: Integer;
|
---|
445 | Values: string;
|
---|
446 | Context: TContextList;
|
---|
447 | begin
|
---|
448 | Result := '';
|
---|
449 | Context := TContextList(Command.Context);
|
---|
450 | if Context.Items.Count > 0 then begin
|
---|
451 | for J := 0 to Context.Items.Count - 1 do begin
|
---|
452 | Values := '';
|
---|
453 | for I := 0 to Context.ValueDefs.Count - 1 do
|
---|
454 | Values := Values + Context.ValueDefs[I].Name + '=' +
|
---|
455 | Context.Items[J].Values[I].GetValue + ' ';
|
---|
456 | if Values <> '' then
|
---|
457 | Result := Result + IntToStr(J) + ' ' + Values;
|
---|
458 | if J < Context.Items.Count - 1 then
|
---|
459 | Result := Result + LineEnding;
|
---|
460 | end;
|
---|
461 | end;
|
---|
462 | end;
|
---|
463 |
|
---|
464 | function TContextList.CommandExport(Sender: TObject; Command: TCommand): string;
|
---|
465 | var
|
---|
466 | I: Integer;
|
---|
467 | J: Integer;
|
---|
468 | Values: string;
|
---|
469 | Lines: string;
|
---|
470 | Context: TContextList;
|
---|
471 | begin
|
---|
472 | Result := inherited;
|
---|
473 | if Result <> '' then Result := Result + LineEnding;
|
---|
474 | Context := TContextList(Command.Context);
|
---|
475 | if Context.Items.Count > 0 then begin
|
---|
476 | Lines := '';
|
---|
477 | for J := 0 to Context.Items.Count - 1 do begin
|
---|
478 | Values := '';
|
---|
479 | for I := 0 to Context.ValueDefs.Count - 1 do
|
---|
480 | Values := Values + Context.ValueDefs[I].Name + '=' +
|
---|
481 | Context.Items[J].Values[I].GetValue + ' ';
|
---|
482 | if Values <> '' then
|
---|
483 | Lines := Lines + 'add ' + Values;
|
---|
484 | if J < Context.Items.Count - 1 then
|
---|
485 | Lines := Lines + LineEnding;
|
---|
486 | end;
|
---|
487 | if Lines <> '' then
|
---|
488 | Result := Result + Command.Context.GetPath + LineEnding +
|
---|
489 | Lines;
|
---|
490 | end;
|
---|
491 | end;
|
---|
492 |
|
---|
493 | function TContextList.CommandSet(Sender: TObject; Command: TCommand): string;
|
---|
494 | var
|
---|
495 | Index: Integer;
|
---|
496 | Context: TContextList;
|
---|
497 | ItemIndex: Integer;
|
---|
498 | Item: TContextItem;
|
---|
499 | begin
|
---|
500 | Result := '';
|
---|
501 | if not (Sender is TTerminal) then Exit;
|
---|
502 |
|
---|
503 | Context := TContextList(Command.Context);
|
---|
504 |
|
---|
505 | Index := Pos(' ', TTerminal(Sender).CommandLine);
|
---|
506 | if Index >= 0 then begin
|
---|
507 | ItemIndex := StrToInt(Copy(TTerminal(Sender).CommandLine, 1, Index - 1));
|
---|
508 | TTerminal(Sender).CommandLine := Trim(Copy(TTerminal(Sender).CommandLine, Index + 1, MaxInt));
|
---|
509 | if (ItemIndex > 0) and (ItemIndex < Context.Items.Count) then begin
|
---|
510 | Item := Context.Items[ItemIndex];
|
---|
511 | ParseParams(Sender, Item);
|
---|
512 | end;
|
---|
513 | end else TTerminal(Sender).Write('no such item');
|
---|
514 | end;
|
---|
515 |
|
---|
516 | function TContextList.CommandGet(Sender: TObject; Command: TCommand): string;
|
---|
517 | begin
|
---|
518 |
|
---|
519 | end;
|
---|
520 |
|
---|
521 | function TContextList.CommandAdd(Sender: TObject; Command: TCommand): string;
|
---|
522 | var
|
---|
523 | NewItem: TContextItem;
|
---|
524 | Context: TContextList;
|
---|
525 | begin
|
---|
526 | Result := '';
|
---|
527 | if not (Sender is TTerminal) then Exit;
|
---|
528 |
|
---|
529 | Context := TContextList(Command.Context);
|
---|
530 | NewItem := TContextItem.Create;
|
---|
531 | NewItem.Values.Init(ValueDefs);
|
---|
532 | ParseParams(Sender, NewItem);
|
---|
533 | Context.Items.Add(NewItem);
|
---|
534 | end;
|
---|
535 |
|
---|
536 | function TContextList.CommandRemove(Sender: TObject; Command: TCommand): string;
|
---|
537 | var
|
---|
538 | Context: TContextList;
|
---|
539 | Index: Integer;
|
---|
540 | begin
|
---|
541 | Result := '';
|
---|
542 | if not (Sender is TTerminal) then Exit;
|
---|
543 | Context := TContextList(Command.Context);
|
---|
544 | Index := StrToInt(TTerminal(Sender).CommandLine);
|
---|
545 | if (Index >= 0) and (Index < Context.Items.Count) then begin
|
---|
546 | Context.Items.Delete(Index);
|
---|
547 | end else TTerminal(Sender).Write('no such item');
|
---|
548 | end;
|
---|
549 |
|
---|
550 | function TContextList.GetCommands: TCommands;
|
---|
551 | begin
|
---|
552 | Result := inherited;
|
---|
553 | if ValueDefs.Count > 0 then begin
|
---|
554 | if not ValueDefs.AllReadOnly then begin
|
---|
555 | with Result.AddNew('add', 'Create a new item') do
|
---|
556 | Execute := CommandAdd;
|
---|
557 | with Result.AddNew('set', 'Change item properties') do
|
---|
558 | Execute := CommandSet;
|
---|
559 | Result.AddNew('edit', '');
|
---|
560 | Result.AddNew('remove', 'Remove items');
|
---|
561 | end;
|
---|
562 | Result.AddNew('get', 'Gets value of item''s property');
|
---|
563 | with Result.AddNew('print', 'Print values of item properties') do
|
---|
564 | Execute := CommandPrint;
|
---|
565 | end;
|
---|
566 | end;
|
---|
567 |
|
---|
568 | constructor TContextList.Create;
|
---|
569 | begin
|
---|
570 | inherited;
|
---|
571 | ValueDefs := TValueDefs.Create();
|
---|
572 | Items := TContextItems.Create;
|
---|
573 | end;
|
---|
574 |
|
---|
575 | destructor TContextList.Destroy;
|
---|
576 | begin
|
---|
577 | FreeAndNil(Items);
|
---|
578 | FreeAndNil(ValueDefs);
|
---|
579 | inherited;
|
---|
580 | end;
|
---|
581 |
|
---|
582 | { TContextItems }
|
---|
583 |
|
---|
584 | function TContextItems.AddNew(ValueDefs: TValueDefs): TContextItem;
|
---|
585 | begin
|
---|
586 | Result := TContextItem.Create;
|
---|
587 | Result.Values.Init(ValueDefs);
|
---|
588 | Add(Result);
|
---|
589 | end;
|
---|
590 |
|
---|
591 | { TValueStringVirtual }
|
---|
592 |
|
---|
593 | function TValueStringVirtual.GetValue: string;
|
---|
594 | begin
|
---|
595 | if Assigned(OnGetValue) then
|
---|
596 | Result := OnGetValue(Self);
|
---|
597 | end;
|
---|
598 |
|
---|
599 | procedure TValueStringVirtual.SetValue(NewValue: string);
|
---|
600 | begin
|
---|
601 | if Assigned(OnSetValue) then
|
---|
602 | OnSetValue(Self, NewValue);
|
---|
603 | end;
|
---|
604 |
|
---|
605 | { TContexts }
|
---|
606 |
|
---|
607 | function TContexts.SearchByName(Name: string): TContext;
|
---|
608 | var
|
---|
609 | I: Integer;
|
---|
610 | begin
|
---|
611 | I := 0;
|
---|
612 | while (I < Count) and (Items[I].Name <> Name) do Inc(I);
|
---|
613 | if I < Count then Result := Items[I]
|
---|
614 | else Result := nil;
|
---|
615 | end;
|
---|
616 |
|
---|
617 | { TValueBool }
|
---|
618 |
|
---|
619 | function TValueBool.GetValue: string;
|
---|
620 | begin
|
---|
621 | Result := BoolToStr(Value);
|
---|
622 | end;
|
---|
623 |
|
---|
624 | procedure TValueBool.SetValue(NewValue: string);
|
---|
625 | begin
|
---|
626 | Value := StrToBool(NewValue);
|
---|
627 | end;
|
---|
628 |
|
---|
629 | { TValueString }
|
---|
630 |
|
---|
631 | function TValueString.GetValue: string;
|
---|
632 | begin
|
---|
633 | Result := Value;
|
---|
634 | end;
|
---|
635 |
|
---|
636 | procedure TValueString.SetValue(NewValue: string);
|
---|
637 | begin
|
---|
638 | Value := NewValue;
|
---|
639 | end;
|
---|
640 |
|
---|
641 | { TValue }
|
---|
642 |
|
---|
643 | function TValue.GetValue: string;
|
---|
644 | begin
|
---|
645 | Result := '';
|
---|
646 | end;
|
---|
647 |
|
---|
648 | procedure TValue.SetValue(NewValue: string);
|
---|
649 | begin
|
---|
650 | end;
|
---|
651 |
|
---|
652 | { TValueInteger }
|
---|
653 |
|
---|
654 | function TValueInteger.GetValue: string;
|
---|
655 | begin
|
---|
656 | Result := IntToStr(Value);
|
---|
657 | end;
|
---|
658 |
|
---|
659 | procedure TValueInteger.SetValue(NewValue: string);
|
---|
660 | var
|
---|
661 | Multiply: Integer;
|
---|
662 | begin
|
---|
663 | Multiply := 1;
|
---|
664 | if NewValue[Length(NewValue)] = 'k' then begin
|
---|
665 | Multiply := 1000;
|
---|
666 | Delete(NewValue, Length(NewValue), 1);
|
---|
667 | end else
|
---|
668 | if NewValue[Length(NewValue)] = 'M' then begin
|
---|
669 | Multiply := 1000000;
|
---|
670 | Delete(NewValue, Length(NewValue), 1);
|
---|
671 | end;
|
---|
672 | Value := StrToInt(NewValue) * Multiply;
|
---|
673 | end;
|
---|
674 |
|
---|
675 | { TValues }
|
---|
676 |
|
---|
677 | procedure TValues.Init(ValueDefs: TValueDefs);
|
---|
678 | var
|
---|
679 | I: Integer;
|
---|
680 | begin
|
---|
681 | Clear;
|
---|
682 | for I := 0 to ValueDefs.Count - 1 do begin
|
---|
683 | if ValueDefs[I].ValueType = vtInteger then
|
---|
684 | AddInteger(TValueDefInteger(ValueDefs[I]).DefaultValue)
|
---|
685 | else if ValueDefs[I].ValueType = vtString then
|
---|
686 | AddString(TValueDefString(ValueDefs[I]).DefaultValue)
|
---|
687 | else if ValueDefs[I].ValueType = vtBool then
|
---|
688 | AddBool(TValueDefBool(ValueDefs[I]).DefaultValue);
|
---|
689 | end;
|
---|
690 | end;
|
---|
691 |
|
---|
692 | function TValues.AllReadOnly: Boolean;
|
---|
693 | begin
|
---|
694 |
|
---|
695 | end;
|
---|
696 |
|
---|
697 | function TValues.AddString(Value: string): TValueString;
|
---|
698 | begin
|
---|
699 | Result := TValueString.Create;
|
---|
700 | Result.Context := Context;
|
---|
701 | Result.Value := Value;
|
---|
702 | Self.Add(Result);
|
---|
703 | end;
|
---|
704 |
|
---|
705 | function TValues.AddBool(Value: Boolean): TValueBool;
|
---|
706 | begin
|
---|
707 | Result := TValueBool.Create;
|
---|
708 | Result.Context := Context;
|
---|
709 | Result.Value := Value;
|
---|
710 | Self.Add(Result);
|
---|
711 | end;
|
---|
712 |
|
---|
713 | function TValues.AddInteger(Value: Integer): TValueInteger;
|
---|
714 | begin
|
---|
715 | Result := TValueInteger.Create;
|
---|
716 | Result.Context := Context;
|
---|
717 | Self.Add(Result);
|
---|
718 | end;
|
---|
719 |
|
---|
720 | { TCommands }
|
---|
721 |
|
---|
722 | function SortByName(const Item1, Item2: TCommand): Integer;
|
---|
723 | begin
|
---|
724 | if Item1.Name > Item2.Name then Result := 1
|
---|
725 | else if Item1.Name < Item2.Name then Result := -1
|
---|
726 | else Result := 0;
|
---|
727 | end;
|
---|
728 |
|
---|
729 | procedure TCommands.SortAll;
|
---|
730 | begin
|
---|
731 | Sort(SortByName);
|
---|
732 | end;
|
---|
733 |
|
---|
734 | function TCommands.AddNew(Name, Description: string): TCommand;
|
---|
735 | begin
|
---|
736 | Result := TCommand.Create;
|
---|
737 | Result.Context := Context;
|
---|
738 | Result.Name := Name;
|
---|
739 | Result.Description := Description;
|
---|
740 | Result.Context := Context;
|
---|
741 | Self.Add(Result);
|
---|
742 | end;
|
---|
743 |
|
---|
744 | function TCommands.SearchByName(Name: string): TCommand;
|
---|
745 | var
|
---|
746 | I: Integer;
|
---|
747 | begin
|
---|
748 | I := 0;
|
---|
749 | while (I < Count) and (Items[I].Name <> Name) do Inc(I);
|
---|
750 | if I < Count then Result := Items[I]
|
---|
751 | else Result := nil;
|
---|
752 | end;
|
---|
753 |
|
---|
754 | { TContext }
|
---|
755 |
|
---|
756 | function TContext.CommandGoUp(Sender: TObject; Command: TCommand): string;
|
---|
757 | begin
|
---|
758 | Result := '';
|
---|
759 | if Sender is TTerminal then
|
---|
760 | if Assigned(TTerminal(Sender).Context.Parent) then
|
---|
761 | TTerminal(Sender).Context := TTerminal(Sender).Context.Parent;
|
---|
762 | end;
|
---|
763 |
|
---|
764 | function TContext.CommandGoDown(Sender: TObject; Command: TCommand): string;
|
---|
765 | var
|
---|
766 | NewContext: TContext;
|
---|
767 | begin
|
---|
768 | Result := '';
|
---|
769 | if Sender is TTerminal then begin
|
---|
770 | NewContext := TTerminal(Sender).Context.Childs.SearchByName(Command.Name);
|
---|
771 | if Assigned(NewContext) then
|
---|
772 | TTerminal(Sender).Context := NewContext;
|
---|
773 | end;
|
---|
774 | end;
|
---|
775 |
|
---|
776 | function TContext.CommandExport(Sender: TObject; Command: TCommand): string;
|
---|
777 | var
|
---|
778 | I: Integer;
|
---|
779 | SubCommand: TCommand;
|
---|
780 | Output: string;
|
---|
781 | begin
|
---|
782 | Result := '';
|
---|
783 | SubCommand := TCommand.Create;
|
---|
784 | for I := 0 to Command.Context.Childs.Count - 1 do begin
|
---|
785 | SubCommand.Context := Command.Context.Childs[I];
|
---|
786 | Output := Command.Context.Childs[I].CommandExport(Sender, SubCommand);
|
---|
787 | if Output <> '' then begin
|
---|
788 | if Result <> '' then
|
---|
789 | Result := Result + LineEnding;
|
---|
790 | Result := Result + Output;
|
---|
791 | end;
|
---|
792 | end;
|
---|
793 | SubCommand.Free;
|
---|
794 | end;
|
---|
795 |
|
---|
796 | function TContext.GetCommands: TCommands;
|
---|
797 | var
|
---|
798 | ParentName: string;
|
---|
799 | I: Integer;
|
---|
800 | begin
|
---|
801 | Result := TCommands.Create;
|
---|
802 | Result.Context := Self;
|
---|
803 | if Assigned(Parent) then begin
|
---|
804 | if Parent.Name <> '' then ParentName := Parent.Name
|
---|
805 | else ParentName := 'root';
|
---|
806 | with Result.AddNew('..', 'go up to ' + ParentName) do begin
|
---|
807 | Execute := CommandGoUp;
|
---|
808 | IsContext := True;
|
---|
809 | end;
|
---|
810 | end;
|
---|
811 | for I := 0 to Childs.Count - 1 do begin
|
---|
812 | with Result.AddNew(Childs[I].Name, Childs[I].Description) do begin
|
---|
813 | Execute := CommandGoDown;
|
---|
814 | IsContext := True;
|
---|
815 | end;
|
---|
816 | end;
|
---|
817 | with Result.AddNew('export', 'Print or save an export script that can be used to restore configuration') do
|
---|
818 | Execute := CommandExport;
|
---|
819 | end;
|
---|
820 |
|
---|
821 | function TContext.GetCommandsStartingWith(Text: string): TCommands;
|
---|
822 | var
|
---|
823 | I: Integer;
|
---|
824 | begin
|
---|
825 | Result := GetCommands;
|
---|
826 | for I := Result.Count - 1 downto 0 do
|
---|
827 | if Copy(Result[I].Name, 1, Length(Text)) <> Text then
|
---|
828 | Result.Delete(I);
|
---|
829 | end;
|
---|
830 |
|
---|
831 | function TContext.GetPath: string;
|
---|
832 | var
|
---|
833 | ParentPath: string;
|
---|
834 | begin
|
---|
835 | Result := Name;
|
---|
836 | if Assigned(Parent) then begin
|
---|
837 | ParentPath := Parent.GetPath;
|
---|
838 | if ParentPath <> '' then Result := ParentPath + ' ' + Result;
|
---|
839 | end;
|
---|
840 | if (Length(Result) > 0) and (Result[1] <> '/') then Result := '/' + Result;
|
---|
841 | end;
|
---|
842 |
|
---|
843 | function TContexts.AddNew(Name, Description: string): TContext;
|
---|
844 | begin
|
---|
845 | Result := TContext.Create;
|
---|
846 | Result.Name := Name;
|
---|
847 | Result.Description := Description;
|
---|
848 | Result.Parent := Context;
|
---|
849 | Add(Result);
|
---|
850 | end;
|
---|
851 |
|
---|
852 | function TContexts.AddCustom(Name, Description: string;
|
---|
853 | ContextClass: TContextClass): TContext;
|
---|
854 | begin
|
---|
855 | Result := ContextClass.Create;
|
---|
856 | Result.Name := Name;
|
---|
857 | Result.Description := Description;
|
---|
858 | Result.Parent := Context;
|
---|
859 | Add(Result);
|
---|
860 | end;
|
---|
861 |
|
---|
862 | function TContexts.AddList(Name, Description: string): TContextList;
|
---|
863 | begin
|
---|
864 | Result := TContextList.Create;
|
---|
865 | Result.Name := Name;
|
---|
866 | Result.Description := Description;
|
---|
867 | Result.Parent := Context;
|
---|
868 | Add(Result);
|
---|
869 | end;
|
---|
870 |
|
---|
871 | function TContexts.AddFields(Name, Description: string): TContextFields;
|
---|
872 | begin
|
---|
873 | Result := TContextFields.Create;
|
---|
874 | Result.Name := Name;
|
---|
875 | Result.Description := Description;
|
---|
876 | Result.Parent := Context;
|
---|
877 | Add(Result);
|
---|
878 | end;
|
---|
879 |
|
---|
880 | constructor TContext.Create;
|
---|
881 | begin
|
---|
882 | Childs := TContexts.Create;
|
---|
883 | Childs.Context := Self;
|
---|
884 | Parent := nil;
|
---|
885 | end;
|
---|
886 |
|
---|
887 | destructor TContext.Destroy;
|
---|
888 | begin
|
---|
889 | FreeAndNil(Childs);
|
---|
890 | inherited Destroy;
|
---|
891 | end;
|
---|
892 |
|
---|
893 | { TDevice }
|
---|
894 |
|
---|
895 | function TDevice.GetVariable(Value: TValue): string;
|
---|
896 | begin
|
---|
897 | if (Value.Context.GetPath = '/system identity') and (Value.Def.Name = 'name') then
|
---|
898 | Result := Identity
|
---|
899 | else if (Value.Context.GetPath = '/system routerboard') and (Value.Def.Name = 'model') then
|
---|
900 | Result := Routerboard.Model
|
---|
901 | else Result := '';
|
---|
902 | end;
|
---|
903 |
|
---|
904 | constructor TDevice.Create;
|
---|
905 | begin
|
---|
906 | Routerboard := TRouterboard.Create;
|
---|
907 | RootContext := TContext.Create;
|
---|
908 | RootContext.Device := Self;
|
---|
909 | end;
|
---|
910 |
|
---|
911 | destructor TDevice.Destroy;
|
---|
912 | begin
|
---|
913 | FreeAndNil(Routerboard);
|
---|
914 | FreeAndNil(RootContext);
|
---|
915 | inherited Destroy;
|
---|
916 | end;
|
---|
917 |
|
---|
918 | end.
|
---|
919 |
|
---|