Permalink
Browse files

FPC + ARC support

My first modifications of original OmniXML code to support FPC and ARC Delphi.
-> I tried to make as little changes as possible:

1) I replaced GpTextStream.pas and GpStreamWrapper.pas (that are Windows-only) with OTextReadWrite.pas (that is Lazarus and ARC enabled).
2) I made OmniXML_Dictionary.pas compatible with Lazarus.
3) I fixed a performance bottle neck in TXMLCustomList: the "FList: TInterfaceList" has horrible performance in Delphi prior to 2007 and Lazarus due to critical sections (that are not necessary in my opinion). I changed it to TList<IXMLNode> in D2009+ and to normal TList with manual reference counting for non-unicode Delphi. This little change made nodes create about 3-4 times faster in non-unicode Delphi.

Everything else is 1:1 the original OmniXML code so everybody can upgrade without any problems.
  • Loading branch information...
1 parent 82df0f0 commit 5e405ea0957df3e6192af7258015fdedd4d5d5ee on.pokorny@gmail.com committed Dec 12, 2013
Showing with 3,287 additions and 1,798 deletions.
  1. +0 −273 GpStreamWrapper.pas
  2. +0 −1,240 GpTextStream.pas
  3. +382 −0 OBufferedStreams.pas
  4. +839 −0 OEncoding.pas
  5. +714 −0 OTextReadWrite.pas
  6. +1,019 −0 OWideSupp.pas
  7. +71 −0 OXml.inc
  8. +14 −8 OmniXML.inc
  9. +152 −256 OmniXML.pas
  10. +11 −1 OmniXMLConf.pas
  11. +6 −0 OmniXMLDatabase.pas
  12. +7 −3 OmniXMLPersistent.pas
  13. +5 −0 OmniXMLProperties.pas
  14. +6 −1 OmniXMLUtils.pas
  15. +6 −0 OmniXMLXPath.pas
  16. +30 −4 OmniXML_Dictionary.pas
  17. +6 −0 OmniXML_LookupTables.pas
  18. +6 −1 OmniXML_MSXML.pas
  19. +13 −11 OmniXML_Types.pas
