Skip to content

Commit

Permalink
- OXmlLng.pas was missing in commit 18, added.
Browse files Browse the repository at this point in the history
- small changes in OTextReadWrite.pas (more intuitive default encoding behaviour).
  • Loading branch information
on.pokorny@gmail.com committed Mar 20, 2014
1 parent 35f4164 commit bcc32f4
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 29 deletions.
63 changes: 34 additions & 29 deletions OTextReadWrite.pas
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ TOTextReader = class(TObject)
protected protected
procedure DoCreate(const aBufferSize: Integer); virtual; procedure DoCreate(const aBufferSize: Integer); virtual;
procedure DoInit(const aNewStream: TStream; const aNewOwnsStream: Boolean; procedure DoInit(const aNewStream: TStream; const aNewOwnsStream: Boolean;
const aDefaultSingleByteEncoding: TEncoding); virtual; const aDefaultEncoding: TEncoding); virtual;
public public
//create //create
constructor Create(const aBufferSize: Integer = OBUFFEREDSTREAMS_DEFBUFFERSIZE); overload; constructor Create(const aBufferSize: Integer = OBUFFEREDSTREAMS_DEFBUFFERSIZE); overload;
//create and init //create and init
constructor Create(const aStream: TStream; constructor Create(const aStream: TStream;
const aDefaultSingleByteEncoding: TEncoding = nil; const aDefaultEncoding: TEncoding = nil;
const aBufferSize: Integer = OBUFFEREDSTREAMS_DEFBUFFERSIZE); overload; const aBufferSize: Integer = OBUFFEREDSTREAMS_DEFBUFFERSIZE); overload;


destructor Destroy; override; destructor Destroy; override;
Expand All @@ -103,16 +103,16 @@ TOTextReader = class(TObject)
// Please note that the file/stream/... is locked until the end of the // Please note that the file/stream/... is locked until the end of the
// document is reached or you call ReleaseDocument! // document is reached or you call ReleaseDocument!


//aDefaultSingleByteEncoding - if no BOM is found, use this encoding, //aDefaultEncoding - if no BOM is found, use this encoding,
// if BOM is found, always correct encoding from the BOM is used // if BOM is found, always the correct encoding from the BOM is used


//load document from file //load document from file
// if aForceEncoding<>nil : enforce encoding (<?xml encoding=".."?> is ignored) // if aForceEncoding<>nil : enforce encoding (<?xml encoding=".."?> is ignored)
procedure InitFile(const aFileName: String; const aDefaultSingleByteEncoding: TEncoding = nil); procedure InitFile(const aFileName: String; const aDefaultEncoding: TEncoding = nil);
//load document from file //load document from file
// if aForceEncoding = nil: in encoding specified by the document // if aForceEncoding = nil: in encoding specified by the document
// if aForceEncoding<>nil : enforce encoding (<?xml encoding=".."?> is ignored) // if aForceEncoding<>nil : enforce encoding (<?xml encoding=".."?> is ignored)
procedure InitStream(const aStream: TStream; const aDefaultSingleByteEncoding: TEncoding = nil); procedure InitStream(const aStream: TStream; const aDefaultEncoding: TEncoding = nil);
//loads XML in default unicode encoding: UTF-16 for DELPHI, UTF-8 for FPC //loads XML in default unicode encoding: UTF-16 for DELPHI, UTF-8 for FPC
procedure InitString(const aString: OWideString); procedure InitString(const aString: OWideString);
{$IFDEF O_RAWBYTESTRING} {$IFDEF O_RAWBYTESTRING}
Expand All @@ -122,7 +122,7 @@ TOTextReader = class(TObject)
//load document from TBytes buffer //load document from TBytes buffer
// if aForceEncoding = nil: in encoding specified by the document // if aForceEncoding = nil: in encoding specified by the document
// if aForceEncoding<>nil : enforce encoding (<?xml encoding=".."?> is ignored) // if aForceEncoding<>nil : enforce encoding (<?xml encoding=".."?> is ignored)
procedure InitBuffer(const aBuffer: TBytes; const aDefaultSingleByteEncoding: TEncoding = nil); procedure InitBuffer(const aBuffer: TBytes; const aDefaultEncoding: TEncoding = nil);
{$ENDIF} {$ENDIF}


//Release the current document (that was loaded with Init*) //Release the current document (that was loaded with Init*)
Expand Down Expand Up @@ -232,7 +232,7 @@ EOTextReader = class(Exception);
function GetEncodingFromStream(const aStream: TStream; function GetEncodingFromStream(const aStream: TStream;
var {%H-}ioTempStringPosition: ONativeInt; var {%H-}ioTempStringPosition: ONativeInt;
const aLastPosition: ONativeInt; const aLastPosition: ONativeInt;
const {%H-}aDefaultSingleByteEncoding: TEncoding): TEncoding; const {%H-}aDefaultEncoding: TEncoding): TEncoding;


