473,406 Members | 2,217 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

String parsing in VB.net

Hi,

I have am converting a VB6 application to VB.net and have run into a
problem. The application connects to a TCP port on a Linux box and
receives a data buffer. The data buffer contains various fields, some
of which are two and four byte integers.

In VB6 I used the Mid function to pull data out of the buffer so I
could decrypt it (do all that tedius network-order byte-swapping, etc).
Quite simply, if I knew that the four bytes from position 42 in the
buffer contain a long integer I could:

myLong = DecryptLong(Mid(myDataBuffer, 42, 4))

However, in VB.net it seems that Mid will not always give me 4 bytes -
it terminates when it hits a chr(0). Thus I pass less than four bytes
into my DecryptLong function, and it gives the wrong result.

Is there any way to make Mid return everything I asked for, or any
function to pad the return string with chr(0)'s before I pass it to
DecryptLong? (I tried writing my own pad function but it suffered from
the same problem - VB.net just doesn't like nulls!)

Or is there a more effective way of extracting a substring than Mid,
one which perhaps gives you the substring you ask for?

Thanks.

Nov 21 '05 #1
9 11328
Stargate,

It is not a VBNet problem, the string is always ended in Net when there is a
0 value.

I think that you have to handle this as a byte array. I assume that this is
the class that should help you with that.

http://msdn.microsoft.com/library/de...classtopic.asp

I hope this helps,

Cor
Nov 21 '05 #2

Stargate4004 wrote:
Hi,

I have am converting a VB6 application to VB.net and have run into a
problem. The application connects to a TCP port on a Linux box and
receives a data buffer. The data buffer contains various fields, some
of which are two and four byte integers.

In VB6 I used the Mid function to pull data out of the buffer so I
could decrypt it (do all that tedius network-order byte-swapping, etc).
Quite simply, if I knew that the four bytes from position 42 in the
buffer contain a long integer I could:

myLong = DecryptLong(Mid(myDataBuffer, 42, 4))

However, in VB.net it seems that Mid will not always give me 4 bytes -
it terminates when it hits a chr(0). Thus I pass less than four bytes
into my DecryptLong function, and it gives the wrong result.

Is there any way to make Mid return everything I asked for, or any
function to pad the return string with chr(0)'s before I pass it to
DecryptLong? (I tried writing my own pad function but it suffered from
the same problem - VB.net just doesn't like nulls!)

Or is there a more effective way of extracting a substring than Mid,
one which perhaps gives you the substring you ask for?


My recommendation would be that myDataBuffer should be a Byte array,
and that DecryptLong should have this signature:

Function DecryptLong(buffer() as byte, start as integer) as integer

ie, you just pass the buffer and the index of the first byte of the
number (note that VB6 'Long' = 32-bit integer = VB.NET 'Integer')

HOWEVER

It turns out that the Framework will do this work for you :) The
BitConverter class contains a bunch of procedures for doing all sorts
of conversions to and from raw bytes. In particular,
BitConverter.ToInt32 Method

Returns a 32-bit signed integer converted from four bytes at a
specified position in a byte array.

Public Shared Function ToInt32( _
ByVal value() As Byte, _
ByVal startIndex As Integer _
) As Integer

Parameters
value
An array of bytes.
startIndex
The starting position within value.

Return Value
A 32-bit signed integer formed by four bytes beginning at startIndex.
There's a lot of stuff in the Framework; unfortunately the only real
way to know if there is something that does what you want is to know
everything that's there :/

--
Larry Lard
Replies to group please

Nov 21 '05 #3
Fantastic!

Thanks for your help, I'll give it a try...

Nov 21 '05 #4
To trap the error, change this:
myLong = DecryptLong(Mid(myDataBuffer, 42, 4))
to something like this:
Dim s As String
...
s = Mid(myDataBuffer, 42, 4)
Debug.Assert(Len(s) = 4)
myLong = DecryptLong(s)
When the assert is true, I believe that len(myDataBuffer) will be < 45.
The mid function will always return 4 bytes even with embedded null
characters provided that there are at least 4 characters available, ie you
are not at the end of the string, as the following example shows:
Dim s, t As String
Dim l As Integer
s = "abc" & Chr(0) & "def"
t = Mid$(s, 3, 4)
l = Len(t) ' ==> 4
s = "abc" & Chr(0) & "d"
t = Mid$(s, 3, 4)
l = Len(t) ' ==> 3
Good luck.

Nov 21 '05 #5
OK, it looks like I could be missing a trick here. I did this to get my
buffer into a byte array:

Dim asciiEncoder As New System.Text.ASCIIEncoding
Dim bDataBuffer As Byte() = asciiEncoder.GetBytes(myDataBuffer)

Then I did this to convert bytes 42 - 45 to a long integer:

myLong = BitConverter.ToInt32(bDataBuffer, 41)

(using 41 rather than 42 as it's an offset into the byte array rather
than a position of the charater in the myDataBuffer string).

But instead of getting 684229409 (which I know was sent to me), I got
675808033. This is because the four characters in myDataBuffer which
make up the integer field are 33, 131, 200 and 40, but when the string
is converted to SIGNED byte array they become 33, 3, 72 and 40.

Either asciiEncoder.GetBytes() or BitConverter.ToInt32 is treating the
bytes as signed. How can I stop this?

Nov 21 '05 #6
Stargate4004
Define myDataBuffer itself as Byte(), do not read the data from TCP as Text
(String), rather read the TCP port directly into a byte array.

ASCII is defined as 7 bit encoding, when you call ASCIIEncoding.GetBytes it
translates all characters over 127 into a value between 0 & 127.

Hence if you read the TCP stream into a byte array to begin with, then extra
the data & only convert the actual Text data into strings. Your values will
come out as you expect.

Hope this helps
Jay

"Stargate4004" <pe****@axl.co.uk> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
| OK, it looks like I could be missing a trick here. I did this to get my
| buffer into a byte array:
|
| Dim asciiEncoder As New System.Text.ASCIIEncoding
| Dim bDataBuffer As Byte() = asciiEncoder.GetBytes(myDataBuffer)
|
| Then I did this to convert bytes 42 - 45 to a long integer:
|
| myLong = BitConverter.ToInt32(bDataBuffer, 41)
|
| (using 41 rather than 42 as it's an offset into the byte array rather
| than a position of the charater in the myDataBuffer string).
|
| But instead of getting 684229409 (which I know was sent to me), I got
| 675808033. This is because the four characters in myDataBuffer which
| make up the integer field are 33, 131, 200 and 40, but when the string
| is converted to SIGNED byte array they become 33, 3, 72 and 40.
|
| Either asciiEncoder.GetBytes() or BitConverter.ToInt32 is treating the
| bytes as signed. How can I stop this?
|
Nov 21 '05 #7

Stargate4004 wrote:
OK, it looks like I could be missing a trick here. I did this to get my
buffer into a byte array:

Dim asciiEncoder As New System.Text.ASCIIEncoding
Dim bDataBuffer As Byte() = asciiEncoder.GetBytes(myDataBuffer)
The root of the problem is that you are treating 'pure binary' data as
characters. If it's not too much work :) I recommend you try and
refactor your code so that myDataBuffer is an array of Byte, rather
than a string. Earlier you said:
The application connects to a TCP port on a Linux box and
receives a data buffer.
Is this your code? I appreciate it might not be, but if it is you
should try and make it so that you receive a Byte() not a String or a
Char().

If that isn't possible:
But instead of getting 684229409 (which I know was sent to me), I got
675808033. This is because the four characters in myDataBuffer which
make up the integer field are 33, 131, 200 and 40, but when the string
is converted to SIGNED byte array they become 33, 3, 72 and 40.
Actually, Byte is unsigned.

Either asciiEncoder.GetBytes() or BitConverter.ToInt32 is treating the
bytes as signed. How can I stop this?


It's ASCIIEncoding that is doing this. Although we commonly refer to a
familiar mapping between the numbers 0-255 and a certain list of
characters as 'ASCII', the actual fact is that ASCII is a *7* bit
encoding - it is only defined for 0-127. Anything beyond that depends
on a whole host of things. Because this encoding only looks at the
bottom 7 bits, it maps 131 (binary 1000 0011) to 3 (binary 000 0011) -
ie values over 127 get 128 subtracted from them.

The fix?

You might be able to get away with just changing to using
System.Text.Encoding.Default, which uses your system's default *ANSI
code page* encoding (ANSI code pages DO cover the full range 0-255).
But this relies on whoever converts the bytes to a string in the first
place also using that same code page. Which they probably will. But
maybe not. So really this is why you want to get bytes back from the
TCP communication, not a string :)

