Added: xsd:base64binary supports
This commit is contained in:
parent
fd9c309309
commit
7ed849490c
@ -9,10 +9,14 @@ unit XMLDataBindingUtils;
|
|||||||
|
|
||||||
interface
|
interface
|
||||||
uses
|
uses
|
||||||
|
Classes,
|
||||||
|
SysUtils,
|
||||||
XMLIntf;
|
XMLIntf;
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
|
EBase64Error = class(Exception);
|
||||||
|
|
||||||
TXMLDateTimeFormat = (xdtDateTime, xdtDate, xdtTime);
|
TXMLDateTimeFormat = (xdtDateTime, xdtDate, xdtTime);
|
||||||
TXMLTimeFragment = (xtfMilliseconds, xtfTimezone);
|
TXMLTimeFragment = (xtfMilliseconds, xtfTimezone);
|
||||||
TXMLTimeFragments = set of TXMLTimeFragment;
|
TXMLTimeFragments = set of TXMLTimeFragment;
|
||||||
@ -32,6 +36,9 @@ const
|
|||||||
function FloatToXML(AValue: Extended): WideString;
|
function FloatToXML(AValue: Extended): WideString;
|
||||||
function XMLToFloat(const AValue: WideString): Extended;
|
function XMLToFloat(const AValue: WideString): Extended;
|
||||||
|
|
||||||
|
function Base64Encode(AValue: String): String;
|
||||||
|
function Base64Decode(AValue: String): String;
|
||||||
|
|
||||||
function GetNodeIsNil(ANode: IXMLNode): Boolean;
|
function GetNodeIsNil(ANode: IXMLNode): Boolean;
|
||||||
procedure SetNodeIsNil(ANode: IXMLNode; ASetNil: Boolean);
|
procedure SetNodeIsNil(ANode: IXMLNode; ASetNil: Boolean);
|
||||||
|
|
||||||
@ -61,11 +68,16 @@ const
|
|||||||
|
|
||||||
XMLIsNilAttribute = 'nil';
|
XMLIsNilAttribute = 'nil';
|
||||||
|
|
||||||
|
Base64ValidChars = ['A'..'Z', 'a'..'z', '0'..'9', '+', '/'];
|
||||||
|
Base64LookupTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
|
||||||
|
'abcdefghijklmnopqrstuvwxyz' +
|
||||||
|
'0123456789+/';
|
||||||
|
Base64Padding = '=';
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
uses
|
uses
|
||||||
DateUtils,
|
DateUtils,
|
||||||
SysUtils,
|
|
||||||
Windows;
|
Windows;
|
||||||
|
|
||||||
|
|
||||||
@ -262,6 +274,132 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Base64Encode(AValue: String): String;
|
||||||
|
var
|
||||||
|
pos: Integer;
|
||||||
|
lookupIndex: array[0..3] of Byte;
|
||||||
|
padCount: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
if Length(AValue) = 0 then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
padCount := 0;
|
||||||
|
|
||||||
|
{ At least 3 input bytes are required, and the input must be a multiple of 3 }
|
||||||
|
if Length(AValue) < 3 then
|
||||||
|
padCount := 3 - Length(AValue)
|
||||||
|
else if Length(AValue) mod 3 <> 0 then
|
||||||
|
padCount := 3 - (Length(AValue) mod 3);
|
||||||
|
|
||||||
|
if padCount > 0 then
|
||||||
|
AValue := AValue + StringOfChar(#0, padCount);
|
||||||
|
|
||||||
|
pos := 1;
|
||||||
|
|
||||||
|
{ Process in 3-byte blocks }
|
||||||
|
while pos <= Length(AValue) - 2 do
|
||||||
|
begin
|
||||||
|
{ Each 3 input bytes are converted into 4 index values
|
||||||
|
in the range of 0..63, by taking 6 bits each step.
|
||||||
|
|
||||||
|
6 high bytes of first char }
|
||||||
|
lookupIndex[0] := (Ord(AValue[pos]) shr 2) and $3F;
|
||||||
|
|
||||||
|
{ 2 low bytes of first char + 4 high bytes of second char }
|
||||||
|
lookupIndex[1] := ((Ord(AValue[pos]) shl 4) and $3F) or
|
||||||
|
(Ord(AValue[pos + 1]) shr 4);
|
||||||
|
|
||||||
|
{ 4 low bytes of second char + 2 high bytes of third char }
|
||||||
|
lookupIndex[2] :=((Ord(AValue[pos + 1]) shl 2) and $3F) or
|
||||||
|
(Ord(AValue[pos + 2]) shr 6);
|
||||||
|
|
||||||
|
{ 6 low bytes of third char }
|
||||||
|
lookupIndex[3] := Ord(AValue[pos + 2]) and $3F;
|
||||||
|
|
||||||
|
Result := Result + Base64LookupTable[lookupIndex[0] + 1] +
|
||||||
|
Base64LookupTable[lookupIndex[1] + 1] +
|
||||||
|
Base64LookupTable[lookupIndex[2] + 1] +
|
||||||
|
Base64LookupTable[lookupIndex[3] + 1];
|
||||||
|
Inc(pos, 3);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Replace padding }
|
||||||
|
if padCount > 0 then
|
||||||
|
begin
|
||||||
|
for pos := Length(Result) downto Length(Result) - Pred(padCount) do
|
||||||
|
Result[pos] := Base64Padding;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Base64LookupIndex(AChar: Char): Byte;
|
||||||
|
var
|
||||||
|
lookupIndex: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := Ord(Base64Padding);
|
||||||
|
|
||||||
|
for lookupIndex := 1 to Length(Base64LookupTable) do
|
||||||
|
if Base64LookupTable[lookupIndex] = AChar then
|
||||||
|
begin
|
||||||
|
Result := Pred(lookupIndex);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Base64Decode(AValue: String): String;
|
||||||
|
var
|
||||||
|
pos: Integer;
|
||||||
|
padCount: Integer;
|
||||||
|
value: Byte;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
if Length(AValue) = 0 then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
if Length(AValue) mod 4 <> 0 then
|
||||||
|
raise EBase64Error.Create('Value length must be a multiple of 4');
|
||||||
|
|
||||||
|
padCount := 0;
|
||||||
|
pos := Length(AValue);
|
||||||
|
|
||||||
|
{ Count padding chars }
|
||||||
|
while (pos > 0) and (AValue[pos] = Base64Padding) do
|
||||||
|
begin
|
||||||
|
Inc(padCount);
|
||||||
|
Dec(pos);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := '';
|
||||||
|
pos := 1;
|
||||||
|
|
||||||
|
while pos <= Length(AValue) - 3 do
|
||||||
|
begin
|
||||||
|
value := (Base64LookupIndex(AValue[pos]) shl 2) or
|
||||||
|
(Base64LookupIndex(AValue[pos + 1]) shr 4);
|
||||||
|
Result := Result + Chr(value);
|
||||||
|
|
||||||
|
value := (Base64LookupIndex(AValue[pos + 1]) shl 4) or
|
||||||
|
(Base64LookupIndex(AValue[pos + 2]) shr 2);
|
||||||
|
Result := Result + Chr(value);
|
||||||
|
|
||||||
|
value := (Base64LookupIndex(AValue[pos + 2]) shl 6) or
|
||||||
|
(Base64LookupIndex(AValue[pos + 3]));
|
||||||
|
Result := Result + Chr(value);
|
||||||
|
|
||||||
|
Inc(pos, 4);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Delete padding }
|
||||||
|
if padCount > 0 then
|
||||||
|
SetLength(Result, Length(Result) - padCount);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function GetNodeIsNil(ANode: IXMLNode): Boolean;
|
function GetNodeIsNil(ANode: IXMLNode): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := ANode.HasAttribute(XMLIsNilAttribute, XMLSchemaInstanceURI) and
|
Result := ANode.HasAttribute(XMLIsNilAttribute, XMLSchemaInstanceURI) and
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
program X2XMLDataBindingTests;
|
program X2XMLDataBindingTests;
|
||||||
|
|
||||||
|
{$APPTYPE CONSOLE}
|
||||||
uses
|
uses
|
||||||
ActiveX,
|
ActiveX,
|
||||||
GUITestRunner,
|
GUITestRunner,
|
||||||
|
@ -181,7 +181,8 @@ type
|
|||||||
tcDateTime,
|
tcDateTime,
|
||||||
tcDate,
|
tcDate,
|
||||||
tcTime,
|
tcTime,
|
||||||
tcString);
|
tcString,
|
||||||
|
tcBase64);
|
||||||
|
|
||||||
TTypeConversions = set of TTypeConversion;
|
TTypeConversions = set of TTypeConversion;
|
||||||
|
|
||||||
@ -193,18 +194,19 @@ type
|
|||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
SimpleTypeMapping: array[0..9] of TTypeMapping =
|
SimpleTypeMapping: array[0..10] of TTypeMapping =
|
||||||
(
|
(
|
||||||
(SchemaName: 'int'; DelphiName: 'Integer'; Conversion: tcNone),
|
(SchemaName: 'int'; DelphiName: 'Integer'; Conversion: tcNone),
|
||||||
(SchemaName: 'integer'; DelphiName: 'Integer'; Conversion: tcNone),
|
(SchemaName: 'integer'; DelphiName: 'Integer'; Conversion: tcNone),
|
||||||
(SchemaName: 'short'; DelphiName: 'Smallint'; Conversion: tcNone),
|
(SchemaName: 'short'; DelphiName: 'Smallint'; Conversion: tcNone),
|
||||||
(SchemaName: 'date'; DelphiName: 'TDateTime'; Conversion: tcDate),
|
(SchemaName: 'date'; DelphiName: 'TDateTime'; Conversion: tcDate),
|
||||||
(SchemaName: 'time'; DelphiName: 'TDateTime'; Conversion: tcTime),
|
(SchemaName: 'time'; DelphiName: 'TDateTime'; Conversion: tcTime),
|
||||||
(SchemaName: 'dateTime'; DelphiName: 'TDateTime'; Conversion: tcDateTime),
|
(SchemaName: 'dateTime'; DelphiName: 'TDateTime'; Conversion: tcDateTime),
|
||||||
(SchemaName: 'float'; DelphiName: 'Double'; Conversion: tcFloat),
|
(SchemaName: 'float'; DelphiName: 'Double'; Conversion: tcFloat),
|
||||||
(SchemaName: 'double'; DelphiName: 'Double'; Conversion: tcFloat),
|
(SchemaName: 'double'; DelphiName: 'Double'; Conversion: tcFloat),
|
||||||
(SchemaName: 'boolean'; DelphiName: 'Boolean'; Conversion: tcBoolean),
|
(SchemaName: 'boolean'; DelphiName: 'Boolean'; Conversion: tcBoolean),
|
||||||
(SchemaName: 'string'; DelphiName: 'WideString'; Conversion: tcString)
|
(SchemaName: 'string'; DelphiName: 'WideString'; Conversion: tcString),
|
||||||
|
(SchemaName: 'base64Binary'; DelphiName: 'WideString'; Conversion: tcBase64)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -216,7 +218,8 @@ const
|
|||||||
{ tcDateTime } True,
|
{ tcDateTime } True,
|
||||||
{ tcDate } True,
|
{ tcDate } True,
|
||||||
{ tcTime } True,
|
{ tcTime } True,
|
||||||
{ tcString } False
|
{ tcString } False,
|
||||||
|
{ tcBase64 } True
|
||||||
);
|
);
|
||||||
|
|
||||||
TypeConversionNone: array[TDelphiAccessor, TDelphiNodeType] of String =
|
TypeConversionNone: array[TDelphiAccessor, TDelphiNodeType] of String =
|
||||||
@ -248,7 +251,8 @@ const
|
|||||||
{ tcDateTime } ' %<Destination>:s := XMLToDateTime(ChildNodes[''%<Source>:s''].NodeValue, xdtDateTime);',
|
{ tcDateTime } ' %<Destination>:s := XMLToDateTime(ChildNodes[''%<Source>:s''].NodeValue, xdtDateTime);',
|
||||||
{ tcDate } ' %<Destination>:s := XMLToDateTime(ChildNodes[''%<Source>:s''].NodeValue, xdtDate);',
|
{ tcDate } ' %<Destination>:s := XMLToDateTime(ChildNodes[''%<Source>:s''].NodeValue, xdtDate);',
|
||||||
{ tcTime } ' %<Destination>:s := XMLToDateTime(ChildNodes[''%<Source>:s''].NodeValue, xdtTime);',
|
{ tcTime } ' %<Destination>:s := XMLToDateTime(ChildNodes[''%<Source>:s''].NodeValue, xdtTime);',
|
||||||
{ tcString } ' %<Destination>:s := ChildNodes[''%<Source>:s''].Text;'
|
{ tcString } ' %<Destination>:s := ChildNodes[''%<Source>:s''].Text;',
|
||||||
|
{ tcBas64 } ' %<Destination>:s := Base64Decode(Trim(ChildNodes[''%<Source>:s''].Text));'
|
||||||
),
|
),
|
||||||
{ dntAttribute }
|
{ dntAttribute }
|
||||||
(
|
(
|
||||||
@ -258,7 +262,8 @@ const
|
|||||||
{ tcDateTime } ' %<Destination>:s := XMLToDateTime(AttributeNodes[''%<Source>:s''].NodeValue, xdtDateTime);',
|
{ tcDateTime } ' %<Destination>:s := XMLToDateTime(AttributeNodes[''%<Source>:s''].NodeValue, xdtDateTime);',
|
||||||
{ tcDate } ' %<Destination>:s := XMLToDateTime(AttributeNodes[''%<Source>:s''].NodeValue, xdtDate);',
|
{ tcDate } ' %<Destination>:s := XMLToDateTime(AttributeNodes[''%<Source>:s''].NodeValue, xdtDate);',
|
||||||
{ tcTime } ' %<Destination>:s := XMLToDateTime(AttributeNodes[''%<Source>:s''].NodeValue, xdtTime);',
|
{ tcTime } ' %<Destination>:s := XMLToDateTime(AttributeNodes[''%<Source>:s''].NodeValue, xdtTime);',
|
||||||
{ tcString } ' %<Destination>:s := AttributeNodes[''%<Source>:s''].Text;'
|
{ tcString } ' %<Destination>:s := AttributeNodes[''%<Source>:s''].Text;',
|
||||||
|
{ tcBase64 } ' %<Destination>:s := Base64Decode(Trim(AttributeNodes[''%<Source>:s''].Text));'
|
||||||
),
|
),
|
||||||
{ dntCustom}
|
{ dntCustom}
|
||||||
(
|
(
|
||||||
@ -268,7 +273,8 @@ const
|
|||||||
{ tcDateTime } ' %<Destination>:s := XMLToDateTime(%<Source>:s, xdtDateTime);',
|
{ tcDateTime } ' %<Destination>:s := XMLToDateTime(%<Source>:s, xdtDateTime);',
|
||||||
{ tcDate } ' %<Destination>:s := XMLToDateTime(%<Source>:s, xdtDate);',
|
{ tcDate } ' %<Destination>:s := XMLToDateTime(%<Source>:s, xdtDate);',
|
||||||
{ tcTime } ' %<Destination>:s := XMLToDateTime(%<Source>:s, xdtTime);',
|
{ tcTime } ' %<Destination>:s := XMLToDateTime(%<Source>:s, xdtTime);',
|
||||||
{ tcString } ''
|
{ tcString } '',
|
||||||
|
{ tcBase64 } ' %<Destination>:s := Base64Decode(Trim(%<Source>:s));'
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
{ daSet }
|
{ daSet }
|
||||||
@ -281,7 +287,8 @@ const
|
|||||||
{ tcDateTime } ' ChildNodes[''%<Destination>:s''].NodeValue := DateTimeToXML(%<Source>:s, xdtDateTime);',
|
{ tcDateTime } ' ChildNodes[''%<Destination>:s''].NodeValue := DateTimeToXML(%<Source>:s, xdtDateTime);',
|
||||||
{ tcDate } ' ChildNodes[''%<Destination>:s''].NodeValue := DateTimeToXML(%<Source>:s, xdtDate);',
|
{ tcDate } ' ChildNodes[''%<Destination>:s''].NodeValue := DateTimeToXML(%<Source>:s, xdtDate);',
|
||||||
{ tcTime } ' ChildNodes[''%<Destination>:s''].NodeValue := DateTimeToXML(%<Source>:s, xdtTime);',
|
{ tcTime } ' ChildNodes[''%<Destination>:s''].NodeValue := DateTimeToXML(%<Source>:s, xdtTime);',
|
||||||
{ tcString } ''
|
{ tcString } '',
|
||||||
|
{ tcBase64 } ' ChildNodes[''%<Destination>:s''].NodeValue := Base64Encode(%<Source>:s);'
|
||||||
),
|
),
|
||||||
{ dntAttribute }
|
{ dntAttribute }
|
||||||
(
|
(
|
||||||
@ -291,7 +298,8 @@ const
|
|||||||
{ tcDateTime } ' SetAttribute(''%<Destination>:s'', DateTimeToXML(%<Source>:s, xdtDateTime));',
|
{ tcDateTime } ' SetAttribute(''%<Destination>:s'', DateTimeToXML(%<Source>:s, xdtDateTime));',
|
||||||
{ tcDate } ' SetAttribute(''%<Destination>:s'', DateTimeToXML(%<Source>:s, xdtDate));',
|
{ tcDate } ' SetAttribute(''%<Destination>:s'', DateTimeToXML(%<Source>:s, xdtDate));',
|
||||||
{ tcTime } ' SetAttribute(''%<Destination>:s'', DateTimeToXML(%<Source>:s, xdtTime));',
|
{ tcTime } ' SetAttribute(''%<Destination>:s'', DateTimeToXML(%<Source>:s, xdtTime));',
|
||||||
{ tcString } ''
|
{ tcString } '',
|
||||||
|
{ tcBase64 } ' SetAttribute(''%<Destination>:s'', Base64Encode(%<Source>:s));'
|
||||||
),
|
),
|
||||||
{ dntCustom}
|
{ dntCustom}
|
||||||
(
|
(
|
||||||
@ -301,7 +309,8 @@ const
|
|||||||
{ tcDateTime } ' %<Destination>:s := DateTimeToXML(%<Source>:s, xdtDateTime);',
|
{ tcDateTime } ' %<Destination>:s := DateTimeToXML(%<Source>:s, xdtDateTime);',
|
||||||
{ tcDate } ' %<Destination>:s := DateTimeToXML(%<Source>:s, xdtDate);',
|
{ tcDate } ' %<Destination>:s := DateTimeToXML(%<Source>:s, xdtDate);',
|
||||||
{ tcTime } ' %<Destination>:s := DateTimeToXML(%<Source>:s, xdtTime);',
|
{ tcTime } ' %<Destination>:s := DateTimeToXML(%<Source>:s, xdtTime);',
|
||||||
{ tcString } ''
|
{ tcString } '',
|
||||||
|
{ tcBase64 } ' %<Destination>:s := Base64Encode(%<Source>:s);'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -130,7 +130,7 @@
|
|||||||
<Directories Name="UsePackages">False</Directories>
|
<Directories Name="UsePackages">False</Directories>
|
||||||
</Directories>
|
</Directories>
|
||||||
<Parameters>
|
<Parameters>
|
||||||
<Parameters Name="RunParams">"F:\Archive\2007\XMLDataBinding\Tests\Data\02. Collection.xsd"</Parameters>
|
<Parameters Name="RunParams">"F:\Archive\2007\XMLDataBinding\DMS_export_import_formaat.xsd"</Parameters>
|
||||||
<Parameters Name="HostApplication"></Parameters>
|
<Parameters Name="HostApplication"></Parameters>
|
||||||
<Parameters Name="Launcher"></Parameters>
|
<Parameters Name="Launcher"></Parameters>
|
||||||
<Parameters Name="UseLauncher">False</Parameters>
|
<Parameters Name="UseLauncher">False</Parameters>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
-$A8
|
-$A8
|
||||||
-$B-
|
-$B-
|
||||||
-$C-
|
-$C+
|
||||||
-$D+
|
-$D+
|
||||||
-$E-
|
-$E-
|
||||||
-$F-
|
-$F-
|
||||||
@ -12,7 +12,7 @@
|
|||||||
-$L+
|
-$L+
|
||||||
-$M-
|
-$M-
|
||||||
-$N+
|
-$N+
|
||||||
-$O-
|
-$O+
|
||||||
-$P+
|
-$P+
|
||||||
-$Q-
|
-$Q-
|
||||||
-$R-
|
-$R-
|
||||||
@ -22,7 +22,7 @@
|
|||||||
-$V+
|
-$V+
|
||||||
-$W-
|
-$W-
|
||||||
-$X+
|
-$X+
|
||||||
-$Y+
|
-$YD
|
||||||
-$Z1
|
-$Z1
|
||||||
-GD
|
-GD
|
||||||
-cg
|
-cg
|
||||||
@ -32,9 +32,8 @@
|
|||||||
-M
|
-M
|
||||||
-$M16384,1048576
|
-$M16384,1048576
|
||||||
-K$00400000
|
-K$00400000
|
||||||
-N"lib"
|
-LE"C:\Documents and Settings\PsychoMark\My Documents\Borland Studio Projects\Bpl"
|
||||||
-LE"c:\program files\borland\delphi7\Projects\Bpl"
|
-LN"C:\Documents and Settings\PsychoMark\My Documents\Borland Studio Projects\Bpl"
|
||||||
-LN"c:\program files\borland\delphi7\Projects\Bpl"
|
|
||||||
-w-UNSAFE_TYPE
|
-w-UNSAFE_TYPE
|
||||||
-w-UNSAFE_CODE
|
-w-UNSAFE_CODE
|
||||||
-w-UNSAFE_CAST
|
-w-UNSAFE_CAST
|
||||||
|
Loading…
Reference in New Issue
Block a user