Creating a Hex Byte String Constant (revisited)

I’m trying to create string constants for &hC0, &hDB, &hDC &hDD for a wire protocol.
They are used in almost every packet exchange.

Looking over the forum, there is this idea:
how-to-define-a-control-character-string-constant
But that only seems to work for bytes less than &u80. &u80 and over generate two-byte UTF-8 sequence.

Any ideas how to create a single byte hex string constant over &h80?

does &u12345678 not work for you?

I need a single byte constant. The &uC0 unicode constant, for example,
turns into 2 bytes &hC380 (the UTF-8 code point) when assigned to a string.

Change the encoding for your string? (Not sure if you can set it to Nil).

Doesn’t seem to matter. Encoding is already Nil, I’ve tried to change to ASCII, same result.
Assigning the constant still produces the 2-byte ‘codepoint’, not the single byte.

Any reason why you don’t want to chrB your hex constants into your string?

[code]Const c = &hFF

Dim s2, s1 As String

s2 = chr© '2 bytes

s1 = chrB© '1 byte[/code]

[quote=445123:@]Any reason why you don’t want to chrB your hex constants into your string?

[code]Const c = &hFF

Dim s2, s1 As String

s2 = chr(c) '2 bytes

s1 = chrB(c) '1 byte[/code][/quote]
It’s part of a network encoding/decoding process that can occur 30x or more per second.
Assigning strings via ‘ChrB’ or loading via Module property every time just seems inefficient.
I’d hoped to generate a module constant that I could re-use in the 4 methods that need them.

&hC0 is the ascii char “¿”.
can’t you just put this in an IDE string constant ?
so for the others ?

[quote=445145:@Jean-Yves Pochez]&hC0 is the ascii char “¿”.
[/quote]

No its not
&hC0 is NOT ASCII - its some other single byte encoding like Windows Latin 1 or something
ASCII stops at &h7F

A way to insert characters using their Unicode Code point value into the constant editor would be nice
Something like this <https://xojo.com/issue/56192>
Or a contextual menu where you could right click and “Insert Character” and get a small popup that would allow you to enter the code point etc

I tried on Windows, where you can enter any ‘character’ with an alt+number-pad sequence, similar to making a TAB constant.
The IDE displayed a single “À” (which is &u00c0), and Xojo still inserted &hC380 (UTF-8) into the result.

Maybe I am not following your issue, but I’ve certainly done constants greater than &h80, and sent them through serial. An example I am looking at (probably from 2014) uses the following constant:

Const commSTX = &h81

And it uses a memory block to convert it to String and then send it over serial as follows:

s = Hex2String(commSTX,1) Serial1.Write(s)
where the memory block function is defined as:

[code]Protected Function Hex2String(HexValue As UInt32, Bytes As UInt8) As String
//converts a 32-bit (4-byte max) hex value into a string (MSB first)

Dim s As String
Dim msb As UInt8
Dim mb As New MemoryBlock(4)
mb.LittleEndian = False

If (Bytes > 0) And (Bytes < 5) Then
msb = 4-Bytes
Else
msb = 0
End If

mb.UInt32Value(0) = HexValue
s = mb.StringValue(msb,Bytes)
Return s
End Function
[/code]

I’m trying to avoid that conversion since it is a part of EVERY message. Serial port speeds aren’t fast enough to warrant that much optimization.
I have a device that can send 30 messages (not bytes) per second over TCP, each wrapped in an special start/stop character.
The messages aren’t a fixed size and typically vary from 10 to 300 characters. Sometimes less, sometimes more.
Try collecting from 10 or more of these devices at once, at 300+ messages per second, each with a Encode/Decode call.

Why not a simple computed property that only has its getter implemented that returns a string
in there you just return chrb( whatever >
Although it has a runtime hit, more than a constant would, it should be very small
And from a semantic point of view you cant tell the difference

No, ASCII stops at 7F. And &hC0 can be something else (this depends on the platform OS and/or encoding).

[quote=445287:@Norman Palardy]Why not a simple computed property that only has its getter implemented that returns a string
in there you just return chrb( whatever >
Although it has a runtime hit, more than a constant would, it should be very small
And from a semantic point of view you cant tell the difference[/quote]
I’d thought of that, but it still looks like a conversion every access.

Here’s what I ended up with:

[code]// Class Constants
kESC = &hDB
'… etc …

//Class Properties
cESC As String
'… etc …

//Class constructor
Public Sub Constructor()
cESC = ChrB(kESC)
'… etc …
End Sub
[/code]
Still a property access each use, but only one ‘conversion’ from integer/hex to string/byte.

[quote=445294:@John A Knight, Jr]I’d thought of that, but it still looks like a conversion every access.

Here’s what I ended up with:

[code]// Class Constants
kESC = &hDB
'… etc …

//Class Properties
cESC As String
'… etc …

//Class constructor
Public Sub Constructor()
cESC = ChrB(kESC)
'… etc …
End Sub
[/code]
Still a property access each use, but only one ‘conversion’ from integer/hex to string/byte.[/quote]

If you’re suffering from performance anxiety, I think a cure might be to define static variables in any method where these values are needed –

static C0 as String = ChrB(&hC0)
static DB as String = ChrB(&hDB)
static DC as String = ChrB(&hDC)
static DD as String = ChrB(&hDD)

Then ChrB would be invoked only once (for each line), during the first invocation of the method.

I don’t know whether there is a difference in speed when reading static v. local variables. If so, then that’s another possibility for improving execution speed.

1 Like