473,811 Members | 3,299 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Search a string buffer with nulls (chr(0))

!NoItAll
297 Contributor
I need to search a buffer for a string of characters.
The buffer is essentially a binary file (it's an image) and contains lots of chr(0) characters.
The string I need to locate also contains chr(0) characters. In fact it is the following string:
chr(100) & chr(0) & chr(0) & chr(163)

This is a marker in the image file for items I need to process.
So I though I would do the following:

Expand|Select|Wrap|Line Numbers
  1. Dim sFileBuffer as String  = system.io.file.readalltext("myimagefile")
  2. Dim sLookFor as String = chr(100) & chr(0) & chr(0) & chr(163)
  3.  
  4. Dim iLocation as Integer = sFileBuffer.IndexOf(sLookFor)
  5.  
The problem is that, although the characters in sLookFor definitely exist inside of sFileBuffer - IndexOf will always return -1 (not found).

I tried the following:

Expand|Select|Wrap|Line Numbers
  1. Dim Marker() as Byte = {100, 0, 0 , 163}
  2. Dim sLookFor as String = System.Text.Encoding.UTF8.GetString(Marker)
  3. Dim sFileBuffer as String  = system.io.file.readalltext("myimagefile",  Encoding.UTF8)
  4.  
  5. Dim iLocation as Integer = sFileBuffer.IndexOf(sLookFor)
  6.  
But this appears to only find occurrences of Chr(100) & Chr(0) - not the full 4 character sequence I desire. It appears to see the second Chr(0) as a termination of the search string.

I think the sticking point here is the null. Yes - I can string.replace( chr(0), Chr(255)) in both the sLookFor and the sFileBuffer and adjust my search accordingly - but that seems like a mess to me.

Is there not a way to search a buffer of binary data? I've tried working with byte arrays - but there appears to be no way to easily search for a sequence of byte values - just individual elements in the array.

VB6 did this perfectly just using strings.
Sep 25 '09
11 5538
!NoItAll
297 Contributor
Oh my - so we could ask the question:
"When is a stopwatch not a stopwatch?"
Answer: "When Microsoft builds it." cue laughter and applause...

Not being a C# person I can still appreciate the superior elegance of your approach. It does, however, look as though it will return a+b as soon as it just finds a match to the first char in TargetBytes.
Would you not need Continue For (or the C# equivalent) after WeHaveAWinner = True? Also - just return a once b = (searchbytes.le ngth-1). I don't see a need for the booleans.

in VB it would look like this:

Expand|Select|Wrap|Line Numbers
  1. Public Function ReturnLocationAfterFound(ByVal SearchBytes As Byte(), ByVal Targetbytes As Byte()) As Integer
  2.         For a As Integer = 0 To (Targetbytes.Length - 1)
  3.             ' Search the length of the target array
  4.             If Targetbytes(a) = SearchBytes(0) Then
  5.                 ' We found a match to the first byte of our comparitor
  6.                 ' Do all the rest match?
  7.                 For b As Integer = 0 To (SearchBytes.Length - 1)
  8.                     Dim WeHaveAWinner As Boolean = False
  9.                     If Targetbytes(a + b) = SearchBytes(b) Then
  10.                         If b = (SearchBytes.Length - 1) Then
  11.                             Return a
  12.                         End If
  13.                         Continue For
  14.                     Else
  15.                         ' break out of the 'b' loop since it doesn't match
  16.                         Exit For
  17.                     End If
  18.                 Next
  19.             End If
  20.         Next
  21.         ' If we got this far there was no match
  22.         Return (-1)
  23.     End Function
  24.  
When I run the unreliable stopwatch this routine in VB now takes less time than my less elegant solution - so this looks really good.
I think I will keep this arrow in my quiver!

Des
Sep 26 '09 #11
tlhintoq
3,525 Recognized Expert Specialist
It does, however, look as though it will return a+b as soon as it just finds a match to the first char in TargetBytes.
Yep. That return should have been moved down to lines so it was outside the 'b' loop. Correction below

Expand|Select|Wrap|Line Numbers
  1. // Returns the value of the NEXT byte after the match
  2. // Or -1 if no match
  3.         public int ReturnLocationAfterFound(byte[] SearchBytes, byte[] Targetbytes)
  4.         {
  5.             for (int a = 0; a < Targetbytes.Length; a++)
  6.             {
  7.                 // Search the length of the target array
  8.                 if (Targetbytes[a] == SearchBytes[0])
  9.                 {
  10.                     // We found a match to the first byte of our comparitor
  11.                     // Do all the rest match?
  12.                     for (int b = 0; b < SearchBytes.Length; b++)
  13.                     {
  14.                         bool WeHaveAWinner = false;
  15.                         if (Targetbytes[a + b] == SearchBytes[b])
  16.                         {
  17.                             WeHaveAWinner = true;// Keeps setting to true as long as they match
  18.                         }
  19.                         else
  20.                         {
  21.                             WeHaveAWinner = false;
  22.                             break;// break out of the 'b' loop since it doesn't match
  23.                         }
  24.                     }
  25.                        // Yep, this should have been outside of the 'for' loop construct
  26.                         if (WeHaveAWinner) return a + b;// this is the location right after our match
  27.                 }
  28.             }
  29.             // If we got this far there was no match
  30.             return -1;
  31.         }
Would you not need Continue For (or the C# equivalent)
Nope. Everything within the curly braces is the 'for' loop. No need to specify a 'continue'. As a matter of fact your placement of the DIM Bool and Continue seem odd to me, but I'm not a VB guy. to me it looks as if the bool will get reintialized to false every loop through b, plus the continue is in the middle of the If...Then... Else... Doesn't that mean the "continue for' get's run before the 'else' clause of the 'if', and therefore the loop starts all over without ever executing the 'else' condition. Basically making the else clause unreachable?

<more studying of your VB translation>

Ok, I think I get what you've done. Ok, yeah...The way you've done it the bool is not used. Just a little difference in programming style but they both get the job done. We both have 3 'if' conditions, I just prefer to not have two inside the inner loop, because they both get evaluated on every pass through the loop. I don't think the difference in processing time of one or two 'if' checks is ever going to make a detectable difference. You'd have to be searching for a signature of a 1000 bytes, and doing it 1000 times to see much of a reduction in performance.

By returning 'a' you are returning the start position of the matching set of bytes.
By returning 'a + b' you are return the start position of the bytes *after* the matching set of bytes. I guess it just depends on what you are looking for.

I thought the goal was to process everything *after* the 'signature' you were looking for, so that's why I went with returning a+b.

Expand|Select|Wrap|Line Numbers
  1. Not being a C# person I can still appreciate the superior elegance of your approach.
I appreciate the kind words, but I think your take on the approach is every bit as good and clean. Keep up the good work.
Sep 26 '09 #12

Sign in to post your reply or Sign up for a free account.

Similar topics

0
2644
by: Connelly Barnes | last post by:
Yet another useful code snippet! This StringBuffer class is a FIFO for character data. Example: B = StringBuffer('Hello W') B.append('orld!') print B.read(5) # 'Hello' print B.read() # 'World!'
1
5211
by: flam | last post by:
Hello, I am having a hard time spliting a string into an array for use in a search. Here is the situation. The user will input a search string. Normally I can just split the string by "split /\s+/, $string". However, I want to allow the user to put words so they appear and are searched together ie. "search this" would be searched as one term and not "search" and then somewhere else "this", etc. So if a user enters something like this:
1
36089
by: Ren? M?hle | last post by:
I have a psp script with a procedure just to run an update on one table. The Problem occurs when I try to compile this script with pspload: ORA-20006: "frsys_updatereport.psp": compilation failed with the following errors. ORA-06502: PL/SQL: numeric or value error: character string buffer too small Here the whole script:
1
2339
by: Srini | last post by:
Hi, I am working on a project and a portion of which involves receiving xml files on internet, extract values to build a string and pass that string to legacy system. I am planning on using XMLReader to read passed xml file and extract values that need to be mapped to string buffer. However, in this method I am not able to get the full path (ie., path information from root to this node)
2
1201
by: Bae,Hyun-jik | last post by:
Hi, My managed C++ library frequently takes LPCTSTR from managed exe. Due to the fact that my library doesn't modify string buffer if its parameter type is LPCTSTR, it won't be required to copy text data from System::String to another buffer memory, however, I couldn't find how to let my library access System::String text buffer directly. Please reply any answers. Thanks in advance.
3
5720
by: s88 | last post by:
Hello All: I'm trying to make a string buffer for my APIs. For example: void test(char * str){ sprintf(str,"inner test\n"); } int main(void){ int i = -5; char *str=(char*)malloc(sizeof(char)*100);
1
11702
by: atl10spro | last post by:
Hello Everyone, I am new to MS Access and although I have created several different databases I lack the VB knowledge to code a search function. I am turning to your expertise for assistance. I am using MS Access 2003. This is what I am looking for: A text field for the user to enter the search string or keyword.
8
4058
by: Zytan | last post by:
When using DllImport to import win32 functions that have strings, I know you can use the native c# string type. But, what about a function that expects a string buffer, and writes to it? I've seen people use StringBuilder for this, but is string good enough? The problem is that I am seeing what appears to be uninitialized data when I use StringBuilder, so I am wonder what is the correct solution thanks Zytan
5
2044
by: rsennat | last post by:
Hi, I'm having the following structures and std::list of that structs. I need to read the list of list as below and build a buffer as a table information. Any idea on how to build a table info (string buffer). list<NVPairsWithId> m_ResponseObj; struct NVPairsWithId {
0
9734
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9607
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10395
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10408
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10137
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6895
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5561
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5700
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4346
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.