Ignore:
Timestamp:
Apr 17, 2019, 12:58:41 AM (5 years ago)
Author:
chronos
Message:
  • Modified: Propagate project build mode options to used packages.
  • Added: Check memory leaks using heaptrc.
  • Modified: Update BGRABitmap package.
Location:
GraphicTest
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • GraphicTest

    • Property svn:ignore
      •  

        old new  
        88GraphicTest.lps
        99GraphicTest.dbg
         10heaptrclog.trc
  • GraphicTest/Packages/bgrabitmap/bgramultifiletype.pas

    r494 r521  
    22
    33{$mode objfpc}{$H+}
     4{$MODESWITCH ADVANCEDRECORDS}
    45
    56interface
     
    78uses
    89  Classes, SysUtils, fgl;
     10
     11type
     12
     13  { TEntryFilename }
     14
     15  TEntryFilename = record
     16  private
     17    FExtension: utf8string;
     18    FName: utf8string;
     19    function GetFilename: utf8string;
     20    function GetIsEmpty: boolean;
     21    procedure SetExtension(AValue: utf8string);
     22    procedure SetFilename(AValue: utf8string);
     23    procedure SetName(AValue: utf8string);
     24  public
     25    class operator =(const AValue1,AValue2: TEntryFilename): boolean;
     26    property Filename: utf8string read GetFilename write SetFilename;
     27    property Name: utf8string read FName write SetName;
     28    property Extension: utf8string read FExtension write SetExtension;
     29    property IsEmpty: boolean read GetIsEmpty;
     30  end;
     31
     32function EntryFilename(AName,AExtension: string): TEntryFilename; overload;
     33function EntryFilename(AFilename: string): TEntryFilename; overload;
    934
    1035type
     
    2247  public
    2348    constructor Create(AContainer: TMultiFileContainer);
    24     function CopyTo({%H-}ADestination: TStream): integer; virtual;
     49    function CopyTo({%H-}ADestination: TStream): int64; virtual;
    2550    property Name: utf8string read GetName write SetName;
    2651    property Extension: utf8string read GetExtension;
     
    3863  protected
    3964    procedure Init; virtual;
    40     function AddEntry(AEntry: TMultiFileEntry): integer;
     65    function AddEntry(AEntry: TMultiFileEntry; AIndex: integer = -1): integer;
    4166    function GetCount: integer;
    4267    function GetEntry(AIndex: integer): TMultiFileEntry;
    4368    function CreateEntry(AName: utf8string; AExtension: utf8string; AContent: TStream): TMultiFileEntry; virtual; abstract;
     69    function GetRawString(AIndex: integer): RawByteString;
     70    function GetRawStringByFilename(AFilename: string): RawByteString;
     71    procedure SetRawString(AIndex: integer; AValue: RawByteString);
     72    procedure SetRawStringByFilename(AFilename: string; AValue: RawByteString);
    4473  public
    45     constructor Create;
    46     constructor Create(AFilename: utf8string);
    47     constructor Create(AStream: TStream);
    48     constructor Create(AStream: TStream; AStartPos: Int64);
    49     function Add(AName: utf8string; AExtension: utf8string; AContent: TStream; AOverwrite: boolean = false; AOwnStream: boolean = true): integer;
    50     function Add(AName: utf8string; AExtension: utf8string; AContent: utf8String; AOverwrite: boolean = false): integer;
     74    constructor Create; overload;
     75    constructor Create(AFilename: utf8string); overload;
     76    constructor Create(AStream: TStream); overload;
     77    constructor Create(AStream: TStream; AStartPos: Int64); overload;
     78    function Add(AName: utf8string; AExtension: utf8string; AContent: TStream; AOverwrite: boolean = false; AOwnStream: boolean = true): integer; overload;
     79    function Add(AName: utf8string; AExtension: utf8string; AContent: RawByteString; AOverwrite: boolean = false): integer; overload;
     80    function Add(AFilename: TEntryFilename; AContent: TStream; AOverwrite: boolean = false; AOwnStream: boolean = true): integer; overload;
     81    function Add(AFilename: TEntryFilename; AContent: RawByteString; AOverwrite: boolean = false): integer; overload;
    5182    procedure Clear; virtual;
    5283    destructor Destroy; override;
    5384    procedure LoadFromFile(AFilename: utf8string);
    5485    procedure LoadFromStream(AStream: TStream); virtual; abstract;
     86    procedure LoadFromResource(AFilename: string); virtual;
    5587    procedure SaveToFile(AFilename: utf8string);
    5688    procedure SaveToStream(ADestination: TStream); virtual; abstract;
    5789    procedure Remove(AEntry: TMultiFileEntry); virtual;
    58     procedure Delete(AIndex: integer); virtual; overload;
    59     function Delete(AName: utf8string; AExtension: utf8string;ACaseSensitive: boolean = True): boolean; overload;
    60     function IndexOf(AEntry: TMultiFileEntry): integer;
    61     function IndexOf(AName: utf8string; AExtenstion: utf8string; ACaseSensitive: boolean = True): integer; virtual;
     90    procedure Delete(AIndex: integer); overload; virtual;
     91    function Delete(AName: utf8string; AExtension: utf8string; ACaseSensitive: boolean = True): boolean; overload;
     92    function Delete(AFilename: TEntryFilename; ACaseSensitive: boolean = True): boolean; overload;
     93    function IndexOf(AEntry: TMultiFileEntry): integer; overload;
     94    function IndexOf(AName: utf8string; AExtenstion: utf8string; ACaseSensitive: boolean = True): integer; overload; virtual;
     95    function IndexOf(AFilename: TEntryFilename; ACaseSensitive: boolean = True): integer; overload;
    6296    property Count: integer read GetCount;
    6397    property Entry[AIndex: integer]: TMultiFileEntry read GetEntry;
     98    property RawString[AIndex: integer]: RawByteString read GetRawString write SetRawString;
     99    property RawStringByFilename[AFilename: string]: RawByteString read GetRawStringByFilename write SetRawStringByFilename;
    64100  end;
    65101
    66102implementation
    67103
    68 uses BGRAUTF8;
     104uses BGRAUTF8, strutils, BGRABitmapTypes;
     105
     106{ TEntryFilename }
     107
     108function TEntryFilename.GetFilename: utf8string;
     109begin
     110  if Extension = '' then
     111    result := Name
     112  else
     113    result := Name+'.'+Extension;
     114end;
     115
     116function TEntryFilename.GetIsEmpty: boolean;
     117begin
     118  result := (FName='') and (FExtension = '');
     119end;
     120
     121procedure TEntryFilename.SetExtension(AValue: utf8string);
     122var
     123  i: Integer;
     124begin
     125  if FExtension=AValue then Exit;
     126  for i := 1 to length(AValue) do
     127    if AValue[i] in ['.','/'] then
     128      raise Exception.Create('Invalid extension');
     129  FExtension:=AValue;
     130end;
     131
     132procedure TEntryFilename.SetFilename(AValue: utf8string);
     133var
     134  idxDot: SizeInt;
     135begin
     136  idxDot := RPos('.',AValue);
     137  if idxDot = 0 then
     138  begin
     139    Name := AValue;
     140    Extension := '';
     141  end
     142  else
     143  begin
     144    Name := copy(AValue,1,idxDot-1);
     145    Extension := copy(AValue,idxDot+1,length(AValue)-idxDot);
     146  end;
     147end;
     148
     149procedure TEntryFilename.SetName(AValue: utf8string);
     150var
     151  i: Integer;
     152begin
     153  if FName=AValue then Exit;
     154  for i := 1 to length(AValue) do
     155    if AValue[i] = '/' then
     156      raise Exception.Create('Invalid name');
     157  FName:=AValue;
     158end;
     159
     160function EntryFilename(AName, AExtension: string): TEntryFilename;
     161begin
     162  result.Name := AName;
     163  result.Extension:= AExtension;
     164end;
     165
     166function EntryFilename(AFilename: string): TEntryFilename;
     167begin
     168  result.Filename:= AFilename;
     169end;
     170
     171class operator TEntryFilename.=(const AValue1, AValue2: TEntryFilename): boolean;
     172begin
     173  result := (AValue1.Name = AValue2.Name) and (AValue1.Extension = AValue2.Extension);
     174end;
    69175
    70176{ TMultiFileEntry }
     
    85191end;
    86192
    87 function TMultiFileEntry.CopyTo(ADestination: TStream): integer;
     193function TMultiFileEntry.CopyTo(ADestination: TStream): int64;
    88194begin
    89195  result := 0;
     
    94200function TMultiFileContainer.GetCount: integer;
    95201begin
    96   result := FEntries.Count;
     202  if Assigned(FEntries) then
     203    result := FEntries.Count
     204  else
     205    result := 0;
    97206end;
    98207
     
    102211end;
    103212
     213function TMultiFileContainer.GetRawString(AIndex: integer): RawByteString;
     214var s: TStringStream;
     215begin
     216  s := TStringStream.Create('');
     217  try
     218    Entry[AIndex].CopyTo(s);
     219    result := s.DataString;
     220  finally
     221    s.Free;
     222  end;
     223end;
     224
     225function TMultiFileContainer.GetRawStringByFilename(AFilename: string
     226  ): RawByteString;
     227var
     228  idx: Integer;
     229begin
     230  idx := IndexOf(EntryFilename(AFilename));
     231  if idx = -1 then
     232    result := ''
     233  else
     234    result := GetRawString(idx);
     235end;
     236
     237procedure TMultiFileContainer.SetRawString(AIndex: integer;
     238  AValue: RawByteString);
     239begin
     240  with Entry[AIndex] do
     241    Add(Name, Extension, AValue, true);
     242end;
     243
     244procedure TMultiFileContainer.SetRawStringByFilename(AFilename: string;
     245  AValue: RawByteString);
     246var
     247  f: TEntryFilename;
     248begin
     249  f := EntryFilename(AFilename);
     250  Add(f.Name,f.Extension,AValue,true);
     251end;
     252
    104253procedure TMultiFileContainer.Init;
    105254begin
     
    107256end;
    108257
    109 function TMultiFileContainer.AddEntry(AEntry: TMultiFileEntry): integer;
    110 begin
    111   result := FEntries.Add(AEntry);
     258function TMultiFileContainer.AddEntry(AEntry: TMultiFileEntry; AIndex: integer): integer;
     259begin
     260  if not Assigned(FEntries) then
     261    raise exception.Create('Entry list not created');
     262  if (AIndex >= 0) and (AIndex < FEntries.Count) then
     263  begin
     264    FEntries.Insert(AIndex, AEntry);
     265    result := AIndex;
     266  end
     267  else
     268    result := FEntries.Add(AEntry);
    112269end;
    113270
     
    160317    newEntry := CreateEntry(AName, AExtension, AContent);
    161318  if Assigned(newEntry) then
    162     result := AddEntry(newEntry)
     319    result := AddEntry(newEntry, index)
    163320  else
    164321    raise exception.Create('Unable to create entry');
     
    166323
    167324function TMultiFileContainer.Add(AName: utf8string; AExtension: utf8string;
    168   AContent: utf8String; AOverwrite: boolean): integer;
     325  AContent: RawByteString; AOverwrite: boolean): integer;
    169326var stream: TMemoryStream;
    170327begin
    171328  stream := TMemoryStream.Create;
    172   stream.Write(AContent[1],length(AContent));
     329  if length(AContent) > 0 then stream.Write(AContent[1],length(AContent));
    173330  result := Add(AName,AExtension,stream,AOverwrite);
     331end;
     332
     333function TMultiFileContainer.Add(AFilename: TEntryFilename; AContent: TStream;
     334  AOverwrite: boolean; AOwnStream: boolean): integer;
     335begin
     336  result := Add(AFilename.Name,AFilename.Extension, AContent, AOverwrite, AOwnStream);
     337end;
     338
     339function TMultiFileContainer.Add(AFilename: TEntryFilename;
     340  AContent: RawByteString; AOverwrite: boolean): integer;
     341begin
     342  result := Add(AFilename.Name,AFilename.Extension, AContent, AOverwrite);
    174343end;
    175344
     
    187356  LoadFromStream(stream);
    188357  stream.Free;
     358end;
     359
     360procedure TMultiFileContainer.LoadFromResource(AFilename: string);
     361var
     362  stream: TStream;
     363begin
     364  stream := BGRAResource.GetResourceStream(AFilename);
     365  try
     366    LoadFromStream(stream);
     367  finally
     368    stream.Free;
     369  end;
    189370end;
    190371
     
    230411    result := true;
    231412  end;
     413end;
     414
     415function TMultiFileContainer.Delete(AFilename: TEntryFilename;
     416  ACaseSensitive: boolean): boolean;
     417begin
     418  result := Delete(AFilename.Name,AFilename.Extension,ACaseSensitive);
    232419end;
    233420
     
    259446end;
    260447
     448function TMultiFileContainer.IndexOf(AFilename: TEntryFilename;
     449  ACaseSensitive: boolean): integer;
     450begin
     451  result := IndexOf(AFilename.Name,AFilename.Extension,ACaseSensitive);
     452end;
     453
    261454procedure TMultiFileContainer.Clear;
    262455var
Note: See TracChangeset for help on using the changeset viewer.