- Only standard objects are supported, ComObject, RegExMatchObject, FileObject, Func and DynaCall (AutoHotkey_H only) objects are not supported.
- Struct (AutoHotkey_H only) object can be dumped but ObjLoad will restore a normal object instead of Struct object.
- When value is of type string or raw data, ObjDump will dump only the string by default and always for keys, so StrPut(key)*(A_IsUnicode?2:1) is used. Additional parameter DumpBuffer can be used to force dumping obj.GetCapacity(value) instead of StrPut(value)*(A_IsUnicode?2:1) for values.
- Numbers consume only required bytes using NumSize/NumType.
Dump object to variable/memory:size := ObjDump(Object,Variable,DumpBuffer)Load object from variable/memory:Obj := ObjLoad(Address)Dump object to file:size := ObjDump(FilePath,Object,DumpBuffer)Load object from file:Obj := ObjLoad(FilePath)
AutoHotkey v1
Code: Select all
ObjDump(obj,ByRef var:="",mode:=0){
If IsObject(var){ ; FileAppend mode
If FileExist(obj){
FileDelete,%obj%
If ErrorLevel
return
}
f:=FileOpen(obj,"rw-rwd","CP0"),VarSetCapacity(v,sz:=RawObjectSize(var,mode)+8,0)
,RawObject(var,NumPut(sz-8,0+(ptr:=&v),"Int64"),mode),count:=sz//65536
Loop % count
f.RawWrite(ptr+0,65536),ptr+=65536
return sz,f.RawWrite(ptr+0,Mod(sz,65536)),f.Close()
} else if !IsByRef(var)
return RawObjectSize(obj,mode)+8
else return sz,VarSetCapacity(var,sz:=RawObjectSize(obj,mode)+8,0),RawObject(obj,NumPut(sz-8,&var,"Int64"),mode)
}
RawObject(obj,addr,buf:=0,objects:=0){
; Type.Enum: Char.1 UChar.2 Short.3 UShort.4 Int.5 UInt.6 Int64.7 UInt64.8 Double.9 String.10 Object.11
; Negative for keys and positive for values
if !objects
objects:={(""):0,(obj):0}
else objects[obj]:=(++objects[""])
for k,v in obj
{ ; 9 = Int64 for size and Char for type
If !(kIsString:=0)&&IsObject(k){
If objects.HasKey(k)
NumPut(-12,addr+0,"Char"),NumPut(objects[k],addr+1,"Int64"),addr+=9
else NumPut(-11,addr+0,"Char"),NumPut(sz:=RawObjectSize(k,buf),addr+1,"Int64"),RawObject(k,addr+9,buf,objects),addr+=sz+9
}else if (k+0=""||k ""!=k+0||k~="\s")
kIsString:=true,NumPut(-10,addr+0,"Char"),NumPut(sz:=StrPut(k,addr+9)*2,addr+1,"Int64"),addr+=sz+9
else NumPut( InStr(k,".")?-9:k>4294967295?-8:k>65535?-6:k>255?-4:k>-1?-2:k>-129?-1:k>-32769?-3:k>-2147483649?-5:-7,addr+0,"Char")
,NumPut(k,addr+1,InStr(k,".")?"Double":k>4294967295?"UInt64":k>65535?"UInt":k>255?"UShort":k>-1?"UChar":k>-129?"Char":k>-32769?"Short":k>-2147483649?"Int":"Int64")
,addr+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
If IsObject(v){
if objects.HasKey(v)
NumPut( 12,addr+0,"Char"),NumPut(objects[v],addr+1,"Int64"),addr+=9
else NumPut( 11,addr+0,"Char"),NumPut(sz:=RawObjectSize(v,buf),addr+1,"Int64"),RawObject(v,addr+9,buf,objects),addr+=sz+9
}else if (v+0=""||v ""!=v+0||v~="\s")
NumPut( 10,addr+0,"Char"),NumPut(sz:=buf?obj.GetCapacity(kIsString?"" k:k):StrPut(v)*2,addr+1,"Int64"),DllCall("RtlMoveMemory","PTR",addr+9,"PTR",buf?obj.GetAddress(kIsString?"" k:k):&v,"PTR",sz),addr+=sz+9
else NumPut(InStr(v,".")?9:v>4294967295?8:v>65535?6:v>255?4:v>-1?2:v>-129?1:v>-32769?3:v>-2147483649?5:7,addr+0,"Char")
,NumPut(v,addr+1,InStr(v,".")?"Double":v>4294967295?"UInt64":v>65535?"UInt":v>255?"UShort":v>-1?"UChar":v>-129?"Char":v>-32769?"Short":v>-2147483649?"Int":"Int64")
,addr+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
}
}
RawObjectSize(obj,buf:=0,objects:=0){
if !objects
objects:={(obj):1}
else if !objects.HasKey(obj)
objects[obj]:=1
sz:=0
for k,v in obj
{
If !(kIsString:=0)&&IsObject(k)
sz+=objects.HasKey(k)?9:RawObjectSize(k,buf,objects)+9
else if (k+0=""||k ""!=k+0||k~="\s")
kIsString:=true,sz+=StrPut(k)*2+9
else sz+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
If IsObject(v)
sz+=objects.HasKey(v)?9:RawObjectSize(v,buf,objects)+9
else if (v+0=""||v ""!=v+0||v~="\s")
sz+=(buf?obj.GetCapacity(kIsString?"" k:k):StrPut(v)*2)+9
else sz+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
}
return sz
}
Code: Select all
ObjLoad(addr,objects:=0){
If (addr+0=""){ ; FileRead Mode
If !FileExist(addr)
return
FileGetSize,sz,%addr%
FileRead,v,*c %addr%
If ErrorLevel||!sz
return
addr:=&v
}
obj:=[],end:=addr+8+(sz:=NumGet(addr+0,"Int64")),addr+=8
if !objects
objects:={0:obj}
else objects.Push(obj)
While addr<end{ ; 9 = Int64 for size and Char for type
If !(kIsString:=0)&&NumGet(addr+0,"Char")=-12
k:=objects[NumGet(addr+1,"Int64")],addr+=9
else if NumGet(addr+0,"Char")=-11
k:=ObjLoad(addr+1,objects),addr+=9+NumGet(addr+1,"Int64")
else if NumGet(addr+0,"Char")=-10
kIsString:=true,sz:=NumGet(addr+1,"Int64"),k:=StrGet(addr+9),addr+=sz+9
else k:=NumGet(addr+1,SubStr("Char UChar Short UShortInt UInt Int64 UInt64Double",(sz:=-NumGet(addr+0,"Char"))*6-5,6)),addr+=SubStr("112244888",sz,1)+1
If NumGet(addr+0,"Char")= 12
obj[kIsString?"" k:k]:=objects[NumGet(addr+1,"Int64")],addr+=9
else if NumGet(addr+0,"Char")= 11
obj[kIsString?"" k:k]:=ObjLoad(addr+1,objects),addr+=9+NumGet(addr+1,"Int64")
else if NumGet(addr+0,"Char")= 10
obj[kIsString?"" k:k]:=StrGet(addr+9),obj.SetCapacity(kIsString?"" k:k,sz:=NumGet(addr+1,"Int64")),DllCall("RtlMoveMemory","PTR",obj.GetAddress(kIsString?"" k:k),"PTR",addr+9,"PTR",sz),addr+=sz+9
else obj[kIsString?"" k:k]:=NumGet(addr+1,SubStr("Char UChar Short UShortInt UInt Int64 UInt64Double",(sz:=NumGet(addr+0,"Char"))*6-5,6)),addr+=SubStr("112244888",sz,1)+1
}
return obj
}
AutoHotkey v2
UPDATE:
Code: Select all
ObjDump(obj,ByRef var:="",mode:=0){
If IsObject(var){ ; FileAppend mode
If FileExist(obj)&&!FileDelete(obj)
return
f:=FileOpen(obj,"rw-rwd","CP0"),VarSetCapacity(v,sz:=RawObjectSize(var,mode)+8,0)
,RawObject(var,NumPut(sz-8,ptr:=&v,"Int64"),mode),count:=sz//65536
Loop count
f.RawWrite(ptr+0,65536),ptr+=65536
return (f.RawWrite(ptr+0,Mod(sz,65536)),f.Close(),sz)
} else if !IsByRef(var)
return RawObjectSize(obj,mode)+8
else return (VarSetCapacity(var,sz:=RawObjectSize(obj,mode)+8,0),RawObject(obj,NumPut(sz-8,&var,"Int64"),mode),sz)
}
RawObject(obj,addr,buf:=0,objects:=0){
; Type.Enum: Char.1 UChar.2 Short.3 UShort.4 Int.5 UInt.6 Int64.7 UInt64.8 Double.9 String.10 Object.11
; Negative for keys and positive for values
if !objects
objects:={(""):0,(obj):0}
else objects[obj]:=(++objects[""])
for k,v in obj
{ ; 9 = Int64 for size and Char for type
If IsObject(k){
If objects.HasKey(k)
NumPut(-12,addr,"Char"),NumPut(objects[k],addr+1,"Int64"),addr+=9
else NumPut(-11,addr,"Char"),NumPut(sz:=RawObjectSize(k,buf),addr+1,"Int64"),RawObject(k,addr+9,buf,objects),addr+=sz+9
}else if Type(k)="String"
NumPut(-10,addr,"Char"),NumPut(sz:=StrPut(k,addr+9)*2,addr+1,"Int64"),addr+=sz+9
else NumPut( InStr(k,".")?-9:k>4294967295?-8:k>65535?-6:k>255?-4:k>-1?-2:k>-129?-1:k>-32769?-3:k>-2147483649?-5:-7,addr,"Char")
,NumPut(k,addr+1,InStr(k,".")?"Double":k>4294967295?"UInt64":k>65535?"UInt":k>255?"UShort":k>-1?"UChar":k>-129?"Char":k>-32769?"Short":k>-2147483649?"Int":"Int64")
,addr+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
If IsObject(v){
if objects.HasKey(v)
NumPut( 12,addr,"Char"),NumPut(objects[v],addr+1,"Int64"),addr+=9
else NumPut( 11,addr,"Char"),NumPut(sz:=RawObjectSize(v,buf),addr+1,"Int64"),RawObject(v,addr+9,buf,objects),addr+=sz+9
}else if Type(v)="String"
NumPut( 10,addr,"Char"),NumPut(sz:=buf?obj.GetCapacity(k):StrPut(v)*2,addr+1,"Int64"),DllCall("RtlMoveMemory","PTR",addr+9,"PTR",buf?obj.GetAddress(k):&v,"PTR",sz),addr+=sz+9
else NumPut(InStr(v,".")?9:v>4294967295?8:v>65535?6:v>255?4:v>-1?2:v>-129?1:v>-32769?3:v>-2147483649?5:7,addr,"Char")
,NumPut(v,addr+1,InStr(v,".")?"Double":v>4294967295?"UInt64":v>65535?"UInt":v>255?"UShort":v>-1?"UChar":v>-129?"Char":v>-32769?"Short":v>-2147483649?"Int":"Int64")
,addr+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
}
}
RawObjectSize(obj,buf:=0,objects:=0){
sz:=0
if !objects
objects:={(obj):1}
else if !objects.HasKey(obj)
objects[obj]:=1
for k,v in obj
{
If IsObject(k)
sz+=objects.HasKey(k)?9:RawObjectSize(k,buf,objects)+9
else if Type(k)="String"
sz+=StrPut(k)*2+9
else sz+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
If IsObject(v)
sz+=objects.HasKey(v)?9:RawObjectSize(v,buf,objects)+9
else if Type(v)="String"
sz+=(buf?obj.GetCapacity(k):StrPut(v)*2)+9
else sz+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
}
return sz
}
Code: Select all
ObjLoad(addr,objects:=0){
If addr+0=""{ ; FileRead Mode
If !FileExist(addr)
return
else v:=FileRead(addr,"RAW")
If ErrorLevel||!FileGetSize(addr)
return
else addr:=&v
}
obj:=[],end:=addr+8+(sz:=NumGet(addr,"Int64")),addr+=8
if !objects
objects:={0:obj}
else objects.Push(obj)
While addr<end{ ; 9 = Int64 for size and Char for type
If NumGet(addr,"Char")=-12
k:=objects[NumGet(addr+1,"Int64")],addr+=9
else if NumGet(addr,"Char")=-11
k:=ObjLoad(addr+1,objects),addr+=9+NumGet(addr+1,"Int64")
else if NumGet(addr,"Char")=-10
sz:=NumGet(addr+1,"Int64"),k:=StrGet(addr+9),addr+=sz+9
else k:=NumGet(addr+1,SubStr("Char UChar Short UShortInt UInt Int64 UInt64Double",(sz:=-NumGet(addr,"Char"))*6-5,6)),addr+=SubStr("112244888",sz,1)+1
If NumGet(addr,"Char")= 12
obj[k]:=objects[NumGet(addr+1,"Int64")],addr+=9
else if NumGet(addr,"Char")= 11
obj[k]:=ObjLoad(addr+1,objects),addr+=9+NumGet(addr+1,"Int64")
else if NumGet(addr,"Char")= 10
obj[k]:=StrGet(addr+9),obj.SetCapacity(k,sz:=NumGet(addr+1,"Int64")),DllCall("RtlMoveMemory","PTR",obj.GetAddress(k),"PTR",addr+9,"PTR",sz),addr+=sz+9
else obj[k]:=NumGet(addr+1,SubStr("Char UChar Short UShortInt UInt Int64 UInt64Double",(sz:=NumGet(addr,"Char"))*6-5,6)),addr+=SubStr("112244888",sz,1)+1
}
return obj
}
- *16.11.2017
- Fix to handle properly keys and values containing numbers and spaces or tabs
- Update latest v2 syntax
*25.02.2016 - Fix ObjLoad bug.
- ObjDump and ObjLoad can now handle object reference to itself or another object within dumped object.
*02.11.2015 - Fix saving binary memory of key (use obj.GetAddress(k) instead of &v)
*20.08.2015 - Include size of dumped object for simplified use
Note wrote:New ObjLoad() function is not compatible to the old functions and cannot load a file dumped with old ObjDump function.
You can rename the old ObjLoad function to ObjLoad2 and run this with new ObjDump function: ObjDump(ObjLoad2(File),File) - 20.05.2014
- Implemented obj-64 -> file -> obj-32 and the other way round.
- Use only the required memory for numbers.
- Additional parameter DumpBuffer, when true obj.GetCapacity(key) is used else StrPut(value)*(A_IsUnicode?2:1)
- 18.05.2014
- Fixed writing large objects
Old_Versions
20.05.2014
AutoHotkey v2
First versions
AutoHotkey v1
AutoHotkey v2
AutoHotkey v1Dump object to variable/memory:size := ObjDump(Object,Variable,DumpBuffer)Load object from variable/memory:Obj := ObjLoad(Address,Size)Dump object to file:size := ObjDump(FilePath,Object,DumpBuffer)Load object from file:Obj := ObjLoad(FilePath)
Code: Select all
ObjDump(obj,ByRef var,mode:=0){
If IsObject(var){ ; FileAppend mode
If FileExist(obj){
FileDelete,%obj%
If ErrorLevel
return
}
f:=FileOpen(obj,"rw-rwd","CP0"),VarSetCapacity(v,sz:=RawObjectSize(var,mode),0)
,RawObject(var,&v,mode),count:=sz//65536,ptr:=&v
Loop % count
f.RawWrite(ptr+0,65536),ptr+=65536
return sz,f.RawWrite(ptr+0,Mod(sz,65536)),f.Close()
} else return sz,VarSetCapacity(var,sz:=RawObjectSize(obj,mode),0),RawObject(obj,&var,mode)
}
RawObject(obj,addr,buf:=0){
; Type.Enum: Char.1 UChar.2 Short.3 UShort.4 Int.5 UInt.6 Int64.7 UInt64.8 Double.9 String.10 Object.11
for k,v in obj
{ ; 9 = Int64 for size and Char for type
If IsObject(k)
NumPut(-11,addr+0,"Char"),NumPut(sz:=RawObjectSize(k,buf),addr+1,"UInt64"),RawObject(k,addr+9),addr+=sz+9
else if (k+0="")
NumPut(-10,addr+0,"Char"),NumPut(StrPut(k,addr+9)*(A_IsUnicode?2:1),addr+1,"UInt64"),addr+=NumGet(addr+1,"UInt64")+9
else NumPut( InStr(k,".")?-9:k>4294967295?-8:k>65535?-6:k>255?-4:k>-1?-2:k>-129?-1:k>-32769?-3:k>-2147483649?-5:-7,addr+0,"Char")
,NumPut(k,addr+1,InStr(k,".")?"Double":k>4294967295?"UInt64":k>65535?"UInt":k>255?"UShort":k>-1?"UChar":k>-129?"Char":k>-32769?"Short":k>-2147483649?"Int":"Int64")
,addr+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
If IsObject(v)
NumPut( 11,addr+0,"Char"),NumPut(sz:=RawObjectSize(v,buf),addr+1,"UInt64"),RawObject(v,addr+9),addr+=sz+9
else if (v+0="")
NumPut( 10,addr+0,"Char"),NumPut(sz:=buf?obj.GetCapacity(k):StrPut(v)*(A_IsUnicode?2:1),addr+1,"Int64"),DllCall("RtlMoveMemory","PTR",addr+9,"PTR",&v,"PTR",sz),addr+=sz+9
else NumPut( InStr(v,".")?9:v>4294967295?8:v>65535?6:v>255?4:v>-1?2:v>-129?1:v>-32769?3:v>-2147483649?5:7,addr+0,"Char")
,NumPut(v,addr+1,InStr(v,".")?"Double":v>4294967295?"UInt64":v>65535?"UInt":v>255?"UShort":v>-1?"UChar":v>-129?"Char":v>-32769?"Short":v>-2147483649?"Int":"Int64")
,addr+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
}
}
RawObjectSize(obj,buf:=0,sz:=0){
; 9 = Int64 for size and Char for type
for k,v in obj
{
If IsObject(k)
sz+=RawObjectSize(k,buf)+9
else if (k+0="")
sz+=StrPut(k)*(A_IsUnicode?2:1)+9
else sz+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
If IsObject(v)
sz+=RawObjectSize(v,buf)+9
else if (v+0="")
sz+=(buf?obj.GetCapacity(k):StrPut(v)*(A_IsUnicode?2:1))+9
else sz+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
}
return sz
}
Code: Select all
ObjLoad(addr,sz:=""){
; Arrays to retrieve type and size from number type
static type:=["Char","UChar","Short","UShort","Int","UInt","Int64","UInt64","Double"],num:=[1,1,2,2,4,4,8,8,8]
If (sz=""){ ; FileRead Mode
If !FileExist(addr)
return
FileGetSize,sz,%addr%
FileRead,v,*c %addr%
If ErrorLevel||!sz
return
addr:=&v
}
end:=addr+sz, obj:=[]
While % addr<end{ ; 9 = Int64 for size and Char for type
If NumGet(addr+0,"Char")=-11
k:=ObjLoad(addr+9,sz:=NumGet(addr+1,"UInt64")),addr+=sz+9
else if NumGet(addr+0,"Char")=-10
k:=StrGet(addr+9),addr+=NumGet(addr+1,"UInt64")+9
else k:=NumGet(addr+1,type[sz:=-1*NumGet(addr+0,"Char")]),addr+=num[sz]+1
If NumGet(addr+0,"Char")= 11
obj[k]:=ObjLoad(addr+9,sz:=NumGet(addr+1,"PTR")),addr+=sz+9
else if NumGet(addr+0,"Char")= 10
obj.SetCapacity(k,sz:=NumGet(addr+1,"UInt64")),DllCall("RtlMoveMemory","PTR",obj.GetAddress(k),"PTR",addr+9,"PTR",sz),addr+=sz+9
else obj[k]:=NumGet(addr+1,type[sz:=NumGet(addr+0,"Char")]),addr+=num[sz]+1
}
return obj
}
Code: Select all
ObjDump(obj,ByRef var,mode:=0){
If IsObject(var){ ; FileAppend mode
If FileExist(obj){
FileDelete,%obj%
If ErrorLevel
return
}
f:=FileOpen(obj,"rw-rwd","CP0"),VarSetCapacity(v,sz:=RawObjectSize(var,mode),0)
,RawObject(var,&v,mode),count:=sz//65536,ptr:=&v
Loop count
f.RawWrite(ptr+0,65536),ptr+=65536
return f.RawWrite(ptr+0,Mod(sz,65536)),f.Close(),sz
} else return VarSetCapacity(var,sz:=RawObjectSize(obj,mode),0),RawObject(obj,&var,mode),sz
}
RawObject(obj,addr,buf:=0){
; Type.Enum: Char.1 UChar.2 Short.3 UShort.4 Int.5 UInt.6 Int64.7 UInt64.8 Double.9 String.10 Object.11
for k,v in obj
{ ; 9 = Int64 for size and Char for type
If IsObject(k),NumPut(-11,addr,"Char"),NumPut(sz:=RawObjectSize(k,buf),addr+1,"UInt64"),RawObject(k,addr+9),addr+=sz+9
else if Type(k)="String",NumPut(-10,addr,"Char"),NumPut(sz:=StrPut(k,addr+9)*2,addr+1,"UInt64"),addr+=sz+9
else NumPut( InStr(k,".")?-9:k>4294967295?-8:k>65535?-6:k>255?-4:k>-1?-2:k>-129?-1:k>-32769?-3:k>-2147483649?-5:-7,addr,"Char")
,NumPut(k,addr+1,InStr(k,".")?"Double":k>4294967295?"UInt64":k>65535?"UInt":k>255?"UShort":k>-1?"UChar":k>-129?"Char":k>-32769?"Short":k>-2147483649?"Int":"Int64")
,addr+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
If IsObject(v),NumPut( 11,addr,"Char"),NumPut(sz:=RawObjectSize(v,buf),addr+1,"UInt64"),RawObject(v,addr+9),addr+=sz+9
else if Type(v)="String",NumPut( 10,addr,"Char"),NumPut(sz:=buf?obj.GetCapacity(k):StrPut(v)*2,addr+1,"Int64"),DllCall("RtlMoveMemory","PTR",addr+9,"PTR",&v,"PTR",sz),addr+=sz+9
else NumPut( InStr(v,".")?9:v>4294967295?8:v>65535?6:v>255?4:v>-1?2:v>-129?1:v>-32769?3:v>-2147483649?5:7,addr,"Char")
,NumPut(v,addr+1,InStr(v,".")?"Double":v>4294967295?"UInt64":v>65535?"UInt":v>255?"UShort":v>-1?"UChar":v>-129?"Char":v>-32769?"Short":v>-2147483649?"Int":"Int64")
,addr+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
}
}
RawObjectSize(obj,buf:=0,sz:=0){
; 9 = Int64 for size and Char for type
for k,v in obj
{
If IsObject(k),sz+=RawObjectSize(k,buf)+9
else if Type(k)="String",sz+=StrPut(k)*2+9
else sz+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
If IsObject(v),sz+=RawObjectSize(v,buf)+9
else if Type(v)="String",sz+=(buf?obj.GetCapacity(k):StrPut(v)*2)+9
else sz+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
}
return sz
}
Code: Select all
ObjLoad(addr,sz:=""){
; Arrays to retrieve type and size from number type
static type:=["Char","UChar","Short","UShort","Int","UInt","Int64","UInt64","Double"],num:=[1,1,2,2,4,4,8,8,8]
If sz=""{ ; FileRead Mode
If !FileExist(addr)
return
FileGetSize,sz,%addr%
FileRead,v,*c %addr%
If ErrorLevel||!sz
return
addr:=&v
}
end:=addr+sz, obj:=[]
While addr<end{ ; 9 = Int64 for size and Char for type
If NumGet(addr,"Char")=-11,k:=ObjLoad(addr+9,sz:=NumGet(addr+1,"UInt64")),addr+=sz+9
else if NumGet(addr,"Char")=-10,k:=StrGet(addr+9),addr+=NumGet(addr+1,"UInt64")+9
else k:=NumGet(addr+1,type[sz:=-NumGet(addr,"Char")]),addr+=num[sz]+1
If NumGet(addr,"Char")= 11,obj[k]:=ObjLoad(addr+9,sz:=NumGet(addr+1,"PTR")),addr+=sz+9
else if NumGet(addr,"Char")= 10,obj.SetCapacity(k,sz:=NumGet(addr+1,"UInt64")),DllCall("RtlMoveMemory","PTR",obj.GetAddress(k),"PTR",addr+9,"PTR",sz),addr+=sz+9
else obj[k]:=NumGet(addr+1,type[sz:=NumGet(addr,"Char")]),addr+=num[sz]+1
}
return obj
}
AutoHotkey v1
Code: Select all
ObjDump(obj,ByRef var){
If IsObject(var){ ; FileAppend mode
If FileExist(obj){
FileDelete,%obj%
If ErrorLevel
return
}
f:=FileOpen(obj,"rw-rwd"),VarSetCapacity(v,sz:=RawObjectSize(var),0)
,RawObject(var,&v),count:=sz//65536,ptr:=&v
Loop count
f.RawWrite(ptr+0,65536),ptr+=65536
return sz,f.RawWrite(ptr+0,Mod(sz,65536)),f.Close()
} else return sz,VarSetCapacity(var,sz:=RawObjectSize(obj),0),RawObject(obj,&var)
}
RawObject(obj,addr){
orig:=addr
for k,v in obj
{
If IsObject(k)
NumPut(-4,addr+0,"Short"),NumPut(szo:=RawObjectSize(k),addr+2,"PTR"),addr+=A_PtrSize+2,RawObject(k,addr),addr+=szo
else if (k+0="")
NumPut(-1,addr+0,"Short"),NumPut(StrPut(k),addr+2,"PTR"),StrPut(k,addr+A_PtrSize+2),addr+=NumGet(addr+2,"PTR")*(A_IsUnicode?2:1)+A_PtrSize+2
else if (k+0!=""&&InStr(k,"."))
NumPut(-3,addr+0,"Short"),NumPut(k,addr+2,"Double"),addr+=8+2
else NumPut(-2,addr+0,"Short"),NumPut(k,addr+2,"Int64"),addr+=8+2
If IsObject(v)
NumPut( 4,addr+0,"Short"),NumPut(szo:=RawObjectSize(v),addr+2,"PTR"),addr+=A_PtrSize+2,RawObject(v,addr),addr+=szo
else if (v+0="")
NumPut( 1,addr+0,"Short"),NumPut(cap:=obj.GetCapacity(k),addr+2,"PTR"),DllCall("RtlMoveMemory","PTR",addr+A_PtrSize+2,"PTR",&v,"PTR",cap),addr+=cap+A_PtrSize+2
else if (v+0!=""&&InStr(v,"."))
NumPut( 3,addr+0,"Short"),NumPut(v,addr+2,"Double"),addr+=8+2
else NumPut( 2,addr+0,"Short"),NumPut(v,addr+2,"Int64"),addr+=8+2
}
}
RawObjectSize(obj,sz:=0){
for k,v in obj
{ ; key
If IsObject(k)
sz+=RawObjectSize(k)+A_PtrSize+2
else if (k+0="")
sz+=StrPut(k)*2+A_PtrSize+2
else sz+=8+2
; value
If IsObject(v)
sz+=RawObjectSize(v)+A_PtrSize+2
else if (v+0="")
sz+=obj.GetCapacity(k)+A_PtrSize+2
else sz+=8+2
}
return sz
}
Code: Select all
ObjLoad(addr,sz:=""){
If (sz=""){ ; FileRead Mode
If !FileExist(addr)
return
FileGetSize,sz,%addr%
FileRead,v,*c %addr%
If ErrorLevel||!sz
return
addr:=&v
}
end:=addr+sz, obj:=[]
While addr<end{
If (NumGet(addr+0,"Short")=-4)
k:=ObjLoad(addr+A_PtrSize+2,sz:=NumGet(addr+2,"PTR")),addr+=sz+2+A_PtrSize
else if (NumGet(addr+0,"Short")=-1)
k:=StrGet(addr+2+A_PtrSize),addr+=NumGet(addr+2,"PTR")*(A_IsUnicode?2:1)+A_PtrSize+2
else k:=NumGet(addr+2,NumGet(addr+0,"Short")=-3?"Double":"Int64"),addr+=8+2
If (NumGet(addr+0,"Short")= 4)
obj[k]:=ObjLoad(addr+A_PtrSize+2,sz:=NumGet(addr+2,"PTR")),addr+=sz+2+A_PtrSize
else if (NumGet(addr+0,"Short")= 1)
obj.SetCapacity(k,NumGet(addr+2,"PTR")),DllCall("RtlMoveMemory","PTR",obj.GetAddress(k),"PTR",addr+2+A_PtrSize,"PTR",NumGet(addr+2,"PTR")),addr+=NumGet(addr+2,"PTR")+A_PtrSize+2
else obj[k]:=NumGet(addr+2,NumGet(addr+0,"Short")=3?"Double":"Int64"),addr+=8+2
}
return obj
}
Code: Select all
ObjDump(obj,ByRef var){
If IsObject(var){ ; FileAppend mode
If FileExist(obj){
FileDelete,%obj%
If ErrorLevel
return
}
f:=FileOpen(obj,"rw-rwd"),VarSetCapacity(v,sz:=RawObjectSize(var),0)
,RawObject(var,&v),count:=sz//65536,ptr:=&v
Loop count
f.RawWrite(ptr+0,65536),ptr+=65536
return f.RawWrite(ptr+0,Mod(sz,65536)),f.Close(),sz
} else return VarSetCapacity(var,sz:=RawObjectSize(obj),0),RawObject(obj,&var),sz
}
RawObject(obj,addr){
for k,v in obj
{
If IsObject(k),NumPut(-4,addr,"Short"),NumPut(szo:=RawObjectSize(k),addr+2,"PTR"),addr+=A_PtrSize+2,RawObject(k,addr),addr+=szo
else if Type(k)="Float",NumPut(-3,addr,"Short"),NumPut(k,addr+2,"Double"),addr+=8+2
else if Type(k)="String",NumPut(-1,addr,"Short"),NumPut(StrPut(k),addr+2,"PTR"),StrPut(k,addr+A_PtrSize+2),addr+=NumGet(addr+2,"PTR")*2+A_PtrSize+2
else NumPut(-2,addr,"Short"),NumPut(k,addr+2,"Int64"),addr+=8+2
If IsObject(v),NumPut( 4,addr,"Short"),NumPut(szo:=RawObjectSize(v),addr+2,"PTR"),addr+=A_PtrSize+2,RawObject(v,addr),addr+=szo
else if Type(v)="Float",NumPut( 3,addr,"Short"),NumPut(v,addr+2,"Double"),addr+=8+2
else if Type(v)="String",NumPut( 1,addr,"Short"),NumPut(cap:=obj.GetCapacity(k),addr+2,"PTR"),DllCall("RtlMoveMemory","PTR",addr+A_PtrSize+2,"PTR",&v,"PTR",cap),addr+=cap+A_PtrSize+2
else NumPut( 2,addr,"Short"),NumPut(v,addr+2,"Int64"),addr+=8+2
}
}
RawObjectSize(obj,sz:=0){
for k,v in obj
{
If IsObject(k),sz:=RawObjectSize(k,zs)+A_PtrSize+2
else if Type(k)="String",sz+=StrPut(k)*2+A_PtrSize+2
else sz+=8+2
If IsObject(v),sz:=RawObjectSize(v,sz)+A_PtrSize+2
else if Type(v)="String",sz+=obj.GetCapacity(k)+A_PtrSize+2
else sz+=8+2
}
return sz
}
Code: Select all
ObjLoad(addr,sz:=""){
If sz=""{ ; FileRead Mode
If !FileExist(addr)
return
FileGetSize,sz,%addr%
FileRead,v,*c %addr%
If ErrorLevel||!sz
return
addr:=&v
}
end:=addr+sz, obj:=[]
While addr<end{
If NumGet(addr,"Short")=-4,k:=ObjLoad(addr+A_PtrSize+2,sz:=NumGet(addr+2,"PTR")),addr+=sz+2+A_PtrSize
else if NumGet(addr,"Short")=-1,k:=StrGet(addr+2+A_PtrSize),addr+=NumGet(addr+2,"PTR")*2+A_PtrSize+2
else k:=NumGet(addr+2,NumGet(addr,"Short")=-3?"Double":"Int64"),addr+=8+2
If NumGet(addr,"Short")= 4,obj[k]:=ObjLoad(addr+A_PtrSize+2,sz:=NumGet(addr+2,"PTR")),addr+=sz+2+A_PtrSize
else if NumGet(addr,"Short")= 1,obj.SetCapacity(k,NumGet(addr+2,"PTR")),DllCall("RtlMoveMemory","PTR",obj.GetAddress(k),"PTR",addr+2+A_PtrSize,"PTR",NumGet(addr+2,"PTR")),addr+=NumGet(addr+2,"PTR")+A_PtrSize+2
else obj[k]:=NumGet(addr+2,NumGet(addr,"Short")=3?"Double":"Int64"),addr+=8+2
}
return obj
}