{ $OmniXML: OmniXML/extras/OmniXMLShared.pas,v 1.1 2004/06/07 13:06:32 mr Exp $ }
 
{$WEAKPACKAGEUNIT ON}
 
(*:XML helper unit. Contains class to manage shared XML document (stored in the
   resizable shared memory).
   @author Primoz Gabrijelcic
   @desc <pre>
   (c) 2002 Primoz Gabrijelcic
   Free for personal and commercial use. No rights reserved.
 
   Author            : Primoz Gabrijelcic
   Creation date     : 2002-05-13
   Last modification : 2002-09-24
   Version           : 1.01
</pre>*)(*
   History:
     1.01: 2002-09-24
       - Added property TGpSharedXML.CachedXML.
     1.0: 2002-05-13
       - Created.
*)
 
unit OmniXMLShared;
 
interface
 
uses
  Windows,
  GpSharedMemory,
  OmniXMLProperties;
 
type
  {:Shared XML document.
  }
  TGpSharedXML = class
  private
    sxOwnsXML     : boolean;
    sxSharedMemory: TGpSharedMemory;
    sxXMLDoc      : TGpXMLDoc;
  protected
    function  Acquire(forWriting: boolean; timeout: DWORD): TGpXMLDoc;
    function  GetName: string;
    function  GetXML: TGpXMLDoc;
  public
    constructor Create(sharedMemoryName: string; xmlDoc: TGpXMLDoc;
      maxSize: cardinal; ownsXML: boolean = true); virtual;
    destructor  Destroy; override;
    function  BeginUpdate(timeout: DWORD): TGpXMLDoc; virtual;
    procedure EndUpdate; virtual;
    function  Read(timeout: DWORD): TGpXMLDoc; virtual;
    property  CachedXML: TGpXMLDoc read sxXMLDoc;
    property  Name: string read GetName;
    property  XML: TGpXMLDoc read GetXML;
  end; { TGpSharedXML }
 
  {:Shared XML list.
  }
  TGpSharedXMLList = class(TGpSharedXML)
  public
    constructor Create(sharedMemoryName: string; xmlList: TGpXMLDocList;
      maxSize: cardinal; ownsXML: boolean = true); reintroduce; virtual;
    function Count: integer;
  end; { TGpSharedXMLList }
 
implementation
 
uses
{$IFDEF DebugXML}
  OmniXMLUtils,
  uDbg,
{$ENDIF DebugXML}
  SysUtils;
 
{ TGpSharedXML }
 
function TGpSharedXML.Acquire(forWriting: boolean;
  timeout: DWORD): TGpXMLDoc;
begin
  Result := nil;
  if sxSharedMemory.AcquireMemory(forWriting, timeout) <> nil then begin
      if (not sxSharedMemory.Modified) or
         sxXMLDoc.LoadFromStream(sxSharedMemory.AsStream)
      then
        Result := sxXMLDoc;
    if not assigned(Result) then
      sxSharedMemory.ReleaseMemory;
    {$IFDEF DebugXML}
    if assigned(Result) then
      Debugger.LogFmtMsg('Acquire: %s',[XMLSaveToString(sxXMLDoc.XMLDoc)]);
    {$ENDIF DebugXML}
  end;
end; { TGpSharedXML.Acquire }
 
function TGpSharedXML.BeginUpdate(timeout: DWORD): TGpXMLDoc;
begin
  Result := Acquire(true, timeout);
end; { TGpSharedXML.BeginUpdate }
 
constructor TGpSharedXML.Create(sharedMemoryName: string; xmlDoc: TGpXMLDoc;
  maxSize: cardinal; ownsXML: boolean);
begin
  inherited Create;
  sxSharedMemory := TGpSharedMemory.Create(sharedMemoryName, 0, maxSize);
  sxXMLDoc := xmlDoc;
  sxOwnsXML := ownsXML;
end; { TGpSharedXML.Create }
 
destructor TGpSharedXML.Destroy;
begin
  if sxOwnsXML then
    FreeAndNil(sxXMLDoc)
  else
    sxXMLDoc := nil;
  FreeAndNil(sxSharedMemory);
  inherited;
end; { TGpSharedXML.Destroy }
 
procedure TGpSharedXML.EndUpdate;
begin
  {$IFDEF DebugXML}
  Debugger.LogFmtMsg('Release: %s',[XMLSaveToString(sxXMLDoc.XMLDoc)]);
  {$ENDIF DebugXML}
  if sxSharedMemory.IsWriting then
    sxXMLDoc.SaveToStream(sxSharedMemory.AsStream);
  if sxSharedMemory.Acquired then
    sxSharedMemory.ReleaseMemory;
end; { TGpSharedXML.EndUpdate }
 
function TGpSharedXML.GetName: string;
begin
  Result := sxSharedMemory.Name;
end; { TGpSharedXML.GetName }
 
function TGpSharedXML.GetXML: TGpXMLDoc;
begin
  if not sxSharedMemory.Acquired then
    Result := nil
  else
    Result := sxXMLDoc;
end; { TGpSharedXML.GetXML }
 
function TGpSharedXML.Read(timeout: DWORD): TGpXMLDoc;
begin
  Result := Acquire(false, timeout);
  EndUpdate;
end; { TGpSharedXML.Read }
 
{ TGpSharedXMLList }
 
function TGpSharedXMLList.Count: integer;
begin
  Result := (XML as TGpXMLDocList).Count;
end; { TGpSharedXMLList.Count }
 
constructor TGpSharedXMLList.Create(sharedMemoryName: string;
  xmlList: TGpXMLDocList; maxSize: cardinal; ownsXML: boolean);
begin
  inherited Create(sharedMemoryName, xmlList, maxSize, ownsXML);
end; { TGpSharedXMLList.Create }
 
{$IFDEF DebugXML}
initialization
  NxStartDebug;
finalization
  NxEndDebug;
{$ENDIF DebugXML}
end.