View
@@ -1,273 +0,0 @@
-{$B-,H+,J+,Q-,T-,X+}
-
-(*:Some useful stream wrappers.
- @author Primoz Gabrijelcic
- @desc <pre>
- (c) 2012 Primoz Gabrijelcic
- Free for personal and commercial use. No rights reserved.
-
- Author : Primoz Gabrijelcic
- Creation date : 2001-07-17
- Last modification: 2012-04-24
- Version : 1.05
- </pre>
-*)(*
- History:
- 1.05: 2012-04-24
- - Added overload for 64-bit Seek.
- 1.04: 2006-09-21
- - TGpStreamWindow class moved to the GpStreams unit.
- 1.03: 2006-08-31
- - Enable int64-based interface for Delphi 6.
- 1.02: 2006-04-14
- - Added TGpStreamWindow class.
- 1.01: 2003-05-16
- - Made Delphi 7 compatible.
- 1.0: 2001-07-17
- - Released.
-*)
-
-unit GpStreamWrapper;
-
-{$IFDEF CONDITIONALEXPRESSIONS}
- {$IF (RTLVersion >= 14)} // Delphi 6.0 or newer
- {$DEFINE D6PLUS}
- {$IFEND}
-{$ENDIF}
-
-interface
-
-uses
- Classes;
-
-type
- {:Base stream wrapper class implementing the delayed Seek.
- }
- TGpStreamWrapper = class(TStream)
- private
- swDelayedSeek : boolean;
- swSeekMode : word;
- swSeekOffset : longint;
- swStoredPosition: longint;
- swStream : TStream;
- {$IFDEF D6Plus}
- private
- swDelayedSeek64 : boolean;
- swSeekOrigin : TSeekOrigin;
- {$ENDIF D6Plus}
- protected
- function GetPosition: {$IFDEF D6PLUS}int64;{$ELSE}longint;{$ENDIF D6PLUS} virtual;
- function GetSize: {$IFDEF D6PLUS}int64; override;{$ELSE}longint; virtual;{$ENDIF D6PLUS}
- procedure SetPosition(newPosition: {$IFDEF D6PLUS}int64{$ELSE}longint{$ENDIF D6PLUS}); virtual;
- procedure SetSize({$IFDEF D6PLUS}const{$ENDIF D6PLUS}newSize: {$IFDEF D6PLUS}int64{$ELSE}longint{$ENDIF D6PLUS}); override;
- function WrappedSeek(offset: integer; mode: word): longint; {$IFDEF D6PLUS}overload;{$ENDIF D6PLUS}virtual;
- {$IFDEF D6PLUS}
- function WrappedSeek(offset: int64; origin: TSeekOrigin): int64; overload; virtual;
- {$ENDIF D6PLUS}
- public
- constructor Create(wrappedStream: TStream);
- procedure DelayedSeek; virtual;
- function Seek(offset: integer; mode: word): longint; {$IFDEF D6PLUS}overload;{$ENDIF D6PLUS} override;
- {$IFDEF D6Plus}
- function Seek(const offset: int64; origin: TSeekOrigin): int64; overload; override;
- {$ENDIF D6Plus} {:Wrapped (underlying) stream.}
- property WrappedStream: TStream read swStream;
- end; { TGpStreamWrapper }
-
-implementation
-
-{ TGpStreamWrapper }
-
-constructor TGpStreamWrapper.Create(wrappedStream: TStream);
-begin
- inherited Create;
- swStream := wrappedStream;
-end; { TGpStreamWrapper.Create }
-
-{:Repositions stream pointer in the wrapped stream (if required). Call this
- method as a first thing in the descendant Read and Write methods.
-}
-procedure TGpStreamWrapper.DelayedSeek;
-begin
- {$IFDEF D6Plus}
- if swDelayedSeek64 then begin
- if (swSeekOffset <> 0) or (swSeekOrigin <> soCurrent) then
- WrappedSeek(swSeekOffset, swSeekOrigin);
- swDelayedSeek64 := false;
- end
- else
- {$ENDIF D6Plus}
- if swDelayedSeek then begin
- if (swSeekOffset <> 0) or (swSeekMode <> soFromCurrent) then
- WrappedSeek(swSeekOffset, swSeekMode);
- swDelayedSeek := false;
- end;
-end; { TGpStreamWrapper.DelayedSeek }
-
-{:Returns the position in the wrapping (virtual) stream. Trivial implementation
- from this class returns position of the wrapped (underlying) stream.
- If descendant overrides this method, it must never call TGpStreamWrapper.Seek
- (directly or indirectly).
-}
-function TGpStreamWrapper.GetPosition: {$IFDEF D6PLUS}int64;{$ELSE}longint;{$ENDIF D6PLUS}
-begin
- Result := WrappedStream.Position;
-end; { TGpStreamWrapper.GetPosition }
-
-{:Returns the size of the wrapping (virtual) stream. Trivial implementation
- from this class returns size of the wrapped (underlying) stream.
- If descendant overrides this method, it must never call TGpStreamWrapper.Seek
- (directly or indirectly).
-}
-function TGpStreamWrapper.GetSize: {$IFDEF D6PLUS}int64;{$ELSE}longint;{$ENDIF D6PLUS}
-begin
- Result := WrappedStream.Size;
-end; { TGpStreamWrapper.GetSize }
-
-{:Repositions stream pointer. Actually only stores this information for later
- use (when stream pointer position is really used).
- @param offset Offset from start, current position, or end of stream (as set
- by the 'mode' parameter) in bytes.
- @param mode Specifies starting point for offset calculation
- (soFromBeginning, soFromCurrent, soFromEnd).
- @returns New position of stream pointer.
-}
-function TGpStreamWrapper.Seek(offset: longint; mode: word): longint;
-begin
- // TStream is using following code to get Size of the stream:
- // Pos := Seek(0, soFromCurrent);
- // Result := Seek(0, soFromEnd);
- // Seek(Pos, soFromBeginning);
- // This code tries to hack around this stupid behaviour.
- if not swDelayedSeek then begin
- if (mode = soFromCurrent) and (offset = 0) then begin
- // possible GetSize call
- swDelayedSeek := true;
- swSeekOffset := offset;
- swSeekMode := mode;
- swStoredPosition := GetPosition;
- Result := swStoredPosition;
- end
- else // not a GetSize call, forward it
- Result := WrappedSeek(offset,mode);
- end
- else begin
- if mode = soFromCurrent then
- // not a GetSize call; saved Seek can only be (0,fromCurrent) - it is not
- // necessary to call DelayedSeek
- Result := WrappedSeek(offset,mode)
- else if mode = soFromEnd then begin
- if swSeekMode = soFromCurrent then begin
- // possible GetSize call
- swSeekOffset := offset;
- swSeekMode := mode;
- Result := GetSize;
- end
- else // not a GetSize call
- Result := WrappedSeek(offset,mode);
- end
- else {if mode = soFromBeginning} begin
- if (swSeekMode = soFromEnd) and (swStoredPosition = offset) then begin
- // definitely GetSize call
- swDelayedSeek := false;
- Result := swStoredPosition;
- end
- else // not a GetSize call
- Result := WrappedSeek(offset,mode);
- end;
- end;
-end; { TGpStreamWrapper.Seek }
-
-{:Repositions stream pointer. Actually only stores this information for later
- use (when stream pointer position is really used).
- @param offset Offset from start, current position, or end of stream (as set
- by the 'mode' parameter) in bytes.
- @param mode Specifies starting point for offset calculation
- (soFromBeginning, soFromCurrent, soFromEnd).
- @returns New position of stream pointer.
-}
-function TGpStreamWrapper.Seek(const offset: int64; origin: TSeekOrigin): int64;
-begin
- // TStream is using following code to get Size of the stream:
- // Pos := Seek(0, soFromCurrent);
- // Result := Seek(0, soFromEnd);
- // Seek(Pos, soFromBeginning);
- // This code tries to hack around this stupid behaviour.
- if not swDelayedSeek64 then begin
- if (origin = soCurrent) and (offset = 0) then begin
- // possible GetSize call
- swDelayedSeek64 := true;
- swSeekOffset := offset;
- swSeekOrigin := origin;
- swStoredPosition := GetPosition;
- Result := swStoredPosition;
- end
- else // not a GetSize call, forward it
- Result := WrappedSeek(offset, origin);
- end
- else begin
- if origin = soCurrent then
- // not a GetSize call; saved Seek can only be (0, fromCurrent) - it is not
- // necessary to call DelayedSeek
- Result := WrappedSeek(offset, origin)
- else if origin = soEnd then begin
- if swSeekOrigin = soCurrent then begin
- // possible GetSize call
- swSeekOffset := offset;
- swSeekOrigin := origin;
- Result := GetSize;
- end
- else // not a GetSize call
- Result := WrappedSeek(offset, origin);
- end
- else {if mode = soBeginning} begin
- if (swSeekOrigin = soEnd) and (swStoredPosition = offset) then begin
- // definitely GetSize call
- swDelayedSeek64 := false;
- Result := swStoredPosition;
- end
- else // not a GetSize call
- Result := WrappedSeek(offset, origin);
- end;
- end;
-end; { TGpStreamWrapper.Seek }
-
-{:Sets the position in the wrapping (virtual) stream. Trivial implementation
- from this class sets position of the wrapped (underlying) stream.
- If descendant overrides this method, it must never call TGpStreamWrapper.Seek
- (directly or indirectly).
-}
-procedure TGpStreamWrapper.SetPosition(newPosition: {$IFDEF D6PLUS}int64{$ELSE}longint{$ENDIF D6PLUS});
-begin
- WrappedStream.Position := newPosition;
-end; { TGpStreamWrapper.SetPosition }
-
-{:Sets the size of the wrapping (virtual) stream. Trivial implementation
- from this class sets position of the wrapped (underlying) stream.
- If descendant overrides this method, it must never call TGpStreamWrapper.Seek
- (directly or indirectly).
-}
-procedure TGpStreamWrapper.SetSize({$IFDEF D6PLUS}const{$ENDIF D6PLUS}newSize: {$IFDEF D6PLUS}int64{$ELSE}longint{$ENDIF D6PLUS});
-begin
- WrappedStream.Size := newSize;
-end; { TGpStreamWrapper.SetSize }
-
-{:Implementation of the 'true' Seek. Called only when Seek is really needed.
- Trivial implementation from this class calls Seek on the wrapped (underlying) stream.
- WrappedSeek must never call TGpStreamWrapper.Seek (directly or indirectly) but use
- directly WrappedStream.Seek.
-}
-function TGpStreamWrapper.WrappedSeek(offset: integer;
- mode: word): longint;
-begin
- Result := WrappedStream.Seek(offset, mode);
-end; { TGpStreamWrapper.WrappedSeek }
-
-{$IFDEF D6Plus}
-function TGpStreamWrapper.WrappedSeek(offset: int64; origin: TSeekOrigin): int64;
-begin
- Result := WrappedStream.Seek(offset, origin);
-end;
-{$ENDIF D6Plus}
-
-end.
Oops, something went wrong.

0 comments on commit 5e405ea

Please sign in to comment.