首页 > 其他分享 >sys.data.pas

sys.data.pas

时间:2025-01-04 17:12:17浏览次数:1  
标签:pas const val pos len sys key data

sys.data.pas

unit sys.data;
// cxg 2024-12-22 key-value list
// fit (fpc+delphi)
{$ifdef fpc}
{$mode delphi}{$H+}
{$endif}

interface

uses Generics.Collections, Variants, SysUtils, Classes;

type
  raw = RawByteString;
  Praw = PRawByteString;
  int = integer;

  Tdata = class
  private
    key: raw; // The key must be unique
    val: TBytes; // value
  private
    list: TList<Tdata>;
  private
    function path(const key: raw): Tdata;
    function getByteCnt: int;
  private
    function getI(const key: raw): int;
    procedure setI(const key: raw; const Value: int);
    function getI64(const key: raw): Int64;
    procedure setI64(const key: raw; const Value: Int64);
    function getB(const key: raw): boolean;
    procedure setB(const key: raw; const Value: boolean);
    function getD(const key: raw): Double;
    procedure setD(const key: raw; const Value: Double);
    function getS(const key: raw): raw;
    procedure setS(const key, Value: raw);
    function getV(const key: raw): Variant;
    procedure setV(const key: raw; const Value: Variant);
    function getST(const key: raw): TStream;
    procedure setST(const key: raw; const Value: TStream);
  public
    property I[const key: raw]: int read getI write setI;
    property I64[const key: raw]: Int64 read getI64 write setI64;
    property B[const key: raw]: boolean read getB write setB;
    property D[const key: raw]: Double read getD write setD;
    property S[const key: raw]: raw read getS write setS;
    property V[const key: raw]: Variant read getV write setV;
    property ST[const key: raw]: TStream read getST write setST;
  public // marshal
    procedure toStream(stream: TStream);
    function toRaw: raw;
    function toBytes: TBytes;
  public // unmarshal
    procedure fromStream(stream: TStream);
    procedure fromRaw(const val: raw);
    procedure fromBytes(const val: TBytes);
  public
    constructor Create;
    destructor Destroy; override;
    procedure clear; // clear list;
  end;

implementation

procedure Tdata.clear;
begin
  while list.Count > 0 do
  begin
    list[0].free;
    list.Delete(0);
  end;
end;

constructor Tdata.Create;
begin
  list := TList<Tdata>.Create;
end;

destructor Tdata.Destroy;
begin
  clear;
  FreeAndNil(list);
end;

function Tdata.path(const key: raw): Tdata;
var
  I: int;
  found: boolean;
begin
  Result := nil;
  found := False;
  for I := 0 to list.Count - 1 do
  begin
    if key = list[I].key then
    begin
      Result := list[I];
      exit;
    end;
  end;
  if not found then
  begin
    Result := Tdata.Create;
    Result.key := key;
    list.Add(Result);
  end;
end;

procedure Tdata.fromBytes(const val: TBytes);
var
  data: Tdata;
  pos, len: int;
  key: raw;
begin
  pos := 0;
  while pos < length(val) do
  begin
    Move(val[pos], len, SizeOf(int));
    pos := pos + SizeOf(int);
    SetLength(key, len);
    Move(val[pos], Praw(key)^, len);
    pos := pos + len;
    Move(val[pos], len, SizeOf(int));
    pos := pos + SizeOf(int);
    data := Tdata.Create;
    SetLength(data.val, len);
    Move(val[pos], pbyte(data.val)^, len);
    pos := pos + len;
    data.key := key;
    list.Add(data);
  end;
end;

procedure Tdata.fromRaw(const val: raw);
var
  data: Tdata;
  pos, len: int;
  key: raw;
begin
  pos := 1;
  while pos < length(val) do
  begin
    Move(val[pos], len, SizeOf(int));
    pos := pos + SizeOf(int);
    SetLength(key, len);
    Move(val[pos], Praw(key)^, len);
    pos := pos + len;
    Move(val[pos], len, SizeOf(int));
    pos := pos + SizeOf(int);
    data := Tdata.Create;
    SetLength(data.val, len);
    Move(val[pos], pbyte(data.val)^, len);
    pos := pos + len;
    data.key := key;
    list.Add(data);
  end;
end;

procedure Tdata.fromStream(stream: TStream);
var
  len: int;
  key: raw;
  data: Tdata;
begin
  stream.Position := 0;
  while stream.Position < stream.size do
  begin
    stream.Read(len, SizeOf(int));
    SetLength(key, len);
    stream.Read(Praw(key)^, len);
    stream.Read(len, SizeOf(int));
    data := Tdata.Create;
    SetLength(data.val, len);
    stream.Read(pbyte(data.val)^, len);
    data.key := key;
    list.Add(data);
  end;
end;

function Tdata.getB(const key: raw): boolean;
var
  data: Tdata;