implementation implementation


Expand All @@ -241,22 +241,21 @@ implementation
{$IFDEF FPC} {$IFDEF FPC}
LazUTF8, LazUTF8,
{$ENDIF} {$ENDIF}
OXmlLNG; OXmlLng;


function GetEncodingFromStream(const aStream: TStream; function GetEncodingFromStream(const aStream: TStream;
var ioTempStringPosition: ONativeInt; var ioTempStringPosition: ONativeInt;
const aLastPosition: ONativeInt; const aLastPosition: ONativeInt;
const aDefaultSingleByteEncoding: TEncoding): TEncoding; const aDefaultEncoding: TEncoding): TEncoding;
var var
xSize: Integer; xSize: Integer;
xBuffer: TEncodingBuffer; xBuffer: TEncodingBuffer;
xEncoding: TEncoding; xEncoding: TEncoding;
begin begin
//MULTI BYTE ENCODINGS MUST HAVE A BOM DEFINED!!! if Assigned(aDefaultEncoding) then
if Assigned(aDefaultSingleByteEncoding) and aDefaultSingleByteEncoding.IsSingleByte then Result := aDefaultEncoding
Result := aDefaultSingleByteEncoding
else else
Result := TEncoding.Ansi; Result := TEncoding.Default;


xSize := aLastPosition - aStream.Position; xSize := aLastPosition - aStream.Position;
if xSize < 2 then if xSize < 2 then
Expand All @@ -273,8 +272,14 @@ function GetEncodingFromStream(const aStream: TStream;


if Assigned(xEncoding) then if Assigned(xEncoding) then
Result := xEncoding; Result := xEncoding;

if not Assigned(Result) then if not Assigned(Result) then
Result := TEncoding.{$IFDEF O_DELPHI_XE2_UP}ANSI{$ELSE}ASCII{$ENDIF}; begin
if Assigned(aDefaultEncoding) then
Result := aDefaultEncoding
else
Result := TEncoding.Default;
end;


aStream.Position := ioTempStringPosition; aStream.Position := ioTempStringPosition;
end; end;
Expand All @@ -288,13 +293,13 @@ procedure TOTextReader.BlockFlushTempBuffer;
end; end;


constructor TOTextReader.Create(const aStream: TStream; constructor TOTextReader.Create(const aStream: TStream;
const aDefaultSingleByteEncoding: TEncoding; const aBufferSize: Integer); const aDefaultEncoding: TEncoding; const aBufferSize: Integer);
begin begin
inherited Create; inherited Create;


DoCreate(aBufferSize); DoCreate(aBufferSize);


InitStream(aStream, aDefaultSingleByteEncoding); InitStream(aStream, aDefaultEncoding);
end; end;


constructor TOTextReader.Create(const aBufferSize: Integer); constructor TOTextReader.Create(const aBufferSize: Integer);
Expand All @@ -320,7 +325,7 @@ procedure TOTextReader.DoCreate(const aBufferSize: Integer);
end; end;


procedure TOTextReader.DoInit(const aNewStream: TStream; procedure TOTextReader.DoInit(const aNewStream: TStream;
const aNewOwnsStream: Boolean; const aDefaultSingleByteEncoding: TEncoding); const aNewOwnsStream: Boolean; const aDefaultEncoding: TEncoding);
var var
xStreamPosition: Integer; xStreamPosition: Integer;
begin begin
Expand All @@ -336,7 +341,7 @@ procedure TOTextReader.DoInit(const aNewStream: TStream;
BlockFlushTempBuffer;//block because GetEncodingFromStream seeks back in stream! BlockFlushTempBuffer;//block because GetEncodingFromStream seeks back in stream!
try try
xStreamPosition := fStreamPosition; xStreamPosition := fStreamPosition;
fEncoding := GetEncodingFromStream(fStream, fStreamPosition, fStreamSize, aDefaultSingleByteEncoding); fEncoding := GetEncodingFromStream(fStream, fStreamPosition, fStreamSize, aDefaultEncoding);
fBOMFound := (xStreamPosition < fStreamPosition);//if BOM was found, fStreamPosition increased fBOMFound := (xStreamPosition < fStreamPosition);//if BOM was found, fStreamPosition increased
finally finally
UnblockFlushTempBuffer; UnblockFlushTempBuffer;
Expand All @@ -363,7 +368,7 @@ function TOTextReader.GetApproxStreamPosition: ONativeInt;


{$IFDEF O_GENERICBYTES} {$IFDEF O_GENERICBYTES}
procedure TOTextReader.InitBuffer(const aBuffer: TBytes; procedure TOTextReader.InitBuffer(const aBuffer: TBytes;
const aDefaultSingleByteEncoding: TEncoding); const aDefaultEncoding: TEncoding);
var var
xLength: Integer; xLength: Integer;
xNewStream: TStream; xNewStream: TStream;
Expand All @@ -375,34 +380,34 @@ procedure TOTextReader.InitBuffer(const aBuffer: TBytes;
xNewStream.WriteBuffer(aBuffer[0], xLength); xNewStream.WriteBuffer(aBuffer[0], xLength);
xNewStream.Position := 0; xNewStream.Position := 0;


DoInit(xNewStream, True, aDefaultSingleByteEncoding); DoInit(xNewStream, True, aDefaultEncoding);
end; end;
{$ENDIF} {$ENDIF}


procedure TOTextReader.InitFile(const aFileName: String; procedure TOTextReader.InitFile(const aFileName: String;
const aDefaultSingleByteEncoding: TEncoding); const aDefaultEncoding: TEncoding);
begin begin
DoInit( DoInit(
TFileStream.Create(aFileName, fmOpenRead or fmShareDenyNone), TFileStream.Create(aFileName, fmOpenRead or fmShareDenyNone),
True, True,
aDefaultSingleByteEncoding); aDefaultEncoding);
end; end;


procedure TOTextReader.InitStream(const aStream: TStream; procedure TOTextReader.InitStream(const aStream: TStream;
const aDefaultSingleByteEncoding: TEncoding); const aDefaultEncoding: TEncoding);
begin begin
if (aStream is TCustomMemoryStream) or (aStream is TFileStream) if (aStream is TCustomMemoryStream) or (aStream is TFileStream)
then begin then begin
//no need for buffering on memory stream or file stream //no need for buffering on memory stream or file stream
// buffering is here just because some (custom) streams may not support seeking // buffering is here just because some (custom) streams may not support seeking
// which is needed when reading encoding from xml header // which is needed when reading encoding from xml header
DoInit(aStream, False, aDefaultSingleByteEncoding); DoInit(aStream, False, aDefaultEncoding);
end else begin end else begin
//we need to buffer streams that do not support seeking (zip etc.) //we need to buffer streams that do not support seeking (zip etc.)
DoInit( DoInit(
TOBufferedReadStream.Create(aStream, fBufferSize), TOBufferedReadStream.Create(aStream, fBufferSize),
True, True,
aDefaultSingleByteEncoding); aDefaultEncoding);
end; end;
end; end;


Expand Down Expand Up @@ -528,13 +533,13 @@ function TOTextReader.ReadNextChar(var outChar: OWideChar): Boolean;


if fTempStringRemain > 0 then begin if fTempStringRemain > 0 then begin
outChar := fTempString[fTempStringPosition]; outChar := fTempString[fTempStringPosition];
case outChar of case Ord(outChar) of
#10: begin 10: begin
if fPreviousChar <> #13 then if fPreviousChar <> #13 then
Inc(fLine); Inc(fLine);
fLinePosition := 0; fLinePosition := 0;
end; end;
#13: begin 13: begin
fLinePosition := 0; fLinePosition := 0;
Inc(fLine); Inc(fLine);
end; end;
Expand Down
2 changes: 2 additions & 0 deletions OWideSupp.pas
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ TFormatSettings = record
DecimalSeparator: AnsiChar; DecimalSeparator: AnsiChar;
ThousandSeparator: AnsiChar; ThousandSeparator: AnsiChar;
TimeSeparator: AnsiChar; TimeSeparator: AnsiChar;
ListSeparator: AnsiChar;
ShortDateFormat: AnsiString; ShortDateFormat: AnsiString;
LongDateFormat: AnsiString; LongDateFormat: AnsiString;
ShortTimeFormat: AnsiString; ShortTimeFormat: AnsiString;
Expand Down Expand Up @@ -644,6 +645,7 @@ function OGetLocaleFormatSettings: TFormatSettings;
Result.DecimalSeparator := DecimalSeparator; Result.DecimalSeparator := DecimalSeparator;
Result.ThousandSeparator := #0; Result.ThousandSeparator := #0;
Result.TimeSeparator := TimeSeparator; Result.TimeSeparator := TimeSeparator;
Result.ListSeparator := ListSeparator;
Result.ShortDateFormat := ShortDateFormat; Result.ShortDateFormat := ShortDateFormat;
Result.LongDateFormat := LongDateFormat; Result.LongDateFormat := LongDateFormat;
Result.ShortTimeFormat := ShortTimeFormat; Result.ShortTimeFormat := ShortTimeFormat;
Expand Down
90 changes: 90 additions & 0 deletions OXmlLng.pas
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,90 @@
unit OXmlLng;

{
Author:
Ondrej Pokorny, http://www.kluug.net
All Rights Reserved.
License:
MPL 1.1 / GPLv2 / LGPLv2 / FPC modified LGPLv2
Please see the /license.txt file for more information.
}

{
OXmlLng.pas
Language definitions for OXml library.
}

{$I OXml.inc}

{$IFDEF O_DELPHI_XE4_UP}
{$ZEROBASEDSTRINGS OFF}
{$ENDIF}

{$IFDEF FPC}
{$MODE DELPHI}
{$ENDIF}

{$BOOLEVAL OFF}

interface

var
OXmlLng_InvalidCData: String = '"%s" is not a valid CData text.';
OXmlLng_InvalidText: String = '"%s" is not a valid text.';
OXmlLng_InvalidComment: String = '"%s" is not a valid comment text.';
OXmlLng_InvalidPITarget: String = '"%s" is not a valid processing instruction target.';
OXmlLng_InvalidPIContent: String = '"%s" is not a valid processing instruction content.';
OXmlLng_InvalidAttributeName: String = '"%s" is not a valid attribute name.';
OXmlLng_InvalidElementName: String = '"%s" is not a valid element name.';
OXmlLng_InvalidCharacterInText: String = 'The character "%s" cannot occur in text.';
OXmlLng_InvalidCharacterInAttribute: String = 'The character "%s" cannot occur in attribute.';
OXmlLng_InvalidStringInText: String = 'The string "%s" cannot occur in text.';
OXmlLng_InvalidCharacterInElement: String = 'The character "%s" cannot occur in element header.';
OXmlLng_InvalidAttributeStartChar: String = 'An attribute cannot start with the character "%s".';
OXmlLng_EqualSignMustFollowAttribute: String = 'Equal sign must follow the attribute "%s".';
OXmlLng_AttributeValueMustBeEnclosed: String = '"%s" attribute value must be enclosed in quotes.';
OXmlLng_TooManyElementsClosed: String = 'Too many elements closed.';
OXmlLng_UnclosedElementsInTheEnd: String = 'There are unclosed elements in the document end.';
OXmlLng_WrongElementClosed: String = 'Trying to close wrong element. Close="%s", open element="%s".';
OXmlLng_InvalidEntity: String = '"%s" is not a valid entity.';
OXmlLng_ReadingAt: String =
'Reading at:'+sLineBreak+
'Line: %d'+sLineBreak+
'Char: %d'+sLineBreak+
'XML token line: %d'+sLineBreak+
'XML token char: %d'+sLineBreak+
'Position in source stub: %d'+sLineBreak+
'Source stub:'+sLineBreak+
'%s';

OXmlLng_XPathPredicateNotSupported: String = 'XPath predicate "%s" is not supported.'+sLineBreak+'XPath: %s';
OXmlLng_XPathPredicateNotValid: String = 'XPath predicate "%s" is not valid.'+sLineBreak+'XPath: %s';
OXmlLng_XPathNotSupported: String = 'XPath is not supported.'+sLineBreak+'XPath: %s';

OXmlLng_AppendFromDifferentDocument: String = 'You can''t append a node from a different XML document.';
OXmlLng_InsertFromDifferentDocument: String = 'You can''t insert a node from a different XML document.';
OXmlLng_InsertEqualNodes: String = 'Node to insert and reference node can''t be equal.';
OXmlLng_ParentNodeCantBeNil: String = 'Parent node can''t be nil.';
OXmlLng_ParentNodeMustBeNil: String = 'Parent node must be nil.';
OXmlLng_NodeToDeleteNotAChild: String = 'You can''t delete a node that is not a child of current node.';
OXmlLng_NodeToInsertNotAChild: String = 'You can''t insert node before a node that is not a child of current node.';
OXmlLng_NodeMustBeDOMDocumentOrElement: String = 'Node must be a DOMDocument or an element.';
OXmlLng_CannotSetText: String = 'You can''t set the text property of this node. Use NodeValue instead.';
OXmlLng_ChildNotFound: String = 'Child not found.';
OXmlLng_ListIndexOutOfRange: String = 'List index out of range.';
OXmlLng_FeatureNotSupported: String = 'This feature is not supported.';
OXmlLng_CannotWriteAttributesWhenFinished: String = 'You can''t add an attribute %s="%s" when the element header ("%s") has been finished.';
OXmlLng_CannotSetIndentLevelAfterWrite: String = 'You can''t set the IndentLevel after something has been already written to the document.';
OXmlLng_NodeNameCannotBeEmpty: String = 'Node name cannot be empty.';
OXmlLng_XPathCannotBeEmpty: String = 'XPath cannot be empty.';
OXmlLng_CannotWriteToVirtualMemoryStream: String = 'You cannot write to a TVirtualMemoryStream.';
OXmlLng_CannotUndo2Times: String = 'Unsupported: you tried to run the undo function two times in a row.';

implementation

end.

0 comments on commit bcc32f4

Please sign in to comment.