PeekHexBytes() and PokeHexBytes()
-
- Addict
- Posts: 4527
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: PeekHexBytes() and PokeHexBytes()
Oops => done now.
yrreti, thanks for telling me!
Regards, Little John
yrreti, thanks for telling me!
Regards, Little John
Re: PeekHexBytes() and PokeHexBytes()
is your first post in this thread the most current?
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.
-
- Addict
- Posts: 4527
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: PeekHexBytes() and PokeHexBytes()
No, at the moment it isn't.
Trond came up with some code for poking, which I like very much. It is simpler and more flexible than the code I wrote so far. Based on his code, this post contains my most recent version (complete code in the 2nd code block of that post). As far as I can see, everything is fine with it. But I consider it a draft at the moment, since I wouldn't be surprised if Trond comes up with more improvements. So at the moment I'm waiting for his reply. In a few days, I'll probably put my final version into the first post.
Thanks for your interest.
Regards, Little John
Trond came up with some code for poking, which I like very much. It is simpler and more flexible than the code I wrote so far. Based on his code, this post contains my most recent version (complete code in the 2nd code block of that post). As far as I can see, everything is fine with it. But I consider it a draft at the moment, since I wouldn't be surprised if Trond comes up with more improvements. So at the moment I'm waiting for his reply. In a few days, I'll probably put my final version into the first post.
Thanks for your interest.
Regards, Little John
Re: PeekHexBytes() and PokeHexBytes()
There is a problem with your input verification, it accepts illegal characters:
Code: Select all
For i = 15 To 26
c = i
c | %00100000
If c < '0' Or (c > '9' And (c < 'a' Or c > 'f'))
Debug "Failed input: " + Chr(i)
Else
Debug "Accepted input: " + Chr(i) + " (thought to be " + Chr(c) + ")"
EndIf
Next
Re: PeekHexBytes() and PokeHexBytes()
This should be relatively bullet-proof, it return the number of bytes written. It also accept a single character as a hex number (so you don't need to pad with 0 first), but rejects three hex digits in a row.
Code: Select all
Procedure _GetString(*M.Character, S.s)
l = StringByteLength(S)
If CompareMemory(*M, @S, L)
ProcedureReturn *M+l
EndIf
ProcedureReturn *M
EndProcedure
Procedure IsHexChar(*Source.Character)
Select *Source\c
Case '0' To '9', 'A' To 'Z', 'a' To 'z'
ProcedureReturn 1
EndSelect
EndProcedure
Procedure _GetHexLength(*Source)
If IsHexChar(*Source)
If IsHexChar(*Source+SizeOf(Character))
If IsHexChar(*Source+2*SizeOf(Character))
ProcedureReturn 0 ; Error in input
EndIf
ProcedureReturn 2
EndIf
ProcedureReturn 1
EndIf
EndProcedure
; Return number of bytes written
Procedure.i PokeHexBytes(*Dest.Ascii, Bytelist.s, Separator.s = "", Prefix.s = "")
Protected *Source.Character = @Bytelist
Protected *OrigDest = *Dest
While *Source\c
*Source = _GetString(*Source, Prefix)
HexL = _GetHexLength(*Source)
If HexL = 0
Break
EndIf
PokeA(*Dest, Val("$" + PeekS(*Source, HexL)))
*Source + HexL * SizeOf(Character)
*Dest + 1
*Source = _GetString(*Source, separator)
Wend
ProcedureReturn *Dest - *OrigDest
EndProcedure
-
- Addict
- Posts: 4527
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: PeekHexBytes() and PokeHexBytes()
Oops I'm making so many stupid mistakes lately ... Thanks again!Trond wrote:There is a problem with your input verification, it accepts illegal characters:
I think I'll use the following instead:
Code: Select all
Macro CheckHexDigit ()
Select *source\c
Case '0' To '9', 'A' To 'F', 'a' To 'f'
; OK, do nothing
Default
ProcedureReturn 0 ; error
EndSelect
*source + SizeOf(Character)
EndMacro
My procedure returns the number of written bytes only on success, and 0 otherwise. I like to get a clear indicator in case of an error (-1 instead of 0 might be better, since poking "" is not really an error, and will also return 0.) Accepting a single character as a hex number is not what I personally want.Trond wrote:This should be relatively bullet-proof, it return the number of bytes written. It also accept a single character as a hex number (so you don't need to pad with 0 first), but rejects three hex digits in a row.
In your code, every time when _GetString() is called, it calles StringByteLength(S). This is not necessary, because S is either the separator or the prefix, and the lengths of both do not change during runtime of the procedure PokeHexBytes(). That's why I changed the code, so that both lengths are determined only once at the beginning, and then passed as parameter.
Regards, Little John
Re: PeekHexBytes() and PokeHexBytes()
I understand, I just worked on my own code because that was simplest to me.That's why I changed the code, so that both lengths are determined only once at the beginning, and then passed as parameter.
Now it returns -1 on failure each byte must be exactly two hex characters, but I didn't test it so buyer beware!
Code: Select all
Macro SkipString (_s_, _length_)
If CompareMemory(*Source, @_s_, _length_)
*source + _length_
EndIf
EndMacro
Procedure IsHexChar(*Source.Character)
Select *Source\c
Case '0' To '9', 'A' To 'Z', 'a' To 'z'
ProcedureReturn 1
EndSelect
EndProcedure
; Return number of bytes written or -1 on failure
Procedure.i PokeHexBytes(*Dest.Ascii, Bytelist.s, Separator.s = "", Prefix.s = "")
Protected *Source.Character = @Bytelist
Protected *OrigDest = *Dest
Protected lenPre = StringByteLength(Prefix)
Protected lenSep = StringByteLength(Separator)
While *Source\c
SkipString(Prefix, lenPre)
If IsHexChar(*Source) And IsHexChar(*Source+SizeOf(Character))
PokeA(*Dest, Val("$" + PeekS(*Source, 2)))
*Source + 2 * SizeOf(Character)
*Dest + 1
SkipString(Separator, lenSep)
Else
ProcedureReturn -1
EndIf
Wend
ProcedureReturn *Dest - *OrigDest
EndProcedure
Re: PeekHexBytes() and PokeHexBytes()
Heh, amusing that the routines are starting to ressemble mine a lot more
PS! Trond you'll get a speed gain if you unroll the procedure in the loop instead as calling the procedure has a higher overhead (stack etc.) than having repeating code (which modern CPUs do optimize for as well).
Then again my source has a bit too much branching and could probably be redone to get rid of half those ifelse.
You could probably speed up things a lot more by simply only acting on data you expect (ignoring anything else) rather than explicitly skipping and comparing things,
at least that was the idea behind the source I quickly threw together earlier.
My source also avoids PokeA() Val() PeekS() which has varying overheads, using direct reference like *string.Character and then using just *sting\c is the fastest way to do it in PureBasic (besides asm I believe).
In any case it's amusing seeing this kind of community collaboration on making the "ultimate" Hex Peek/poke routines.
PS! Trond you'll get a speed gain if you unroll the procedure in the loop instead as calling the procedure has a higher overhead (stack etc.) than having repeating code (which modern CPUs do optimize for as well).
Then again my source has a bit too much branching and could probably be redone to get rid of half those ifelse.
You could probably speed up things a lot more by simply only acting on data you expect (ignoring anything else) rather than explicitly skipping and comparing things,
at least that was the idea behind the source I quickly threw together earlier.
My source also avoids PokeA() Val() PeekS() which has varying overheads, using direct reference like *string.Character and then using just *sting\c is the fastest way to do it in PureBasic (besides asm I believe).
In any case it's amusing seeing this kind of community collaboration on making the "ultimate" Hex Peek/poke routines.
-
- Addict
- Posts: 4527
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: PeekHexBytes() and PokeHexBytes()
Please see first post for new code. Trond, thanks again!
Regards, Little John
Regards, Little John
Re: PeekHexBytes() and PokeHexBytes()
Thanks a lot, works fine here on Windows 7 Ultimate x86 and with PB 4.50
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.