I made some functions to make my own life easier, maybe it can help you too?

Could easily make some kind of hex editor with this.
Currently I have added:
memoryToHex.s(address,length,byteorder=#bigEndian)
hexToMemory(address,hex$,byteorder=#bigEndian)
hexToText.s(hex$)
hexToTextSanitized.s(hex$)
SendNetworkHex.l(connection,hex$)
getHexSize.l(hex$)
strToHex.s(string$)
longToHex.s(long,byteorder=#littleEndian)
wordToHex.s(word.w,byteorder=#littleEndian)
byteToHex.s(byte.b)
hexToLong(*long,hex$,byteorder=#littleEndian)
hexToWord(*word,hex$,byteorder=#littleEndian)
hexToByte(*byte,hex$)
EDIT: Now with byte order support (little and big endian).
Code: Select all
;Some commands to make working with hex easier
;Made by Joakim L. Christiansen a.k.a JLC
;Feel free to use! :)
EnableExplicit
Enumeration ;endians
;http://en.wikipedia.org/wiki/Endianness
;http://forums.purebasic.com/english/viewtopic.php?p=294231
#littleEndian ;right to left
#bigEndian ;left to right
EndEnumeration
Procedure.l getHexSize(hex$) ;no point to use if you got a brain
hex$ = RemoveString(hex$," ")
ProcedureReturn Len(hex$)/2
EndProcedure
Procedure.s memoryToHex(address,length,byteorder=#bigEndian) ;returns a string containing the hex representation of the memory area
Protected result$, i
If byteorder = #bigEndian
For i=0 To length-1
result$ + RSet(Hex(PeekB(address+i),#PB_Byte),2,"0")+" "
Next
ElseIf byteorder = #littleEndian
For i=length-1 To 0 Step -1
result$ + RSet(Hex(PeekB(Address+i),#PB_Byte),2,"0")+" "
Next
EndIf
ProcedureReturn RTrim(result$)
EndProcedure
Procedure hexToMemory(address,hex$,byteorder=#bigEndian) ;converts hex into data
Protected i, pos, len
hex$ = RemoveString(hex$," ")
len = Len(hex$)
If byteorder = #bigEndian
For i=1 To len Step 2
PokeB(address+pos,Val("$"+Mid(hex$,i,2)))
pos+1
Next
ElseIf byteorder = #littleEndian
For i=len - 1 To 0 Step -2
PokeB(Address+pos,Val("$"+Mid(hex$,i,2)))
pos+1
Next
EndIf
EndProcedure
Procedure.s hexToText(hex$) ;tries to show hex as text
Protected i, pos, len, result$, val
hex$ = RemoveString(hex$," ")
len = Len(hex$)
result$ = Space(len/2)
For i=1 To len Step 2
val = Val("$"+Mid(hex$,i,2))
If val <> #Null ;replace null char with space
PokeB(@result$+pos,val)
Else
PokeB(@result$+pos,' ')
EndIf
pos+1
Next
ProcedureReturn result$
EndProcedure
Procedure.s hexToTextSanitized(hex$) ;emulates hex editors, called "sanitized" since it removes tabs and linefeeds
Protected i, pos, len, result$, val
hex$ = RemoveString(hex$," ")
len = Len(hex$)
result$ = Space(len/2)
For i=1 To len Step 2
val = Val("$"+Mid(hex$,i,2))
Select val
Case #Null,#TAB,#CR,#LF: PokeB(@result$+pos,'.')
Default: PokeB(@result$+pos,val)
EndSelect
pos+1
Next
ProcedureReturn result$
EndProcedure
Procedure.s memoryToTextSanitized(address,length) ;emulates hex editors, called "sanitized" since it removes tabs and linefeeds
Protected result$, i, byte.b
For i=0 To length
byte = PeekB(address+i)
Select byte
Case #Null,#TAB,#CR,#LF: result$ + "."
Default: result$ + Chr(byte)
EndSelect
Next
ProcedureReturn result$
EndProcedure
Procedure.l SendNetworkHex(connection,hex$) ;stuff should often be big-endian over network btw
Protected result, *buffer = AllocateMemory(getHexSize(hex$))
hexToMemory(*buffer,hex$)
result = SendNetworkData(connection,*buffer,MemorySize(*buffer))
FreeMemory(*buffer)
ProcedureReturn result
EndProcedure
Procedure.s strToHex(string$)
ProcedureReturn memoryToHex(@string$,Len(string$))
EndProcedure
Procedure.s longToHex(long,byteorder=#littleEndian)
ProcedureReturn memoryToHex(@long,4,byteorder)
EndProcedure
Procedure.s wordToHex(word.w,byteorder=#littleEndian)
ProcedureReturn memoryToHex(@word,2,byteorder)
EndProcedure
Procedure.s byteToHex(byte.b)
ProcedureReturn memoryToHex(@byte,1)
EndProcedure
Procedure hexToLong(*long,hex$,byteorder=#littleEndian)
hex$ = RemoveString(hex$," ")
If Len(hex$) = 8 ;limits stupidity
hexToMemory(*long,hex$,byteorder)
EndIf
EndProcedure
Procedure hexToWord(*word,hex$,byteorder=#littleEndian)
hex$ = RemoveString(hex$," ")
If Len(hex$) = 4 ;limits stupidity
hexToMemory(*word,hex$,byteorder)
EndIf
EndProcedure
Procedure hexToByte(*byte,hex$)
If Len(hex$) = 2 ;limits stupidity
hexToMemory(*byte,hex$)
EndIf
EndProcedure
;little-endian example (uncomment to test)
;Define long.l
;hexToLong(@long,"00 00 00 04") ;at default saves in little-endian order, same as long=$00000004
;Debug long
;Debug longToHex(long) ;at default reads as little-endian
;Debug longToHex(long,#bigEndian) ;shown as physically stored (left to right)
;End
;Just me playing around with it...
Define hex$ = "F7"+strToHex("Hello")+"F7"
Define size = getHexSize(hex$)
Define *buffer = AllocateMemory(size)
hexToMemory(*buffer,hex$)
Debug PeekS(*buffer,size)
Debug memoryToHex(*buffer,size)
Debug ""
Debug hexToText("48656C6C6F20776F726C64210041206E756C6C20776F6E742073746F70206D65203A29")
Debug hexToTextSanitized("48656C6C6F20776F726C64210D0A416E64206E6F7720636F6D657320612074616209636F6F6C2072696768743F0D0A0D0A0D0A0D0A0D0A0D0A0D0A")
Debug ""
Define string$ = "Hex rules!"
Debug memoryToHex(@string$,Len(string$))
Code: Select all
;Extra
Procedure.l reverseLong(long)
Protected result.l, i
For i=0 To 3
PokeB(@result+i,PeekB(@long+3-i))
Next
ProcedureReturn result
EndProcedure
Procedure.q uLongToQuad(ulong.l)
ProcedureReturn ulong & $FFFFFFFF
EndProcedure
Procedure.s uToHex(u.u,byteorder=#littleEndian)
ProcedureReturn memoryToHex(@u,2,byteorder)
EndProcedure