--
Larry Lard
Replies to group please

Nov 21 '05 #8
Many thanks for all your help everybody.

I changed the code to use a Byte array all the way through, and
hey-presto it all works fine now.

Thanks again.

Peter.

Nov 21 '05 #9
> When the assert is true, I believe that len(myDataBuffer) will be < 45.

Oops - I mean when the assert fails.

Nov 21 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

26
by: Kai Jaensch | last post by:
Hello, i am an newbie and i have to to solve this problem as fast as i can. But at this time i donīt have a lot of success. Can anybody help me (and understand my english :-))? I have a...
18
by: Steve Litvack | last post by:
Hello, I have built an XMLDocument object instance and I get the following string when I examine the InnerXml property: <?xml version=\"1.0\"?><ROOT><UserData UserID=\"2282\"><Tag1...
50
by: z. f. | last post by:
HI, i have string in format dd/mm/yyyyy hh:mm:ss and giving this as an input to DateTime.Parse gives a string was not recognized as a valid date time format string error. how do i make the parse...
9
by: Python.LeoJay | last post by:
Dear all, i need to parse billions of numbers from a file into float numbers for further calculation. i'm not satisfied with the speed of atof() function on my machine(i'm using visual c++ 6)....
4
by: Michael Meckelein | last post by:
Hello, Wondering, if C# (framework 2.0) does not support parsing DateTime timezones in three letter acronyms. I would like to parse date strings like "2005 Nov 01 11:58:47.490 CST -6:00" but...
3
by: dimasteg | last post by:
Hi all C. Nead some help with string "on the fly" parsing, how it can be realized ? Any ideas? I got some of my own, but it's interesting to get other points of view . Regards.
9
balabaster
by: balabaster | last post by:
I'm looking for some ideas regarding string parsing and brackets. Say I have the following string: 56*(73+23/(28+(7/14)-(3/2)) What would be the best way to parse the string for each opening...
6
by: James Arnold | last post by:
Hello, I am new to C and I am trying to write a few small applications to get some hands-on practise! I am trying to write a random string generator, based on a masked input. For example, given...
6
by: (2b|!2b)==? | last post by:
I am expecting a string of this format: "id1:param1,param2;id2:param1,param2,param3;id" The tokens are seperated by semicolon ";" However each token is really a struct of the following...
1
by: eyeore | last post by:
Hello everyone my String reverse code works but my professor wants me to use pop top push or Stack code and parsing code could you please teach me how to make this code work with pop top push or...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.