begin
  data := path(key);
  Result := PBoolean(data.val)^;
end;

function Tdata.getD(const key: raw): Double;
var
  data: Tdata;
begin
  data := path(key);
  Result := PDouble(data.val)^;
end;

function Tdata.getI(const key: raw): integer;
var
  data: Tdata;
begin
  data := path(key);
  Result := PInteger(data.val)^;
end;

function Tdata.getI64(const key: raw): Int64;
var
  data: Tdata;
begin
  data := path(key);
  Result := PInt64(data.val)^;
end;

function Tdata.getS(const key: raw): raw;
var
  data: Tdata;
  len: int;
begin
  data := path(key);
  len := length(data.val);
  if len = 0 then
    Result := ''
  else
  begin
    SetLength(Result, len);
    Move(pbyte(data.val)^, Praw(Result)^, len);
  end;
end;

function Tdata.getByteCnt: integer;
var
  I: int;
begin
  Result := 0;
  for I := 0 to list.Count - 1 do
    Result := Result + SizeOf(int) * 2 + length(list[I].key) +
      length(list[I].val);
end;

function Tdata.getST(const key: raw): TStream;
var
  data: Tdata;
  len: int;
begin
  data := path(key);
  len := length(data.val);
  Result := TMemoryStream.Create;
  Result.size := len;
  Result.Write(pbyte(data.val)^, len);
  Result.Position := 0;
end;

function Tdata.getV(const key: raw): Variant;
var
  p: pbyte;
  len: int;
  data: Tdata;
begin
  data := path(key);
  len := length(data.val);
  Result := VarArrayCreate([0, len - 1], varByte);
  p := VarArrayLock(Result);
  try
    Move(pbyte(data.val)^, p^, len);
  finally
    VarArrayUnlock(Result);
  end;
end;

procedure Tdata.setB(const key: raw; const Value: boolean);
var
  data: Tdata;
begin
  data := path(key);
  SetLength(data.val, SizeOf(boolean));
  PBoolean(data.val)^ := Value;
end;

procedure Tdata.setD(const key: raw; const Value: Double);
var
  data: Tdata;
begin
  data := path(key);
  SetLength(data.val, SizeOf(Double));
  PDouble(data.val)^ := Value;
end;

procedure Tdata.setI(const key: raw; const Value: integer);
var
  data: Tdata;
begin
  data := path(key);
  SetLength(data.val, SizeOf(int));
  PInteger(data.val)^ := Value;
end;

procedure Tdata.setI64(const key: raw; const Value: Int64);
var
  data: Tdata;
begin
  data := path(key);
  SetLength(data.val, SizeOf(Int64));
  PInt64(data.val)^ := Value;
end;

procedure Tdata.setS(const key, Value: raw);
var
  len: int;
  data: Tdata;
begin
  data := path(key);
  len := length(Value);
  SetLength(data.val, len);
  if len > 0 then
    Move(Praw(Value)^, pbyte(data.val)^, len);
end;

procedure Tdata.setST(const key: raw; const Value: TStream);
var
  data: Tdata;
begin
  data := path(key);
  SetLength(data.val, Value.size);
  Value.Position := 0;
  Value.Read(pbyte(data.val)^, Value.size);
  Value.Position := 0;
end;

procedure Tdata.setV(const key: raw; const Value: Variant);
var
  p: pbyte;
  len: int;
  data: Tdata;
begin
  data := path(key);
  len := VarArrayHighBound(Value, 1) - VarArrayLowBound(Value, 1) + 1;
  p := VarArrayLock(Value);
  try
    SetLength(data.val, len);
    Move(p^, pbyte(data.val)^, len);
  finally
    VarArrayUnlock(Value);
  end;
end;

function Tdata.toBytes: TBytes;
var
  I, len, pos: int;
begin
  SetLength(Result, getByteCnt);
  pos := 0;
  for I := 0 to list.Count - 1 do
  begin
    len := length(list[I].key);
    Move(len, Result[pos], SizeOf(int));
    pos := pos + SizeOf(int);
    Move(Praw(list[I].key)^, Result[pos], len);
    pos := pos + len;
    len := length(list[I].val);
    Move(len, Result[pos], SizeOf(int));
    pos := pos + SizeOf(int);
    Move(pbyte(list[I].val)^, Result[pos], len);
    pos := pos + len;
  end;
end;

function Tdata.toRaw: raw;
var
  I, len, pos: int;
begin
  SetLength(Result, getByteCnt);
  pos := 1;
  for I := 0 to list.Count - 1 do
  begin
    len := length(list[I].key);
    Move(len, Result[pos], SizeOf(int));
    pos := pos + SizeOf(int);
    Move(Praw(list[I].key)^, Result[pos], len);
    pos := pos + len;
    len := length(list[I].val);
    Move(len, Result[pos], SizeOf(int));
    pos := pos + SizeOf(int);
    Move(pbyte(list[I].val)^, Result[pos], len);
    pos := pos + len;
  end;
