Page 2 of 2
Re: Need quick StringToHex() function
Posted: Tue Mar 19, 2013 5:46 pm
by SFSxOI
Wilbert's code is very nice, fast too, thanks Wilbert
If anyone needs something to check for valid hex digits you can use regular expressions also, like this using the POSIX character class for hex instead of doing the [a-fA-F0-9] thing:
Code: Select all
Procedure IsHex(in_str.s)
rex_ishex = CreateRegularExpression(#PB_Any,"^[[:xdigit:]]+$")
is_hex.b = MatchRegularExpression(rex_ishex, in_str)
FreeRegularExpression(rex_ishex)
ProcedureReturn is_hex
EndProcedure
; returns #True (1) if character is valid hex, #False (0) if not
Re: Need quick StringToHex() function
Posted: Tue Feb 24, 2015 2:04 pm
by Joris
Hi,
I have a strange problem, probably related to my PB-settings, but I don't know how to fix it.
If I use Wilbert's HexToString procedure above, in my source it works very fine (outside the pbi-file). Thanks Wilbert.
If placed inside the pbi like below, it gives a wrong result in the saved file.
Of coarse I can remove it from the pbi and place it inside my 'working source', but what causes this problem.
I'm quit sure it has something todo with #PB_Compiler_Unicode, but how to set it right ?
The result in the file should look the same in a hex-editor (like UltraEdit) as the string send.
Thanks.
Code: Select all
XIncludeFile "String Convertie.pbi" ;in here is the HexToString procedure
Global s.s = "F043104C0839212BF7"
s=HexToString("F043104C0839212BF7")
If CreateFile(0, "C:\test.dat")
WriteData(0, @s, Len(s))
CloseFile(0)
Else
Debug "may not create the file!"
EndIf
Re: Need quick StringToHex() function
Posted: Tue Feb 24, 2015 3:33 pm
by Joris
I suppose my problem above can only be solved if not activating the "Create Unicode executable".
I understand Unicode needs two bytes for a single character, ASCII only one.
Yet, still I don't understand why the problem arrives and how to work uniformly ?
Probably best would be always Unicode and giving this result "00F0 0043 0010 004C 0008 0039 0021 002B 00F7" instead of "F0 43 10 4C 08 39 21 2B F7", but this could cause a big problem as the hardware needs ASCII, so I may not activate "Create Unicode executable" ?
Yeah, sorry to if it seems stupid but I'm not used to this and so still confused.
Re: Need quick StringToHex() function
Posted: Tue Feb 24, 2015 8:49 pm
by Danilo
And if you replace
with
WriteData(0, @s, Len(s)) writes only half of Unicode strings.
Re: Need quick StringToHex() function
Posted: Tue Feb 24, 2015 9:15 pm
by StarBootics
When I run this code in Unicode Mode :
Code: Select all
; Converts hex notation to a string (each hex code to a byte)
Procedure.s HexToString(Original.s)
Protected i.a, n.a, *In.Ascii = @Original
Protected *Out.Ascii = *In
i = *In\a
While i
i & 31
If i < 7
i + 9
Else
i & 15
EndIf
If n > 15
*Out\a = n << 4 | i
*Out + 1
n = 0
Else
n = i | 16
EndIf
*In + SizeOf(Character)
i = *In\a
Wend
*Out\a = 0
CompilerIf #PB_Compiler_Unicode
ProcedureReturn PeekS(@Original, -1, #PB_UTF8)
CompilerElse
ProcedureReturn Original
CompilerEndIf
EndProcedure
Global Original.s = "F043104C0839212BF7"
Debug Original
String.s = HexToString(Original)
If Trim(String) <> ""
Debug String
Else
Debug "Empty String"
EndIf
I get this in the debugger output:
F043104C0839212BF7
Empty String
This is a way to write a string as Data whatever if you are compiling in Ascii or Unicode. Indeed if you create the file in Ascii you have to read it in Ascii.
Code: Select all
Procedure WriteStringEx(FileID.l, String.s)
WriteLong(FileID, SizeOf(Character) * Len(String))
WriteData(FileID, @String, SizeOf(Character) * Len(String))
EndProcedure
Procedure.s ReadStringEx(FileID.l)
String.s = Space(ReadLong(FileID))
ReadData(FileID, @String, Len(String))
ProcedureReturn String
EndProcedure
Best regards
StarBootics
Re: Need quick StringToHex() function
Posted: Tue Feb 24, 2015 9:22 pm
by Joris
Danilo it gives the same result.
It seems really related to the compiler option "Create Unicode executable".
If activating "Create Unicode executable" the output is wrong, with yours and Wilbert's sollution : => 43 10 4C 08 39 21 2B
Deactivate "Create Unicode executable" and the result is ok : => F0 43 10 4C 08 39 21 2B F7
Code: Select all
; Converts hex notation to a string (each hex code to a byte)
Procedure.s HexToString(Original.s)
Protected i.a, n.a, *In.Ascii = @Original
Protected *Out.Ascii = *In
i = *In\a
While i
i & 31
If i < 7
i + 9
Else
i & 15
EndIf
If n > 15
*Out\a = n << 4 | i
*Out + 1
n = 0
Else
n = i | 16
EndIf
*In + SizeOf(Character)
i = *In\a
Wend
*Out\a = 0
CompilerIf #PB_Compiler_Unicode
ProcedureReturn PeekS(@Original, -1, #PB_UTF8)
CompilerElse
ProcedureReturn Original
CompilerEndIf
EndProcedure
Global s.s = "F043104C0839212BF7"
s=HexToString("F043104C0839212BF7")
If CreateFile(0, "e:\test.syx") ; we create a new text file...
WriteString(0,s,#PB_Ascii)
;WriteData(0, @s, Len(s))
CloseFile(0) ; close the previously opened file and so store the written data
Else
Debug "may not create the file!"
EndIf
Re: Need quick StringToHex() function
Posted: Tue Feb 24, 2015 9:44 pm
by StarBootics
I forget to mention, I'm under Ubuntu Gnome 14.10 x64 and PureBasic 5.31 x64.
I don't understand why I get an empty string, strange...
Beat regards
StarBootics
Re: Need quick StringToHex() function
Posted: Tue Feb 24, 2015 9:51 pm
by wilbert
Try to replace #PB_UTF8 in this line from the HexToString procedure
ProcedureReturn PeekS(@Original, -1, #PB_UTF8)
with #PB_Ascii
The hex codes you present don't seem to be a utf8 string.
Re: Need quick StringToHex() function
Posted: Wed Feb 25, 2015 7:09 am
by Danilo
Joris wrote:Danilo it gives the same result.
I didn't look at the procedure before. Just said that "WriteData(0, @s, Len(s))" cannot give the same result for ASCII and Unicode.
Changed the procedure a bit now, hope it is still correct for all cases you need:
Code: Select all
; Converts hex notation to a string (each hex code to a byte)
Procedure.s HexToString(Original.s)
Protected i.a, n.a, *In.Character = @Original
Protected *Out.Ascii = *In
i = *In\c
While i
i & 31
If i < 7
i + 9
Else
i & 15
EndIf
If n > 15
*Out\a = n << 4 | i
*Out + SizeOf(Character)
n = 0
Else
n = i | 16
EndIf
*In + SizeOf(Character)
i = *In\c
Wend
*Out\a = 0
CompilerIf #PB_Compiler_Unicode
ProcedureReturn Original;PeekS(@Original, -1, #PB_UTF8)
CompilerElse
ProcedureReturn Original
CompilerEndIf
EndProcedure
Global s.s = "F043104C0839212BF7"
s=HexToString("F043104C0839212BF7")
Debug s
If CreateFile(0, "e:\test.syx") ; we create a new text file...
WriteString(0,s,#PB_Ascii)
;WriteData(0, @s, Len(s))
CloseFile(0) ; close the previously opened file and so store the written data
Else
Debug "may not create the file!"
EndIf
Gives me 2 identical files for Asc/Uni, 9 Bytes each: F0 43 10 4C 08 39 21 2B F7
Re: Need quick StringToHex() function
Posted: Wed Feb 25, 2015 9:34 am
by Joris
StarBootics if I run your code here in Unicode mode I get this CL9!+ as debug output (the file output is a better reference). And I'm still under XP32.
But after Wilbert's tip and your SizeOf(Character) * Len(sysex_save) all results are like should, with and without "Create Unicode executable".
Wilbert replacing #PB_UTF8 with #PB_Ascii gives the result like should in both cases. So that UTF8, I must look what that exactly means and should do...
F0 00 43 00 ... etc. in unicode, I understand the double zero stands for the second byte and to me that is ok, in ASCII no double zero, completely ok.
Danilo your code works fine here too and in both cases giving the same result, so that might be the solution. I'm gonna look now how it differs from the previous ones.
Yet, I probably must compile my program without activating "Create Unicode executable" as else would appear that double 00 when saving files.
But then what to do if for example someone creates text-files in unicode format to use in my program ?
How to prevent it goes wrong then ? (Yeah I can/will tell in the help only to use ASCII files, but...)
Does anyone have a little text-file in unicode-format for me ?
Thanks all for helping.
Re: Need quick StringToHex() function
Posted: Wed Feb 25, 2015 12:33 pm
by Joris
Trying to learn and hopefully understanding a bit more about all this... there is a lot... maybe it would be much easier if there are some small sample text-files of all sort format there is to find :
All different encoding forms, BOM, big-endian, little-endian etc.
Besides the PB help a bit more of info here :
http://unicode.org/faq/utf_bom.html#BOM
http://www.ultraedit.com/support/tutori ... icode.html
Thanks