unit utslvclauxiliary; {** @explan(说明) tslvcl 辅助库 %% **} interface type TCharDiscrimi=class static CD_SMA; static CD_BGA; static CD_SMZ; static CD_BGZ; static CD_UDL; static CD_NIN; static CD_ZER; static CD_ISOK; class function sinit();virtual; begin if not CD_ISOK then begin K := 1; CD_SMA := ord("a"); CD_BGA := ord("A"); CD_SMZ := ord("z"); CD_BGZ := ord("Z"); CD_UDL := ord("_"); CD_NIN := ord("9"); CD_ZER := ord("0"); CD_ISOK := 1; end end class function IsLetter(cc); begin return IsUppercaseLetter(CC)OR IsLowercaseLetter(cc); end class function IsLowercaseLetter(cc); begin return(cc >= CD_SMA)and(cc <= CD_SMZ); end class function IsUppercaseLetter(cc); begin return(cc >= CD_BGA)and(cc <= CD_BGZ); end class function IsNumber(cc); begin return(cc >= CD_ZER)and(cc <= CD_NIN); end class function IsVariableName(s); begin if ifstring(s)and length(s)>= 1 then begin cc := ord(s[1]); if IsLetter(cc)or cc=CD_UDL then begin for i := 2 To length(s) do begin cc := ord(s[i]); if not(IsLetter(cc)or IsNumber(cc)or(cc=CD_UDL))then begin return false; end end return true; end end return 0; end function create(); begin sinit(); end end type TByteDataOP=class() //位操作类 {** @explan(说明) 位操作封装 **} {** @example(范例:byte数组转整数) oa := new TByteDataOP(); echo tostn(oa.bytesasint(array(1,1,1,1))); **} {** @example(范例:整数转byte数组) oa := new TByteDataOP(); echo tostn(oa.intasbytes(235); **} class function BytesAsInt(a); begin {** @explan(说明) 四个byte转换为integer %% @param(a)(array) 正式表示的四字节 %% @return(integer) 组装好的整数 %% **} uu := a[0]; ul := a[1]; lu := a[2]; ll := a[3]; l := makelong(ll,lu,8); u := makelong(ul,uu,8); return makelong(l,u); end class function IntAsBytes(v); begin {** @explan(说明) 整数转换为byte 数组(整数数组模拟) %% @param(v)(integer) %% @return(array) 模拟的byte数组 %% **} lowuperdword(v,l,u); lowuperdword(l,ll,lu); lowuperdword(u,ul,uu); return array(uu,ul,lu,ll); end class function ShortsToInt(a); begin {** @explan(说明) 两个short转换为一个int %% @param(a)(array) 两个元素的数组 %% @return(integer) 整数 %% **} l := a[1]; u := a[0]; return makelong(l,u); end class function IntToShorts(v); begin {** @explan(说明) 整数转换为两个short 数组(整数数组模拟) %% @param(v)(integer) %% @return(array) 模拟的short数组 %% **} lowuperdword(v,l,u); return array(l,u); end class function StrAsBytes(s); begin {** @explan(说明) 字符串转换为byte数组 %% @param(s)(string) 字符串 %% @return(array) 模拟的byte数组 %% **} r := array(); for i := 0 to length(s) do r[i]:= ord(s[i]); return r; end class function BytesAsStr(b); begin {** @explan(说明) byte数组转字符串 %% @param(b)(array) byte数组 %% @return(string) 字符串 **} r := ""; for i := 0 to length(b)-1 do r += chr(b[i]); return r; end end //**************************数组链表类****************************************** type tarray1dlk=class //从0开始 private _len; FCompareValue; protected _data; //数据 public {** @explan(说明) 一维链表类 %% @param(_len)(integer) 长度 %% @param(_data)(array) 数据 %% @param(CompareValue)(fpointer) 回调函数 function(v1,v2)begin return v1 = v2 ; end %% **} function setdata(data); begin {** @explan(说明) 一次性设置数据 %% @param(data)(array) 数据 %% **} _data := data; _len := length(data); end function clean(); begin {** @explan(说明) 清空 %% **} _data := array(); _len := 0; end function create(); //构造 begin {** @explan(说明) 构造 %% **} _data := array(); _len := 0; end function CallCompare(v1,v2,f); begin if datatype(f)=7 then return call(f,v1,v2); if datatype(FCompareValue)=7 then return call(FCompareValue,v1,v2); return v1=v2; end function append(v) //追加 begin {** @explan(说明) 追加 %% @param(v)() tsl数据 %% **} _data[_len++]:= v; end; function geti(i); //获取 begin {** @explan(说明) 获得 %% @param(i)(integer) id %% **} return _data[i]; end function seti(i,v); //设置值 begin {** @explan(说明) 设置值 %% @param(i)(integer) id %% @param(v)() tsl数据 %% **} if i >= 0 and i<_len then begin _data[i]:= v; end end function deli(i); //删除 begin {** @explan(说明) 删除 %% @param(i)(integer) id %% **} //len := length(_data)-1; if i<0 or i >= _len then return-1; _len -= 1; return deleteindex(_data,i,1); end function delis(i); begin {** @explan(说明) 批量删除 %% @param(i)(array) 删除的id %% **} dels := getdels(i); for ii,v in dels do deli(v); end function getdels(i); //删除多行 begin {** @ignore (忽略) %% @explan(说明) 批量删除 %% @param(i)(array) 删除的id %% **} ii := sselect thisrow from(i union2 array())where(thisrow >= 0 and thisrow<_len)order by thisrow end; dels := array(); ix := 0; for iv in ii do begin dels[iv]:= ii[iv]-ix; ix++; end return dels; end function insertbefor(v,i); //之前插入 begin {** @explan(说明) 在i之前插入 %% @param(v)() 插入数据 %% @param(i)(integer) id %% **} if not ifnumber(i)then return; if i >= _len then return append(v); else if i <= 0 then begin _data := array(v)union _data; end else begin _data := _data[0:(i-1)]union array(v)union _data[i:]; end _len++; end function insertafter(v,i); //之后插入 begin {** @explan(说明) 在i之后插入 %% @param(v)() 插入数据 %% @param(i)(integer) id %% **} if not ifnumber(i)then return; if i >= _len then return append(v); else if i<0 then begin _data := array(v)union _data; end else begin _data := _data[0:i]union array(v)union _data[i+1:]; end _len++; end function findvid(v1,func,lx); //查找序号,func通过送入的比较函数 begin {** @explan(说明) 查找序号和v1 匹配的id %% @param(v1)(any) tsl数据 %% @param(lx)(bool) 逆序查找 %% @param(func)(fpointer) 比较函数 第一个参数为 数组中对象,第二个参数为输入判断条件 %% **} ret :=-1; if lx then begin for i := length(_data)downto 0 do begin if CallCompare(_data[i],v1,func)then return i; end return ret; end for i,v in _data do begin if CallCompare(v,v1,func)then begin return i; end end return ret; end function getprev(v1); //获得上一个 begin {** @explan(说明) 获得上一个 匹配的id %% @param(v1)() tsl数据 %% **} if _len<2 then return nil; id :=-1; for i,v in _data do begin if CallCompare(v,v1)then begin id := i; break; end end return _data[id-1]; end function getnext(v1); //获得下一个 begin {** @explan(说明) 获得下一个 匹配的id %% @param(v1)() tsl数据 %% **} if _len<2 then return nil; id := _len; for i,v in _data do begin if CallCompare(v,v1)then begin id := i; break; end end return _data[id+1]; end function ergodic(f); //循环处理 begin {** @explan(说明) 循环所有数据 %% @param(f)(fpointer) 处理函数 function(id,v) begin end %% **} if(datatype(f)<> 7)then return nil; for i,v in _data do begin ret := call(f,i,v); //## f(i,v); if ret=-1 then break; end return 1; end function data(); //数组数据 begin {** @explan(说明) 返回所有数据 %% **} return _data; end function replace(i,v) //替换 begin {** @explan(说明) 替换 %% @param(i)(integer) 序号 %% @param(v)() tsl数据 %% **} if i >= 0 and i<_len then begin ret := _data[i]; _data[i]:= v; return ret; end else return nil; end function len(); //大小 begin {** @explan(说明) 长度 %% **} //return length(_data); return _len; end function setorder(i,j); begin {** @explan(说明) 设置元素位置 %% @param(i)(integer)原始位置 %% @param(j)(integer) 移动后的位置 **} if j>_len-1 then j := _len-1; if j<0 then j := 0; if i=j or(i<0 and i>_len)then exit; sl := createserial(i,j); for ii := 0 to length(sl)-2 do begin SwapNoCheck(sl[ii],sl[ii+1]); end end function swap(i,j); //交换 begin {** @explan(说明) 交换 %% @param(i)(integer) 序号 %% @param(j)(integer) 序号 %% **} if ifnumber(i)and ifnumber(j)and i <> j and i >= 0 and j >= 0 and i<_len and j<_len then begin SwapNoCheck(i,j); //vi := _data[i]; //_data[i]:=_data[j]; //_data[j] := vi; end end property CompareValue read FCompareValue write FCompareValue; private function SwapNoCheck(i,j); begin vi := _data[i]; _data[i]:= _data[j]; _data[j]:= vi; end function createserial(i,j); begin if j>i then return i -> j; r := array(); kk := 0; for ii := i downto j do r[kk++]:= ii; return r; end function moveto(i,j); //将i移动到j前面 begin {** @ignore 忽略%% @explan(说明) 将i移动到j前面 %% @param(i)(integer) 序号 %% @param(j)(integer) 序号 %% **} if not(ifnumber(i)and i >= 0 and i<_len)then return-1; if ifnil(j)then j := 0; if i=j then return-1; vi := geti(i); insertbefor(vi,j); if i>j then begin deli(i+1); end else begin deli(i); end end end type tstrindexarray = class {** @explan(数组类型) 忽略字符串下标的大小写%% **} function create(); begin FData := array(); FRows := array(); end function DeleteIndex(idx); begin {** @explan(说明) 删除指定下标 %% **} if ifnil(idx)or ifobj(idx)then return 0; if ifstring(idx)then begin lidx := lowercase(idx); ::deleteindex(FData,lidx,0); return ::deleteindex(FRows,lidx,0); end ::deleteindex(FData,idx,0); return ::deleteindex(FRows,idx,0); end function Operator[1](index,value); begin if ifstring(index)then begin li := lowercase(index); end else li := index; if ifnone(value)then begin r := FData[li]; if r then return r; r := new tstrindexarray(); FData[li]:= r; FRows[li]:= index; return r; end FRows[li]:= index; if ifarray(value)and value then begin r := new tstrindexarray(); FData[li]:= r; for i,v in value do begin r[i]:= v; end return; end FData[li]:= value; end function Operator[](index); begin if ifstring(index)then r := FData[lowercase(index)]; else r := FData[index]; //if ifnil(r) then return NeW tstrindexarray(); return r; end function Size(); begin {** @explan(说明) 获得长度 %% **} return Length(FData); end function toarray(n); begin {** @explan(说明) 获得tsl array %% @param(n)(bool) false 返回小写下标,true 返回原始下标 %% **} r := array(); for i,v in FData do begin if v is class(tstrindexarray)then begin r[n?i:FRows[i]]:= v.toarray(n); end else r[n?i:FRows[i]]:= v; end return r; end function IndexNames(); begin {** @explan(说明) 获得 所有下标 %% **} return FRows; end function HaveIndex(); begin {** @explan(说明) 判断是否有某个下标 %% **} o := self(true); for i := 1 to Paramcount do begin if not(o is class(tstrindexarray))then return false; id := params[i]; if ifnil(o.TrueIndex(id))then return false; o := o[id]; end return true; end function TrueIndex(n); begin {** @explan(说明) 获得对应下标 %% **} if ifstring(n)then idx := lowercase(n); else idx := n; return FRows[idx]; end property Data write SetData; function destroy(); begin FData := nil; FRows := nil; end private function SetData(d); begin if not ifarray(d)then return false; FRows := array(); FData := array(); si := self(true); for i,v in d do begin si[i]:= v; end return true; end FData; FRows; end type tnumindexarray = Class {** @explan(说明) 数字下标数组对象 %% **} private FData; public function Create();virtual; begin {** @explan(说明) 构造函数 %% **} FData := array(); end function Operator[1](idx,v); begin {** @explan(说明)通过下标设置元素 %% **} return SetValueByIndex(idx,v); end function Operator[](idx); begin {** @explan(说明) 通过下标获取元素 %% **} return GetValueByIndex(idx); end function length(); begin {** @explan(说明) 获得数据长度 %% @return(integer) 长度 %% **} return length(FData); end function Push({value1,value2,....}); begin {** @explan(说明) 在末尾追加元素,参数个数不定 %% **} r := length(FData); r1 := r; for i := 0 to ParamCount-1 do begin FData[r]:= Params[i+1]; r++; end if r1 <> r then LengthChanged(r1-r); return r; end function Pop(); begin {** @explan(说明) 弹出末尾的元素 %% **} if FData then begin id := length(FData)-1; r := FData[id]; deleteindex(FData,id); LengthChanged(-1); return r; end return nil; end function IndexOf(v); begin for i,vi in FData do begin if vi=v then return i; end return-1; end function LastIndexOf(v); begin for i := length(FData)-1 downto 0 do begin if v=FData[i]then return i; end return-1; end function GetValueByIndex(idx);virtual; begin return FData[idx]; end function SetValueByIndex(idx,v);virtual; begin len := length(FData); if idx<0 then return nil; if idx <= len then begin FData[idx]:= v; end else begin for i := len to idx do FData[i]:= nil; FData[idx]:= v; return v; end end function splice({startid,sellength,value1,valfue2,....}); begin {** @explan(说明) 替换元素,第一个参数为开始位置,第二个为替换的个数,以后的参数为用来替换的值,返回被替换的值%% **} p := params; st := p[0]; sl := p[1]; sl := ifnil(sl)?inf:sl; sl := sl<0?0:sl; len := length(FData); st := st<0?0:st; st := st >= len?(len):st; et := st+sl; et := et >= len?(len):et; r := array(); idx := 0; for i := st to et-1 do begin r[idx++]:= FData[i]; end r1 := FData[0:st-1]; r2 := FData[et:len-1]; FData := r1 union p[2:]union r2; if len <> length(FData)then LengthChanged(length(FData)-len); return r; end function shift(); begin {** @explan(说明) 弹出头部元素 %% **} r := nil; len := length(FData); if len>0 then begin deleteindex(FData,0); LengthChanged(-1); end return len<1?(len):(len-1); end function unshift({value1,value2,....}); begin {** @explan(说明) 在数据头部加入元素,个数待定 %% **} p := Params; if p then begin FData := p union FData; LengthChanged(1); end return length(FData); end function swap(i,j); begin {** @explan(说明) 交换下标中的值 %% **} if i=j then return false; len := length(FData); if i >= 0 and i= 0 and j