end;

procedure Tdata.toStream(stream: TStream);
var
  I, len: int;
begin
  stream.Position := 0;
  for I := 0 to list.Count - 1 do
  begin
    len := length(list[I].key);
    stream.Write(len, SizeOf(int));
    stream.Write(Praw(list[I].key)^, len);
    len := length(list[I].val);
    stream.Write(len, SizeOf(int));
    stream.Write(pbyte(list[I].val)^, len);
  end;
  stream.Position := 0;
end;

end.

 

标签:pas,const,val,pos,len,sys,key,data
From: https://www.cnblogs.com/hnxxcxg/p/18652114

相关文章

  • 银河麒麟Linux同步时间:NTPd、Chrony、systemd-timesyncd 配置与使用
    1.时间同步协议服务对比在网络中,常用的时间同步协议服务主要有以下几种:特性NTPdsystemd-timesyncdChrony协议NTPSNTPNTP说明NTPd(NetworkTimeProtocoldaemon)是最经典的时间同步服务,使用NTP协议来同步系统时间。它支持复杂的配置,能够处理多个时间源,并且具有......
  • Linux系统centos7,怎么配置yum,以及Errno 14 curl#37 - “Couldn‘t open file /dvd/App
    情况:我手上是一个删掉Windows系统,依靠centos7重装了Linux系统的电脑,里面是空的,什么都没有。加上在今年6月份,上游已经放弃centos7的维护,之前的一些源和网站都没用,那些教程也就没用了。步骤:1.进入root账号,这样才有足够权限做后面的事 2.检查网络是否可以连接外网。拿阿......
  • JavaScript的引用数据类型(Reference Data Types)
    Python基础Python是一种广泛使用的高级编程语言,凭借其简单易读的语法、丰富的库和框架、以及强大的社区支持,Python在数据科学、机器学习、网络开发、自动化脚本等多个领域中得到了广泛应用。本文将介绍Python的基础知识,包括语法、数据结构、控制结构、函数、模块与包等内容......
  • JavaScript的数据封装(Data Encapsulation)
    Python基础Python是一种高级编程语言,由GuidovanRossum于1991年首次发布。由于其简单易读的语法、强大的功能和丰富的库,Python已经成为当今最受欢迎的编程语言之一。无论您是初学者还是有经验的开发者,掌握Python都将为您的编程之路打开新的大门。在本文中,我们将探讨Python......
  • HTML Select Drop Down List Data Source From Web API
    前端,html还是mvc页面,我们想实现一个下拉选单,写<select>指定id或者name,稍后在js代码能获取到它。 #7~#9行,没有参数条件可传,保留为空。#19WebAPI地址。#21为异步方法,看下,#37,是为了不让代码写在一块,Insus.NET已经重构成另一个function,也是本示例中重点核心代码,下面继续看看,......
  • 用Python进行Data-Matrix进行识别
    一、描述用大恒工业相机进行拍摄,因项目不方便,所以不妨原图,放置二值化后的图和选取的位置图二、上代码处理#图像二值化defpreprocess_image(image_path):image=cv2.imread(image_path,cv2.IMREAD_GRAYSCALE)_,binary=cv2.threshold(image,190,255,cv2.THRE......
  • Easysearch Java SDK 2.0.x 使用指南(三)
    在EasysearchJavaSDK2.0.x使用指南(一)中,我们介绍了EasysearchJavaSDK2.0.2的基本使用和批量操作功能。在EasysearchJavaSDK2.0.x使用指南(二)中,则详细介绍了索引管理相关的功能,包括索引的创建、删除、开关、刷新、滚动等操作,以及新版SDK提供的同步和异步两种调用......
  • 在Lazarus下的Free Pascal编程教程——打造有智慧的人机交互界面
    0.前言我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程。我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识。了解我编写教程的思路,请参阅体现我最初想法的那篇文章中的“1.编程计划”和“2.已......
  • 使用学生优惠创建 Azure Database for MySQL 数据库
    前言在此之前,你需要拥有一个已通过学生认证的Azure账户。关于通过Azure学生认证,网上已有大量教程,此处不再赘述。前些日子认证通过了Azure的学生认证,在部署此网站时发现Azure的B1s服务器用来部署网站同时部署数据库会出现内存不足的情况,同时想到Azure还为学生用户提......
  • Spring Data REST 远程代码执行漏洞(CVE-2017-8046)分析与复现15
    前言2009年9月Spring3.0RC1发布后,Spring就引入了SpEL(SpringExpressionLanguage)。对于开发者而言,引入新的工具显然是令人兴奋的,但是对于运维人员,也许是噩耗的开始。类比Struts2框架,会发现绝大部分的安全漏洞都和ognl脱不了干系。尤其是远程命令执行漏洞,占据了多少甲方乙方......