olevariant序列

发布时间 2023-06-18 10:07:27作者: delphi中间件

olevariant序列

/// <author>cxg 2020-12-31</author>

unit yn.variant;

interface

uses
  classes, zlib, Variants, SysUtils;

{$IFNDEF UNICODE}
type
  RawByteString = AnsiString;
{$ENDIF}
{$if CompilerVersion < 18} //before delphi 2007
type
  TBytes = array of Byte;
{$ifend}

function bytes2var(const S: TBytes): OleVariant;
function var2bytes(const V: OleVariant): TBytes;
function raw2bytes(const raw: RawByteString): TBytes;
function bytes2raw(const bs: TBytes): RawByteString;
procedure var2stream(const V: OLEVariant; Stream: TStream);
procedure stream2var(Stream: TStream; var V: OLEVariant);
function zip(V: OleVariant): OleVariant;
function unzip(V: OleVariant): OleVariant;
function var2raw(const AData: OleVariant): rawbytestring;
function raw2var(const AText: rawbytestring): OleVariant;

implementation

function bytes2var(const S: TBytes): OleVariant;
var
  P: Pointer;
begin
  Result := NULL;
  if Length(S) > 0 then begin
    Result := VarArrayCreate([0, Length(S) - 1], varByte);
    P := VarArrayLock(Result);
    try
      Move(S[0], P^, Length(S));
    finally
      VarArrayUnlock(Result);
    end;
  end;
end;

function var2bytes(const V: OleVariant): TBytes;
var
  P: Pointer;
  Size: Integer;
begin
  if VarIsArray(V) and (VarType(V) and varTypeMask = varByte) then
  begin
    Size := VarArrayHighBound(V, 1) - VarArrayLowBound(V, 1) + 1;
    if Size > 0 then
    begin
      SetLength(Result, Size);
      P := VarArrayLock(V);
      try
        Move(P^, Result[0], Size);
      finally
        VarArrayUnlock(V);
      end;
    end;
  end;
end;

function raw2bytes(const raw: RawByteString): TBytes;
var
  len: integer;
begin
  len := length(raw);
  SetLength(result, len);
  Move(raw[1], Result[0], len);
end;

function bytes2raw(const bs: TBytes): RawByteString;
var
  len: integer;
begin
  len := Length(bs);
  SetLength(Result, len);
  Move(bs[0], Result[1], len);
end;

procedure var2stream(const V: OLEVariant; Stream: TStream);
var
  P: Pointer;
begin
  Stream.Position := 0;
  Stream.Size := VarArrayHighBound(V, 1) - VarArrayLowBound(V, 1) + 1;
  P := VarArrayLock(V);
  try
    Stream.Write(P^, Stream.Size);
  finally
    VarArrayUnlock(V);
  end;
  Stream.Position := 0;
end;

procedure stream2var(Stream: TStream; var V: OLEVariant);
var
  P: Pointer;
begin
  V := VarArrayCreate([0, Stream.Size - 1], varByte);
  P := VarArrayLock(V);
  try
    Stream.Position := 0;
    Stream.Read(P^, Stream.Size);
  finally
    VarArrayUnlock(V);
  end;
end;

function zip(V: OleVariant): OleVariant;
var
  M, M0: TMemoryStream;
begin
  M := TMemoryStream.Create;
  M0 := TMemoryStream.Create;
  try
    if V = Null then
      exit;
    var2stream(V, M);
    M.Position := 0;
    ZCompressStream(M, M0);
    Stream2Var(M0, V);
  finally
    M.Free;
    M0.Free
  end;
  Result := V;
end;

function unzip(V: OleVariant): OleVariant;
var
  M, M0: TMemoryStream;
begin
  M := TMemoryStream.Create;
  M0 := TMemoryStream.Create;
  try
    if V = Null then
      exit;
    Var2Stream(V, M);
    M.Position := 0;
    ZDeCompressStream(M, M0);
    Stream2Var(M0, V);
  finally
    M.Free;
    M0.Free
  end;
  Result := V;
end;

function var2raw(const AData: OleVariant): rawbytestring;
var
  nSize: Integer;
  pData: Pointer;
begin
  if AData = Null then
    Result := ''
  else
  begin
    nSize := VarArrayHighBound(AData, 1) - VarArrayLowBound(AData, 1) + 1;
    SetLength(Result, nSize);
    pData := VarArrayLock(AData);
    try
      Move(pData^, Pansichar(Result)^, nSize);
    finally
      VarArrayUnlock(AData);
    end;
  end;
end;

function raw2var(const AText: rawbytestring): OleVariant;
var
  nSize: Integer;
  pData: Pointer;
begin
  nSize := Length(AText);
  if nSize = 0 then
    Result := Null
  else
  begin
    Result := VarArrayCreate([0, nSize - 1], varByte);
    pData := VarArrayLock(Result);
    try
      Move(Pansichar(AText)^, pData^, nSize);
    finally
      VarArrayUnlock(Result);
    end;
  end;
end;

end.