unit mm_adr_name; {$mode ObjFPC}{$H+} interface uses Windows, Classes, SysUtils, g23tree, sys_types; { name node: [ offset 12..39:28 size 12..39:28 name[32] ] } type TName=array[0..31] of AnsiChar; TNameAdrNode=packed object private Function GetOffset:Pointer; Procedure SetOffset(q:Pointer); Function GetSize:QWORD; Procedure SetSize(q:QWORD); public F:bitpacked record Offset:DWORD; Size :DWORD; end; name:TName; property Offset:Pointer read GetOffset write SetOffset; property Size:QWORD read GetSize write SetSize; Function cmp_merge(const n:TNameAdrNode):Boolean; end; type TNamedAdrAllcCompare=object function c(const a,b:TNameAdrNode):Integer; static; end; TNamedManager=class private type TAllcPoolNodeSet=specialize T23treeSet; var Flo,Fhi:Pointer; FMaxSize:QWORD; FAllcSet:TAllcPoolNodeSet; public property lo:Pointer read Flo; property hi:Pointer read Fhi; Constructor Create(_lo,_hi:QWORD); private procedure _Insert(const key:TNameAdrNode); Function _FetchNode_m(mode:Byte;cmp:Pointer;var R:TNameAdrNode):Boolean; procedure _Merge(key:TNameAdrNode); procedure _Devide(Offset:Pointer;Size:QWORD;var key:TNameAdrNode); public Function Mname(Offset:Pointer;Size:QWORD;pname:PChar):Integer; Function Query(Offset:Pointer;pname:PChar):Integer; procedure Print; end; implementation const EINVAL=22; // function TNamedAdrAllcCompare.c(const a,b:TNameAdrNode):Integer; begin //1 FOffset Result:=Integer(a.F.Offset>b.F.Offset)-Integer(a.F.Offsetb) then Result:=a else Result:=b; end; // Function TNameAdrNode.GetOffset:Pointer; begin Result:=Pointer(QWORD(F.Offset) shl 12); end; Procedure TNameAdrNode.SetOffset(q:Pointer); begin F.Offset:=DWORD(QWORD(q) shr 12); Assert(GetOffset=q); end; Function TNameAdrNode.GetSize:QWORD; begin Result:=QWORD(F.Size) shl 12; end; Procedure TNameAdrNode.SetSize(q:QWORD); begin F.Size:=DWORD(q shr 12); Assert(GetSize=q); end; Function TNameAdrNode.cmp_merge(const n:TNameAdrNode):Boolean; begin Result:=False; if (CompareChar0(name,n.name,SizeOf(TName))<>0) then Exit; Result:=True; end; /// Constructor TNamedManager.Create(_lo,_hi:QWORD); var key:TNameAdrNode; begin Assert(_lo<_hi); Flo:=Pointer(_lo); Fhi:=Pointer(_hi); FMaxSize:=(_hi-_lo+1); key:=Default(TNameAdrNode); key.Offset:=Pointer(_lo); key.Size :=FMaxSize; _Insert(key); end; procedure TNamedManager._Insert(const key:TNameAdrNode); begin Assert(key.Size<>0); FAllcSet.Insert(key); end; const M_LE=0; M_BE=1; C_UP=2; C_DW=4; C_LE=6; C_BE=8; Function TNamedManager._FetchNode_m(mode:Byte;cmp:Pointer;var R:TNameAdrNode):Boolean; var It:TAllcPoolNodeSet.Iterator; key,rkey:TNameAdrNode; begin Result:=false; key:=R; Case (mode and 1) of M_LE:It:=FAllcSet.find_le(key); M_BE:It:=FAllcSet.find_be(key); else Exit; end; if (It.Item=nil) then Exit; rkey:=It.Item^; Case (mode and (not 1)) of C_UP: begin if not rkey.cmp_merge(key) then Exit; if ((rkey.Offset+rkey.Size)<>cmp) then Exit; end; C_DW: begin if not rkey.cmp_merge(key) then Exit; if (rkey.Offset <>cmp ) then Exit; end; C_LE:if ((rkey.Offset+rkey.Size)<=cmp) then Exit; C_BE:if (rkey.Offset>=cmp) then Exit; else Exit; end; R:=rkey; FAllcSet.erase(It); Result:=True; end; // procedure TNamedManager._Merge(key:TNameAdrNode); var rkey:TNameAdrNode; begin //prev union repeat rkey:=key; rkey.F.Offset:=rkey.F.Offset-1; //hack if not _FetchNode_m(M_LE or C_UP,key.Offset,rkey) then Break; key.F.Size :=key.F.Size+(key.F.Offset-rkey.F.Offset); //hack key.F.Offset:=rkey.F.Offset; //hack until false; //next union repeat rkey:=key; rkey.F.Offset:=rkey.F.Offset+rkey.F.Size; //hack if not _FetchNode_m(M_BE or C_DW,(key.Offset+key.Size),rkey) then Break; key.F.Size :=key.F.Size+rkey.F.Size; //hack until false; _Insert(key); end; procedure TNamedManager._Devide(Offset:Pointer;Size:QWORD;var key:TNameAdrNode); var FOffset:Pointer; FSize:QWORD; FEndN,FEndO:Pointer; begin FOffset:=key.Offset; FSize :=key.Size; FEndN:=Offset +Size; FEndO:=FOffset+FSize; if (Offset>FOffset) then //prev save begin key.Size:=Offset-FOffset; _Merge(key); end; if (FEndO>FEndN) then //next save begin key.Offset:=FEndN; key.Size :=FEndO-FEndN; _Merge(key); end else if (FEndO<>FEndN) then //tunc size begin Size:=FEndO-Offset; end; //new save key.Offset :=Offset; key.Size :=Size; end; Function TNamedManager.Mname(Offset:Pointer;Size:QWORD;pname:PChar):Integer; var key:TNameAdrNode; FEndN,FEndO:Pointer; FSize:QWORD; name:TName; function _fetch:Boolean; begin Result:=False; FEndN:=Offset+Size; if _FetchNode_m(M_LE or C_LE,Offset,key) then begin FEndO:=key.Offset+key.Size; _Devide(Offset,Size,key); Result:=True; end else if _FetchNode_m(M_BE or C_BE,FEndN,key) then begin FEndO:=key.Offset+key.Size; _Devide(key.Offset,FEndN-key.Offset,key); Result:=True; end; end; function _map:Boolean; begin Result:=False; Assert(key.Size<>0); //new save key.name:=name; _Merge(key); if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -Min(FSize,Size); end; begin Result:=0; if (Size=0) or (Size>FMaxSize) then Exit(EINVAL); if (OffsetFhi) then Exit(EINVAL); FEndO:=AlignDw(Offset,PHYSICAL_PAGE_SIZE); Size:=Size+(Offset-FEndO); Offset:=FEndO; Size:=AlignUp(Size,PHYSICAL_PAGE_SIZE); name:=Default(TName); if (pname<>nil) then begin MoveChar0(pname^,name,SizeOf(TName)); end; repeat key:=Default(TNameAdrNode); key.Offset:=Offset; if _fetch then begin if _map then Break; end else begin Result:=EINVAL; Break; end; until false; end; Function TNamedManager.Query(Offset:Pointer;pname:PChar):Integer; var It:TAllcPoolNodeSet.Iterator; key:TNameAdrNode; begin Result:=0; if (pname=nil) then Exit(EINVAL); Offset:=AlignDw(Offset,PHYSICAL_PAGE_SIZE); key:=Default(TNameAdrNode); key.Offset:=Offset; It:=FAllcSet.find_le(key); if (It.Item=nil) then Exit(EINVAL); key:=It.Item^; if (Offset>=(key.Size+key.Offset)) then Exit(EINVAL); MoveChar0(key.name,pname^,SizeOf(TName)); end; procedure TNamedManager.Print; var key:TNameAdrNode; It:TAllcPoolNodeSet.Iterator; begin It:=FAllcSet.cbegin; While (It.Item<>nil) do begin key:=It.Item^; Writeln(HexStr(QWORD(key.Offset),11),'..', HexStr(QWORD(key.Offset+key.Size),11),':', HexStr(key.Size,11),'#', Pchar(@key.name)); It.Next; end; end; initialization end.