zoukankan      html  css  js  c++  java
  • acFileStorage equivalent

    searching for a vcl that can enable embed any files within dfm similar to acfilestorage

    When there are bugs with the file naming, then the porting wasn't completely done. The problem with "malformed" strings is still always the same. A string is treated as ANSI, but since Delphi 2009 the strings in Delphi has the Unicode format. What means, a string of Length 5 needs 10 bytes to store. Another typical fault is to treat a Unicode Buffer as ANSI. Such things leads always into "malformed" strings.

    Now, you need to change the way the file name is stored. The function "WriteStream(…)" should be something like this…

    Code:
    procedure TStoredFile.WriteData(Stream: TStream);
    var
      Buffer: TArray<Byte>;
      TheSize: Cardinal;
      Target: Pointer;
    begin
      // storing the file name
      Buffer := TEncoding.UTF8.GetBytes(FFileName);       <- The filename is converted to UTF8…
      TheSize := Length(Buffer);
      Stream.Write(TheSize, 4);
      Stream.Write(Buffer, 0, TheSize);                   <- …and the bytes will be written
    
      // pack and write data
      TheSize := SFCalcTargetSz(FSize); // calculate required size for taget buffer
      GetMem(Target, TheSize);
      try
        TheSize := SFPack(FData.Memory, Target, FSize);
        Stream.Write(TheSize, 4); // compressed size
        Stream.Write(Target^, TheSize); // original size and compressed data
      finally
        FreeMem(Target);
      end;
    end;

    Here is the function "ReadStream(…)"…

    Code:
    procedure TStoredFile.ReadData(Stream: TStream);
    var
      Buffer: TArray<Byte>;
      TheSize: Cardinal;
      Source: Pointer;
    begin
      // reading the file name
      Stream.Read(TheSize, SizeOf(TheSize));
      SetLength(Buffer, TheSize);
      Stream.Read(Buffer, 0, TheSize);                              <- Read the UTF8 Bytes…
      FFileName := TEncoding.UTF8.GetString(Buffer, 0, TheSize);    <- …and convert them back to Unicode
    
      // reading the file size
      Stream.Read(TheSize, 4); // compressed size
      if (Owner = nil) or TacFileStorage(Owner).Compressed then
      begin
        dec(TheSize, 4);
        GetMem(Source, TheSize); // allocating memory for compressed buffer
        Stream.Read(FSize, 4); // original size
        FData.SetSize(FSize); // allocating memory for decompressed buffer
        try
          Stream.Read(Source^, TheSize); // reading compressed data
          SFUnpack(Source, FData.Memory, TheSize);
        finally
          FreeMem(Source);
        end
      end
      else // this is for compatibility with older versions
      begin
        FSize := TheSize;
        FData.SetSize(FSize);
        // reading the stream
        Stream.ReadBuffer(FData.Memory^, FSize);
      end;
    end;

    The filename is stored in the format UTF8 byte, which allows in the best case one Byte for one Character. Please remember Unicode needs two Bytes per Character.

    Useless to say, that this is a breaking change. The chance is high, that existing streams couldn't be read sucessfulyy. In this case the DFM should be clear manually. I should be enough to remove the content of the property "StoredData = { ... }", which is easy to find. The component could then be loaded again.


    Note: Now, it's not recommended to use the component TacFileStorage, because in the worst case a file with 1 MiB became 2 MiB, because of it is stored as Hex string. It would be much better to use a resource file that is unpacked on run-time.

    https://www.board4allcz.eu/showthread.php?t=626035

  • 相关阅读:
    usb_submit_urb
    xilinx uboot网卡驱动分析
    kernel: swapper: page allocation failure. order:1, mode:0x20
    Linux格式化硬盘 常用命令小记
    spring3:对JDBC的支持 之 JDBC模板类
    spring3: AOP 之代理机制
    spring3: AOP 之切面实例化模型 ——跟我学spring3
    spring3: AOP 之 通知顺序
    spring3: AOP 之 通知参数
    spring3: 切面及通知实例 Aspectj的aop
  • 原文地址:https://www.cnblogs.com/findumars/p/5384046.html
Copyright © 2011-2022 走看看