|
@@ -0,0 +1,177 @@
|
|
|
+program tw31029;
|
|
|
+
|
|
|
+{$ifdef fpc}
|
|
|
+{$mode objfpc}{$H+}
|
|
|
+{$endif}
|
|
|
+
|
|
|
+uses
|
|
|
+ TypInfo,
|
|
|
+ variants;
|
|
|
+
|
|
|
+type
|
|
|
+ TBytes = array of Byte;
|
|
|
+
|
|
|
+ {$M+}
|
|
|
+ TMyObject = class
|
|
|
+ private
|
|
|
+ FDynArr1: TBytes;
|
|
|
+ FDynArr2: TBytes;
|
|
|
+ FDynArr3: TBytes;
|
|
|
+ FDynArr4: TBytes;
|
|
|
+ function GetDynArr2: TBytes;
|
|
|
+ function GetDynArr3(AIndex: Integer): TBytes;
|
|
|
+ procedure SetDynArr2(AValue: TBytes);
|
|
|
+ procedure SetDynArr3(AIndex: Integer; AValue: TBytes);
|
|
|
+ protected
|
|
|
+ procedure CheckIndex(AIndex: Integer); inline;
|
|
|
+ function GetDynArr4: TBytes; virtual;
|
|
|
+ procedure SetDynArr4(AValue: TBytes); virtual;
|
|
|
+ published
|
|
|
+ property DynArr1: TBytes read FDynArr1 write FDynArr1;
|
|
|
+ property DynArr2: TBytes read GetDynArr2 write SetDynArr2;
|
|
|
+ property DynArr3: TBytes index 1 read GetDynArr3 write SetDynArr3;
|
|
|
+ property DynArr4: TBytes read GetDynArr4 write SetDynArr4;
|
|
|
+ end;
|
|
|
+ {$M-}
|
|
|
+
|
|
|
+ function TMyObject.GetDynArr2: TBytes;
|
|
|
+ begin
|
|
|
+ Result := FDynArr2;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure TMyObject.SetDynArr2(AValue: TBytes);
|
|
|
+ begin
|
|
|
+ FDynArr2 := AValue;
|
|
|
+ end;
|
|
|
+
|
|
|
+ function TMyObject.GetDynArr3(AIndex: Integer): TBytes;
|
|
|
+ begin
|
|
|
+ Result := FDynArr3;
|
|
|
+ CheckIndex(AIndex);
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure TMyObject.SetDynArr3(AIndex: Integer; AValue: TBytes);
|
|
|
+ begin
|
|
|
+ FDynArr3 := AValue;
|
|
|
+ CheckIndex(AIndex);
|
|
|
+ end;
|
|
|
+
|
|
|
+ function TMyObject.GetDynArr4: TBytes;
|
|
|
+ begin
|
|
|
+ Result := FDynArr4;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure TMyObject.SetDynArr4(AValue: TBytes);
|
|
|
+ begin
|
|
|
+ FDynArr4 := AValue;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure TMyObject.CheckIndex(AIndex: Integer);
|
|
|
+ begin
|
|
|
+ if AIndex <> 1 then begin
|
|
|
+ Writeln('Invalid property index: ', AIndex);
|
|
|
+ Halt(1);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure CheckArr(const A1, A2: TBytes; const AMsg: string; ACode: LongInt); inline;
|
|
|
+ begin
|
|
|
+ //Writeln(HexStr(Pointer(A1)), ' ', HexStr(Pointer(A2)));
|
|
|
+ if A1 <> A2 then begin
|
|
|
+ Writeln(AMsg);
|
|
|
+ Halt(ACode);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure CheckArrContents(const A1, A2: TBytes; const AMsg: string; ACode: LongInt);
|
|
|
+ var
|
|
|
+ valid: Boolean;
|
|
|
+ i: LongInt;
|
|
|
+ begin
|
|
|
+ valid := True;
|
|
|
+ if Length(A1) <> Length(A2) then
|
|
|
+ valid := False;
|
|
|
+ if valid then begin
|
|
|
+ for i := Low(A1) to High(A1) do begin
|
|
|
+ if A1[i] <> A2[i] then begin
|
|
|
+ valid := False;
|
|
|
+ Break;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ if not valid then begin
|
|
|
+ Writeln(AMsg);
|
|
|
+ Halt(ACode);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+var
|
|
|
+ VMyObject: TMyObject;
|
|
|
+ VDynArr1, VDynArr2, VDynArr3, VDynArr4: TBytes;
|
|
|
+ V: Variant;
|
|
|
+begin
|
|
|
+ VMyObject := TMyObject.Create;
|
|
|
+ try
|
|
|
+ { direct use of SetDynArrayProp }
|
|
|
+
|
|
|
+ VMyObject.DynArr1 := nil;
|
|
|
+ VDynArr1 := TBytes.Create(65, 66, 64);
|
|
|
+ SetDynArrayProp(VMyObject, 'DynArr1', Pointer(VDynArr1));
|
|
|
+ CheckArr(VMyObject.DynArr1, VDynArr1,
|
|
|
+ 'SetDynArrayProp: VMyObject.DynArr1 <> VDynArr1', 2);
|
|
|
+ VMyObject.DynArr1 := TBytes.Create(65, 66, 64);
|
|
|
+ VDynArr1 := GetDynArrayProp(VMyObject, 'DynArr1');
|
|
|
+ CheckArr(VMyObject.DynArr1, VDynArr1,
|
|
|
+ 'GetDynArrayProp: VMyObject.DynArr1 <> VDynArr1', 3);
|
|
|
+
|
|
|
+ VMyObject.DynArr2 := nil;
|
|
|
+ VDynArr2 := TBytes.Create(65, 66, 64);
|
|
|
+ SetDynArrayProp(VMyObject, 'DynArr2', Pointer(VDynArr2));
|
|
|
+ CheckArr(VMyObject.DynArr2, VDynArr2,
|
|
|
+ 'SetDynArrayProp: VMyObject.DynArr2 <> VDynArr2', 4);
|
|
|
+ VMyObject.DynArr2 := TBytes.Create(65, 66, 64);
|
|
|
+ VDynArr2 := GetDynArrayProp(VMyObject, 'DynArr2');
|
|
|
+ CheckArr(VMyObject.DynArr2, VDynArr2,
|
|
|
+ 'GetDynArrayProp: VMyObject.DynArr2 <> VDynArr2', 5);
|
|
|
+
|
|
|
+ VMyObject.DynArr3 := nil;
|
|
|
+ VDynArr3 := TBytes.Create(65, 66, 64);
|
|
|
+ SetDynArrayProp(VMyObject, 'DynArr3', Pointer(VDynArr3));
|
|
|
+ CheckArr(VMyObject.DynArr3, VDynArr3,
|
|
|
+ 'SetDynArrayProp: VMyObject.DynArr3 <> VDynArr3', 6);
|
|
|
+ VMyObject.DynArr3 := TBytes.Create(65, 66, 64);
|
|
|
+ VDynArr3 := GetDynArrayProp(VMyObject, 'DynArr3');
|
|
|
+ CheckArr(VMyObject.DynArr3, VDynArr3,
|
|
|
+ 'GetDynArrayProp: VMyObject.DynArr3 <> VDynArr3', 7);
|
|
|
+
|
|
|
+ VMyObject.DynArr4 := nil;
|
|
|
+ VDynArr4 := TBytes.Create(65, 66, 64);
|
|
|
+ SetDynArrayProp(VMyObject, 'DynArr4', Pointer(VDynArr4));
|
|
|
+ CheckArr(VMyObject.DynArr4, VDynArr4,
|
|
|
+ 'SetDynArrayProp: VMyObject.DynArr4 <> VDynArr4', 8);
|
|
|
+ VMyObject.DynArr4 := TBytes.Create(65, 66, 64);
|
|
|
+ VDynArr4 := GetDynArrayProp(VMyObject, 'DynArr4');
|
|
|
+ CheckArr(VMyObject.DynArr4, VDynArr4,
|
|
|
+ 'GetDynArrayProp: VMyObject.DynArr4 <> VDynArr4', 9);
|
|
|
+
|
|
|
+ { indirect use through a variant (a single test should be enough) }
|
|
|
+ VMyObject.DynArr1 := nil;
|
|
|
+ VDynArr1 := TBytes.Create(65, 66, 64);
|
|
|
+ V := Null;
|
|
|
+ DynArrayToVariant(V, Pointer(VDynArr1), TypeInfo(VDynArr1));
|
|
|
+ SetPropValue(VMyObject, 'DynArr1', V);
|
|
|
+ CheckArrContents(VMyObject.DynArr1, VDynArr1,
|
|
|
+ 'SetPropValue: VMyObject.DynArr1 <> VDynArr1', 10);
|
|
|
+ VMyObject.DynArr1 := TBytes.Create(65, 66, 64);
|
|
|
+ V := GetPropValue(VMyObject, 'DynArr1');
|
|
|
+ VDynArr1 := nil;
|
|
|
+ DynArrayFromVariant(Pointer(VDynArr1), V, TypeInfo(VDynArr1));
|
|
|
+ CheckArrContents(VMyObject.DynArr1, VDynArr1,
|
|
|
+ 'GetPropValue: VMyObject.DynArr1 <> VDynArr1', 10);
|
|
|
+
|
|
|
+ WriteLn('All tests OK');
|
|
|
+ finally
|
|
|
+ VMyObject.Free;
|
|
|
+ end;
|
|
|
+end.
|
|
|
+
|