diff --git a/README.md b/README.md
index ee79c0f..ca748fa 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,10 @@ Header translation for Microsoft XmlLite
**Note**: This is a minimal translation, some parts were not implemented and most are untested.
+**Note**: i only used it in Win32 projects, but Delphi/Win64 was independently tested at
+* https://github.com/EtheaDev/SVGIconImageList/pull/97
+* https://github.com/EtheaDev/SVGIconImageList/issues/96
+
Sample code taken from production. We use this to generate very large (>1GB) Xml files from an array of temporary files.
procedure AppendFile(const FileName: string; _IXMLWriter: IXMLWriter);
@@ -49,4 +53,4 @@ Sample code taken from production. We use this to generate very large (>1GB) Xm
_IXMLWriter.WriteEndElement;
_IXMLWriter.WriteEndDocument;
_IXMLWriter.Flush;
- end;
\ No newline at end of file
+ end;
diff --git a/Samples/DynArrays to-from files/fxsParser.pas b/Samples/DynArrays to-from files/fxsParser.pas
index de53bb4..b4989dd 100644
--- a/Samples/DynArrays to-from files/fxsParser.pas
+++ b/Samples/DynArrays to-from files/fxsParser.pas
@@ -39,7 +39,6 @@ implementation
TTableList = TList< TfxsTable >;
TFieldList = TList< TfxsField >;
-
// 1: xml tags and attrs are case-sensitive !!!
// 2: xml always consists of s SINGLE root tag
Const
@@ -61,7 +60,19 @@ procedure WriteXML(const Data: TfxsTables; const ToFile: string);
t: TfxsTable; f: TfxsField;
begin
- wx := CreateXmlFileWriter(ToFile);
+// wx := CreateXmlFileWriter(ToFile);
+
+ wx := CreateXmlLite.Data(ToFile).Writer; // Default UTF-8
+
+// wx := CreateXmlLite.Data(ToFile).Encoding(TEncoding.Unicode).Writer; // UTF-16
+// wx := CreateXmlLite.Data(ToFile).Encoding(1251).Writer; // Windows GetACP for Russian
+// wx := CreateXmlLite.Data(ToFile).Encoding('windows-1251').Writer; // Windows GetACP for Russian
+
+// The following three variants fail within XmlLite.dll with bad encoding error :-(
+// wx := CreateXmlLite.Data(ToFile).Encoding( 866).Writer; // Windows GetOEMCP for Russian
+// wx := CreateXmlLite.Data(ToFile).Encoding('CP866').Writer; // Windows GetOEMCP for Russian
+// wx := CreateXmlLite.Data(ToFile).Encoding('cp1251').Writer; // Windows GetACP for Russian
+
if wx = nil then raise Exception.Create(ToFile + #13#10 + 'Can not write to the given file.');
EXmlLite.Check( wx.SetProperty(XmlWriterProperty.Indent, LongInt(True)) );
@@ -69,6 +80,7 @@ procedure WriteXML(const Data: TfxsTables; const ToFile: string);
EXmlLite.Check( wx.WriteStartDocument( XmlStandalone.Omit ) );
EXmlLite.Check( wx.WriteComment( ' Delphi XML-Lite Demo Sample File, can be deleted ' ) );
+ EXmlLite.Check( wx.WriteComment( ' Cyrillic text sample for encodings test. Пример кириллического текста. ' ) );
EXmlLite.Check( wx.Flush );
EXmlLite.Check( wx.WriteStartElement( nil, Tag_DocRoot, nil) );
@@ -115,7 +127,13 @@ function ReadXML (const FromFile: string): TfxsTables;
CurrTableLevel, CurrLevel: Cardinal;
begin
Result := nil;
- rx := CreateXmlFileReader( FromFile );
+
+// rx := CreateXmlFileReader( FromFile );
+ rx := CreateXmlLite.Data(FromFile).Reader;
+ // reader should auto-adapt to the file encoding unless that is impossible in very special cases
+ // so here is no fair reason to pin-point encodings.
+ // not that pin-pointing it was of much sense for writer as well
+
if rx = nil then raise Exception.Create( FromFile + #13#10 + 'Can not read from the given file.');
ts := nil; fs := nil;
diff --git a/Samples/Privat_ExchRates.xml b/Samples/Privat_ExchRates.xml
new file mode 100644
index 0000000..83ea558
--- /dev/null
+++ b/Samples/Privat_ExchRates.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+|
|
diff --git a/XmlLite.pas b/XmlLite.pas
index 4f1d548..86df079 100644
--- a/XmlLite.pas
+++ b/XmlLite.pas
@@ -21,7 +21,8 @@ interface
uses
ActiveX,
- Windows, // LONG_PTR type in Win32/Win64 with different Delphi versions
+ Windows, // LONG_PTR type in Win32/Win64 with different Delphi versions
+ Classes,
SysUtils;
{$MINENUMSIZE 4}
@@ -337,7 +338,7 @@ interface
function WriteSurrogateCharEntity(const wchLow, wchHigh: WideChar): HRESULT; stdcall;
function WriteWhitespace(const pwszWhitespace: PWideChar): HRESULT; stdcall;
function Flush: HRESULT; stdcall;
- end platform experimental {'Requires Windows 10'};
+ end library {'Requires Windows 10'};
(** MSDN https://msdn.microsoft.com/en-us/library/ms752841.aspx
@@ -362,25 +363,71 @@ interface
end;
-function CreateXmlFileReader(const FileName: string = ''): IXMLReader; overload;
+// Low-level, when shaving few msecs really might matter.
+// Note: anything involving FileNames is Disk I/O bound, thus does not need those msecs.
+function FastCreateXmlReader(): IXMLReader;
+function FastCreateXmlWriter(): IXMLWriter;
+{$WARN SYMBOL_library OFF}
+function FastCreateXmlWriterLite(): IXmlWriterLite; {Windows 10 only; Delphi XE2 does not allow LIBRARY keyword here}
+{$WARN SYMBOL_library Default}
+
+type
+ TAfterXmlLiteCreationHelper = TProc; // re-define for pre-2010 Delphi versions
+
+ iXmlLiteCreationHelper = interface
+ function Data(const COMStream: iStream): IXmlLiteCreationHelper; overload;
+ function Data(const FileName: TFileName): IXmlLiteCreationHelper; overload;
+ function Data(const DataStream: TStream; const OwnStreamObject: boolean = True;
+ const Rewind: boolean = false): IXmlLiteCreationHelper; overload;
+
+ function Encoding(const Encoding: TEncoding): IXmlLiteCreationHelper; overload;
+ function Encoding(const EncodingCodePage: UINT): IXmlLiteCreationHelper; overload;
+ function Encoding(const EncodingName: string): IXmlLiteCreationHelper; overload;
+
+ function MemoryManager(const MM: iMalloc): IXmlLiteCreationHelper;
+ function ExternalEntities(const EntitiesResolver: iXmlResolver): IXmlLiteCreationHelper;
+
+ function Reader: IXMLReader;
+ function Writer: IXMLWriter;
+{$WARN SYMBOL_library OFF}
+ function LiteWriter: IXmlWriterLite; library {Windows 10 only};
+{$WARN SYMBOL_library DEFAULT}
+
+ // one may register a handler that would check that the actual reader or writer was created (the parameter is not nil)
+ function OnDestroy(const callback: TAfterXmlLiteCreationHelper; const UserData: Pointer = nil): IXmlLiteCreationHelper;
+ end;
+
+function CreateXmlLite: iXmlLiteCreationHelper; // Main entry point :-D
+
+function CreateXmlFileReader(const FileName: string): IXMLReader; overload; deprecated 'Use CreateXmlLite() helper';
function CreateXmlFileReader(const FileName: string;
- const AEncodingCodePage: UINT): IXMLReader; overload;
+ const AEncodingCodePage: UINT): IXMLReader; overload; deprecated 'Use CreateXmlLite() helper';
function CreateXmlFileReader(const FileName: string;
- const AEncodingName: string): IXMLReader; overload;
+ const AEncodingName: string): IXMLReader; overload; deprecated 'Use CreateXmlLite() helper';
function CreateXmlFileReader(const FileName: string;
- const Encoding: TEncoding): IXmlReader; overload;
+ const Encoding: TEncoding): IXmlReader; overload; deprecated 'Use CreateXmlLite() helper';
-function CreateXmlFileWriter(const FileName: string = ''): IXMLWriter; overload;
+function CreateXmlFileWriter(const FileName: string): IXMLWriter; overload; deprecated 'Use CreateXmlLite() helper';
function CreateXmlFileWriter(const FileName: string;
- const AEncodingCodePage: UINT): IXMLWriter; overload;
+ const AEncodingCodePage: UINT): IXMLWriter; overload; deprecated 'Use CreateXmlLite() helper';
function CreateXmlFileWriter(const FileName: string;
- const AEncodingName: string): IXMLWriter; overload;
+ const AEncodingName: string): IXMLWriter; overload; deprecated 'Use CreateXmlLite() helper';
function CreateXmlFileWriter(const FileName: string;
- const Encoding: TEncoding): IXmlWriter; overload;
-
-function OpenXmlFileStreamReader(const FileName: string): IStream;
-
-function OpenXmlFileStreamWriter(const FileName: string): IStream;
+ const Encoding: TEncoding): IXmlWriter; overload; deprecated 'Use CreateXmlLite() helper';
+
+// All these CreateXmlXXXXX functions are subject to combinatorial explosion
+// with regard to their semantic parameters and different datatypes for each.
+// This can be resolved using Advanced Records with class operators Implicit
+// ( approach being christened Magnet Pattern in Scala community, if you
+// want to google some names, though the idea is self evident IMHO ).
+// But this approach is problematic with both optional parameters and
+// quite limited Delphi type inference.
+// So i prefered to unify them into a fluid-API helper.
+
+// These functions might get helpful for any COM/OLE programming, not just XmlLite
+// Though they are nowhere above trivial, so perhaps to be deprecated and removed too?
+function OpenFileStreamReader(const FileName: string): IStream;
+function OpenFileStreamWriter(const FileName: string): IStream;
procedure CheckHR(const HR: HRESULT); inline; deprecated 'Use EXmlLite.Check';
@@ -404,13 +451,10 @@ EXmlLite = class(Exception)
implementation
-uses
- Classes;
-
const
XMLReaderGuid: TGUID = '{7279FC81-709D-4095-B63D-69FE4B0D9030}';
XMLWriterGuid: TGUID = '{7279FC88-709D-4095-B63D-69FE4B0D9030}';
- XMLWriterLiteGUID: TGUID = '{862494C6-1310-4AAD-B3CD-2DBEEBF670D3}';
+ XMLWriterLiteGUID: TGUID = '{862494C6-1310-4AAD-B3CD-2DBEEBF670D3}' library {Windows 10};
// An idea to sleep with: do not load DLL and those functions until we really call them, if ever.
// Implemented starting with Delphi 2010 - http://www.tindex.net/Language/delayed.html
@@ -456,13 +500,30 @@ function CreateXmlWriterOutputWithEncodingName(
-function CreateXmlFileReader(const FileName: string): IXMLReader;
+function FastCreateXmlReader(): IXMLReader;
begin
EXmlLite.Check(CreateXmlReader(XMLReaderGuid, Result, nil));
+end;
+
+function FastCreateXmlWriter(): IXMLWriter;
+begin
+ EXmlLite.Check(CreateXmlWriter(XMLWriterGuid, iUnknown(Result), nil));
+end;
+
+{$WARN SYMBOL_library OFF}
+function FastCreateXmlWriterLite(): IXmlWriterLite;
+begin
+ EXmlLite.Check(CreateXmlWriter(XMLWriterLiteGUID, iUnknown(Result), nil));
+end;
+{$WARN SYMBOL_library Default}
+
+function CreateXmlFileReader(const FileName: string): IXMLReader;
+begin
+ Result := FastCreateXmlReader;
if (Result <> nil) and (FileName <> '') then
begin
EXmlLite.Check(Result.SetProperty(XmlReaderProperty.DtdProcessing, Ord(XmlDtdProcessing.Parse)));
- EXmlLite.Check(Result.SetInput(OpenXmlFileStreamReader(FileName)));
+ EXmlLite.Check(Result.SetInput(OpenFileStreamReader(FileName)));
end;
end;
@@ -480,12 +541,12 @@ function CreateXmlFileReader(const FileName: string;
ReaderInput: IXMLReaderInput;
begin
Assert(FileName <> '', 'Need XML File name');
- EXmlLite.Check(CreateXmlReader(XMLReaderGuid, Result, nil));
+ Result := FastCreateXmlReader;
if Result <> nil then
begin
EXmlLite.Check(Result.SetProperty(XmlReaderProperty.DtdProcessing,
Ord(XmlDtdProcessing.Parse)));
- Stream := OpenXmlFileStreamReader(FileName);
+ Stream := OpenFileStreamReader(FileName);
EXmlLite.Check(CreateXmlReaderInputWithEncodingCodePage(Stream, nil,
AEncodingCodePage, True, nil, ReaderInput));
EXmlLite.Check(Result.SetInput(ReaderInput));
@@ -499,12 +560,12 @@ function CreateXmlFileReader(const FileName: string;
ReaderInput: IXMLReaderInput;
begin
Assert(FileName <> '', 'Need XML File name');
- EXmlLite.Check(CreateXmlReader(XMLReaderGuid, Result, nil));
+ Result := FastCreateXmlReader;
if Result <> nil then
begin
EXmlLite.Check(Result.SetProperty(XmlReaderProperty.DtdProcessing,
Ord(XmlDtdProcessing.Parse)));
- Stream := OpenXmlFileStreamReader(FileName);
+ Stream := OpenFileStreamReader(FileName);
EXmlLite.Check(CreateXmlReaderInputWithEncodingName(Stream, nil,
PWideChar(AEncodingName), True, nil, ReaderInput));
EXmlLite.Check(Result.SetInput(ReaderInput));
@@ -514,9 +575,9 @@ function CreateXmlFileReader(const FileName: string;
function CreateXmlFileWriter(const FileName: string): IXMLWriter;
begin
- EXmlLite.Check(CreateXmlWriter(XMLWriterGuid, iUnknown(Result), nil));
+ Result := FastCreateXmlWriter;
if (Result <> nil) and (FileName <> '') then
- EXmlLite.Check(Result.SetOutput(OpenXmlFileStreamWriter(FileName)));
+ EXmlLite.Check(Result.SetOutput(OpenFileStreamWriter(FileName)));
end;
function CreateXmlFileWriter(const FileName: string; const Encoding: TEncoding): IXmlWriter;
@@ -531,10 +592,10 @@ function CreateXmlFileWriter(const FileName: string;
Stream: IStream;
begin
Assert(FileName <> '', 'Need XML File name');
- EXmlLite.Check(CreateXmlWriter(XMLWriterGuid, IUnknown(Result), nil));
+ Result := FastCreateXmlWriter;
if (Result <> nil) then
begin
- Stream := OpenXmlFileStreamWriter(FileName);
+ Stream := OpenFileStreamWriter(FileName);
EXmlLite.Check(CreateXmlWriterOutputWithEncodingCodePage(Stream, nil,
AEncodingCodePage, WriterOutput));
Assert(WriterOutput <> nil);
@@ -549,10 +610,10 @@ function CreateXmlFileWriter(const FileName: string;
Stream: IStream;
begin
Assert(FileName <> '', 'Need XML File name');
- EXmlLite.Check(CreateXmlWriter(XMLWriterGuid, IUnknown(Result), nil));
+ Result := FastCreateXmlWriter;
if (Result <> nil) then
begin
- Stream := OpenXmlFileStreamWriter(FileName);
+ Stream := OpenFileStreamWriter(FileName);
EXmlLite.Check(CreateXmlWriterOutputWithEncodingName(Stream, nil,
PWideChar(AEncodingName), WriterOutput));
Assert(WriterOutput <> nil);
@@ -560,18 +621,373 @@ function CreateXmlFileWriter(const FileName: string;
end;
end;
-
-function OpenXmlFileStreamReader(const FileName: string): IStream;
+function OpenFileStreamReader(const FileName: string): IStream;
begin
Assert(FileExists(FileName), 'XML file should exist');
Result := TStreamAdapter.Create(TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite), soOwned);
end;
-function OpenXmlFileStreamWriter(const FileName: string): IStream;
+function OpenFileStreamWriter(const FileName: string): IStream;
begin
Result := TStreamAdapter.Create(TFileStream.Create(FileName, fmCreate), soOwned);
end;
+type
+ xlHelper = class( TInterfacedObject, iXmlLiteCreationHelper)
+ private
+ DestroyingCallBack: TAfterXmlLiteCreationHelper;
+ DestroyingTag: Pointer;
+ CreatedReaderWriter: iInterface;
+
+ Resolver: iXmlResolver;
+ HeapManager: iMalloc;
+
+ type
+{$ScopedEnums OFF}
+ xlEncType = (etNone, etName, etCP);
+ xlDataType = (dtNone, dtCOM, dtFileName, dtDelphiStream);
+ var
+ EncType: xlEncType;
+ DataType: xlDataType;
+ DataDSOwn, DataDSRewind: boolean;
+ DataDSObject: TStream;
+ DataCOMStream: iStream;
+ DataFileName: string;
+ EncCharset: string;
+ EncCodePage: Cardinal;
+ procedure CleanFor(const Mode: xlDataType); overload;
+ procedure CleanFor(const Mode: xlEncType); overload;
+ function InternalCreateReaderStream(): iUnknown;
+ function InternalCreateWriterStream(): iUnknown;
+ procedure InternalCreateDataCOMStream(const ForWriting: boolean);
+ protected
+ function Data(const COMStream: iStream): IXmlLiteCreationHelper; overload;
+ function Data(const FileName: TFileName): IXmlLiteCreationHelper; overload;
+ function Data(const DataStream: TStream; const OwnStreamObject, Rewind: boolean): IXmlLiteCreationHelper; overload;
+
+ function Encoding(const EncodingObj: TEncoding): IXmlLiteCreationHelper; overload;
+ function Encoding(const EncodingCodePage: UINT): IXmlLiteCreationHelper; overload;
+ function Encoding(const EncodingName: string): IXmlLiteCreationHelper; overload;
+
+ function MemoryManager(const MM: iMalloc): IXmlLiteCreationHelper;
+ function ExternalEntities(const EntitiesResolver: iXmlResolver): IXmlLiteCreationHelper;
+
+ function Reader: IXMLReader;
+ function Writer: IXMLWriter;
+{$WARN SYMBOL_library Off}
+ function LiteWriter: IXmlWriterLite; library {Windows 10 only};
+{$WARN SYMBOL_library Default}
+
+ // register a handler that would check that the actual reader or writer was created (the parameter is not nil)
+ function OnDestroy(const callback: TAfterXmlLiteCreationHelper; const UserData: Pointer = nil): IXmlLiteCreationHelper;
+ public
+ destructor Destroy; override;
+ end;
+
+{$WARN SYMBOL_library OFF}
+function CreateXmlLite: iXmlLiteCreationHelper;
+begin
+ Result := xlHelper.Create;
+end;
+{$WARN SYMBOL_library Default}
+
+{ xlHelper }
+
+function xlHelper.Data(const DataStream: TStream; const OwnStreamObject,
+ Rewind: boolean): IXmlLiteCreationHelper;
+var Mode: xlDataType;
+begin
+ if Assigned(DataStream)
+ then Mode := dtDelphiStream
+ else Mode := dtNone;
+ CleanFor( Mode );
+ if DataType = dtDelphiStream then
+ begin
+ if Self.DataDSOwn and (Self.DataDSObject <> DataStream) then
+ FreeAndNil( Self.DataDSObject );
+
+ Self.DataDSObject := DataStream;
+ Self.DataDSRewind := Rewind;
+ Self.DataDSOwn := OwnStreamObject;
+ end;
+
+ Result := Self;
+end;
+
+function xlHelper.Data(const FileName: TFileName): IXmlLiteCreationHelper;
+var Mode: xlDataType;
+begin
+ if FileName > ''
+ then Mode := dtFileName
+ else Mode := dtNone;
+ CleanFor( Mode );
+ if DataType = dtFileName then
+ Self.DataFileName := FileName;
+
+ Result := Self;
+end;
+
+function xlHelper.Data(const COMStream: iStream): IXmlLiteCreationHelper;
+var Mode: xlDataType;
+begin
+ if Assigned(COMStream)
+ then Mode := dtCOM
+ else Mode := dtNone;
+ CleanFor( Mode );
+ if DataType = dtCOM then
+ Self.DataCOMStream := COMStream;
+
+ Result := Self;
+end;
+
+function xlHelper.Encoding(const EncodingName: string): IXmlLiteCreationHelper;
+var Mode: xlEncType;
+begin
+ if EncodingName > ''
+ then Mode := etName
+ else Mode := etNone;
+ CleanFor( Mode );
+ if EncType = etName then
+ Self.EncCharset := EncodingName;
+
+ Result := Self;
+end;
+
+function xlHelper.Encoding(
+ const EncodingCodePage: UINT): IXmlLiteCreationHelper;
+var Mode: xlEncType;
+begin
+ if EncodingCodePage > 0
+ then Mode := etCP
+ else Mode := etNone;
+ CleanFor(Mode);
+ if EncType = etCP then
+ Self.EncCodePage := EncodingCodePage;
+
+ Result := Self;
+end;
+
+function xlHelper.Encoding(const EncodingObj: TEncoding): IXmlLiteCreationHelper;
+begin
+ Result := Encoding( EncodingObj.CodePage );
+ // if .CodePage is not yet published (example: Delphi 2009) see class helper hack in OmniXML's OEncodings
+end;
+
+// This can not be easily bound to FastMM4 / Delphi RTL MM because needing two extra methods:
+// is-this-pointer-allocated-in-this-MM and how-much-memory-block-was-REALLY-allocated-for-the-pointer
+function xlHelper.MemoryManager(const MM: iMalloc): IXmlLiteCreationHelper;
+begin
+ Self.HeapManager := MM;
+
+ Result := Self;
+end;
+
+function xlHelper.ExternalEntities(
+ const EntitiesResolver: iXmlResolver): IXmlLiteCreationHelper;
+begin
+ Self.Resolver := EntitiesResolver;
+
+ Result := Self;
+end;
+
+procedure xlHelper.InternalCreateDataCOMStream(const ForWriting: boolean);
+var FileMode: Word;
+ Ownership: TStreamOwnership;
+begin
+ if ForWriting
+ then FileMode := fmCreate
+ else FileMode := fmOpenRead or fmShareDenyWrite;
+
+ if DataType > dtNone then
+ begin
+ if DataType = dtFileName then
+ begin
+ DataDSObject := TFileStream.Create(DataFileName, FileMode);
+ DataDSOwn := True;
+ DataDSRewind := False;
+ DataType := dtDelphiStream;
+ end;
+
+ if DataType = dtDelphiStream then
+ begin
+ if DataDSOwn
+ then Ownership := soOwned
+ else Ownership := soReference;
+ if DataDSRewind then
+ DataDSObject.Seek(0,soFromBeginning);
+ DataCOMStream := TStreamAdapter.Create(DataDSObject, Ownership);
+ DataDSObject := nil;
+ DataType := dtCOM;
+ end;
+ end;
+
+ if DataType <> dtCOM then
+ DataCOMStream := nil;
+end;
+
+function xlHelper.InternalCreateReaderStream: iUnknown;
+var
+ ReaderInput: IXMLReaderInput;
+begin
+ Result := nil;
+
+ InternalCreateDataCOMStream( False );
+
+ if nil <> DataCOMStream then begin
+ ReaderInput := nil;
+ case EncType of
+ etName: EXmlLite.Check(
+ CreateXmlReaderInputWithEncodingName( DataCOMStream, nil,
+ PWideChar(EncCharset), True, nil, ReaderInput));
+ etCP: EXmlLite.Check(
+ CreateXmlReaderInputWithEncodingCodePage( DataCOMStream, HeapManager,
+ EncCodePage, True, nil, ReaderInput));
+ else;
+ end;
+ if nil <> ReaderInput
+ then Result := ReaderInput
+ else Result := DataCOMStream;
+ end;
+end;
+
+function xlHelper.InternalCreateWriterStream(): iUnknown;
+var
+ WriterOutput: IXMLWriterOutput;
+begin
+ Result := nil;
+
+ InternalCreateDataCOMStream( True );
+
+ if nil <> DataCOMStream then begin
+ WriterOutput := nil;
+ case EncType of
+ etName: EXmlLite.Check(
+ CreateXmlWriterOutputWithEncodingName(
+ DataCOMStream, HeapManager, PWideChar(EncCharset), WriterOutput));
+ etCP: EXmlLite.Check(
+ CreateXmlWriterOutputWithEncodingCodePage(
+ DataCOMStream, HeapManager, EncCodePage, WriterOutput));
+ else;
+ end;
+
+ if nil <> WriterOutput
+ then Result := WriterOutput
+ else Result := DataCOMStream;
+ end;
+end;
+
+function xlHelper.Reader: IXMLReader;
+var
+ ReaderInput: IUnknown;
+begin
+ EXmlLite.Check(CreateXmlReader(XMLReaderGuid, Result, HeapManager));
+ if Result <> nil then
+ begin
+ EXmlLite.Check(Result.SetProperty(XmlReaderProperty.DtdProcessing,
+ Ord(XmlDtdProcessing.Parse)));
+ if Resolver <> nil then
+ EXmlLite.Check(Result.SetProperty(XmlReaderProperty.XmlResolver,
+ NativeInt(Pointer(Resolver)))); // did not tested!
+
+ ReaderInput := InternalCreateReaderStream;
+
+ if nil <> ReaderInput then
+ EXmlLite.Check(Result.SetInput(ReaderInput));
+ end;
+
+ Self.CreatedReaderWriter := Result;
+ CleanFor(dtNone);
+ CleanFor(etNone);
+end;
+
+function xlHelper.Writer: IXMLWriter;
+var
+ WriterOutput: IUnknown;
+begin
+ EXmlLite.Check(CreateXmlWriter(XMLWriterGuid, IUnknown(Result), HeapManager));
+ if (Result <> nil) then
+ begin
+ WriterOutput := InternalCreateWriterStream;
+
+ if WriterOutput <> nil then
+ EXmlLite.Check(Result.SetOutput(WriterOutput));
+ end;
+
+ Self.CreatedReaderWriter := Result;
+ CleanFor(dtNone);
+ CleanFor(etNone);
+end;
+
+{$WARN SYMBOL_library OFF}
+function xlHelper.LiteWriter: IXmlWriterLite;
+var
+ WriterOutput: IUnknown;
+begin
+ EXmlLite.Check(CreateXmlWriter(XMLWriterLiteGUID, IUnknown(Result), HeapManager));
+ if (Result <> nil) then
+ begin
+ WriterOutput := InternalCreateWriterStream;
+
+ if WriterOutput <> nil then
+ EXmlLite.Check(Result.SetOutput(WriterOutput));
+ end;
+
+ Self.CreatedReaderWriter := Result;
+ CleanFor(dtNone);
+ CleanFor(etNone);
+end;
+{$WARN SYMBOL_library Default}
+
+function xlHelper.OnDestroy(const callback: TAfterXmlLiteCreationHelper;
+ const UserData: Pointer): IXmlLiteCreationHelper;
+begin
+ DestroyingCallBack := callback;
+ DestroyingTag := UserData;
+
+ Result := Self;
+end;
+
+destructor xlHelper.Destroy;
+begin
+ if Assigned( DestroyingCallBack ) then
+ DestroyingCallBack( CreatedReaderWriter, DestroyingTag);
+
+ CleanFor(dtNone);
+ CleanFor(etNone);
+
+ inherited;
+end;
+
+procedure xlHelper.CleanFor(const Mode: xlEncType);
+begin
+ if Mode = EncType then exit;
+
+ if Mode <> etName then
+ EncCharset := '';
+ if Mode <> etCP then
+ EncCodePage := 0;
+
+ EncType := Mode;
+end;
+
+procedure xlHelper.CleanFor(const Mode: xlDataType);
+begin
+ if Mode = DataType then exit;
+
+ if Mode <> dtFileName then
+ DataFileName := '';
+ if Mode <> dtCOM then
+ DataCOMStream := nil;
+ if Mode <> dtDelphiStream then
+ begin
+ if DataDSOwn then
+ DataDSObject.Free;
+ DataDSObject := nil;
+ end;
+
+ DataType := Mode;
+end;
+
{ EXmlLite }
constructor EXmlLite.CreateForErrCode(const FunctionResult: HRESULT);