delphimvcframework
delphimvcframework copied to clipboard
Feature request: Аdd the processing properties of type tkDynArray
add the processing properties of type tkDynArray. It is necessary for serialization/deserialization of objects created WSDLImporter.
For example:
class procedure Mapper.ConvertNativeArray(Info: PTypeInfo; P: Pointer;
AArr: TJSONArray);
var
ElemInfo: PTypeInfo;
Dims: Integer;
Size, I: Integer;
ObjectInstance: TObject;
JSObj: TJSONPair;
begin
GetDynArrayElTypeInfo(Info, ElemInfo, Dims);
Size := GetDynArrayLength(P);
for I := 0 to Size - 1 do
begin
if ElemInfo.Kind = tkClass then
begin
ObjectInstance := TObject(P^);
AArr.AddElement(ObjectToJSONObject(ObjectInstance));
end
else
case ElemInfo.Kind of
tkInteger:
case GetTypeData(ElemInfo).OrdType of
otSByte,
otUByte: AArr.AddElement(TJSONNumber.Create(Byte(p^)));
otSWord,
otUWord: AArr.AddElement(TJSONNumber.Create(SmallInt(p^)));
otSLong,
otULong: AArr.AddElement(TJSONNumber.Create(Integer(p^)));
end;
tkFloat:
case GetTypeData(ElemInfo).FloatType of
ftSingle: AArr.AddElement(TJSONNumber.Create(Single(p^)));
ftDouble: if Info = TypeInfo(TDateTime) then
AArr.AddElement(TJSONString.Create(ISODateTimeToString(TDateTime(P^))))
else
AArr.AddElement(TJSONNumber.Create(Double(P^)));
ftComp: AArr.AddElement(TJSONNumber.Create(Comp(P^)));
ftCurr: AArr.AddElement(TJSONNumber.Create(Currency(P^)));
ftExtended: AArr.AddElement(TJSONNumber.Create(Extended(P^)));
end;
tkInt64: AArr.AddElement(TJSONNumber.Create(Int64(P^)));
tkChar: AArr.AddElement(TJSONString.Create(Char(P^)));
tkWChar: AArr.AddElement(TJSONString.Create(WideChar(P^)));
tkWString: AArr.AddElement(TJSONString.Create(PWideString(P)^));
tkString: AArr.AddElement(TJSONString.Create(PShortString(P)^));
tkLString: AArr.AddElement(TJSONString.Create(PAnsiString(P)^));
tkUString: AArr.AddElement(TJSONString.Create(PUnicodeString(P)^));
end;
P := Pointer( NativeUInt(P) + GetTypeSize(Info));
end;
end;
class procedure Mapper.ConvertNativeArray(AObject: TObject;
APropertyName: String; P: Pointer; AArr: TJSONArray);
begin
ConvertNativeArray(GetPropInfo(AObject, APropertyName)^.PropType^, P, AArr);
end;
class procedure Mapper.ConvertNativeArray(AObject: TObject;
APropertyName: String; AArr: TJSONArray);
var P: Pointer;
begin
P := Pointer(GetDynArrayProp(AObject, APropertyName));
ConvertNativeArray(AObject, APropertyName, P, AArr);
end;
.....
tkDynArray: ConvertNativeArray(AObject, f, JSONObject);
....
Nice. Can you propose a PR on the pluggable_mapper branch? (dmvcframework 3.0)
Hmmm... Well, something like this:
procedure TMVCJsonDataObjectsSerializer.SerializeDynamicArray(
const AValue: TValue;
const AArray: TJsonArray;
const AType: TMVCSerializationType;
const AIgnoredAttributes: TMVCIgnoredList
);
function GetTypeSize(Info: PTypeInfo): Cardinal;
var
Context: TRttiContext;
Typ: TRttiType;
begin
if Info = TypeInfo(Variant) then
Exit(SizeOf(TVarData));
Result := SizeOf(Pointer);
Typ := Context.GetType(Info);
if Assigned(Typ) then
Result := Typ.TypeSize;
end;
var
I: Integer;
Obj: TObject;
Val: TValue;
P: Pointer;
begin
if AValue.GetArrayLength > 0 then
begin
P := Pointer(AValue.GetReferenceToRawData^);
for I := 0 to AValue.GetArrayLength - 1 do
begin
Val := AValue.GetArrayElement(i);
case Val.Kind of
tkInteger: case GetTypeData(Val.TypeInfo).OrdType of
otSByte,
otUByte: AArray.Add(Byte(P^));
otSWord,
otUWord: AArray.Add(SmallInt(P^));
otSLong,
otULong: AArray.Add(Integer(P^));
end;
tkChar: AArray.Add(Char(P^));
tkEnumeration: if (Val.TypeInfo = System.TypeInfo(Boolean)) then
AArray.Add(Val.AsBoolean)
else
AArray.Add(GetEnumName(Val.TypeInfo, Val.AsOrdinal));
tkFloat: case GetTypeData(Val.TypeInfo).FloatType of
//System.TypInfo.ftSingle: AArray.Add(Single(p^));
System.TypInfo.ftDouble: if Val.TypeInfo = TypeInfo(TDateTime) then
AArray.Add(TDateTime(P^))
else
AArray.Add(Double(P^));
System.TypInfo.ftComp: AArray.Add(Comp(P^));
System.TypInfo.ftCurr: AArray.Add(Currency(P^));
System.TypInfo.ftExtended: AArray.Add(Extended(P^));
end;
tkString: AArray.Add(PShortString(P)^);
tkClass: begin
Obj := TObject(P^);
ObjectToJsonObject(Obj, AArray.AddObject, GetSerializationType(Obj, AType), AIgnoredAttributes);
end;
tkWChar: AArray.Add(WideChar(P^));
tkLString: AArray.Add(PAnsiString(P)^);
tkWString: AArray.Add(PWideString(P)^);
tkArray: SerializeDynamicArray(Val, AArray.AddArray, AType, AIgnoredAttributes);
tkInt64: AArray.Add(Int64(P^));
tkDynArray: SerializeDynamicArray(Val, AArray.AddArray, AType, AIgnoredAttributes);
tkUString: AArray.Add(PUnicodeString(P)^);
tkRecord: ;
tkInterface: ;
tkSet: ;
tkVariant: ;
end;
P := Pointer( NativeUInt(P) + GetTypeSize(Val.TypeInfo));
end;
end;
end;