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: -
Dim sFileBuffer as String = system.io.file.readalltext("myimagefile")
-
Dim sLookFor as String = chr(100) & chr(0) & chr(0) & chr(163)
-
-
Dim iLocation as Integer = sFileBuffer.IndexOf(sLookFor)
-
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: -
Dim Marker() as Byte = {100, 0, 0 , 163}
-
Dim sLookFor as String = System.Text.Encoding.UTF8.GetString(Marker)
-
Dim sFileBuffer as String = system.io.file.readalltext("myimagefile", Encoding.UTF8)
-
-
Dim iLocation as Integer = sFileBuffer.IndexOf(sLookFor)
-
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
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: -
Public Function ReturnLocationAfterFound(ByVal SearchBytes As Byte(), ByVal Targetbytes As Byte()) As Integer
-
For a As Integer = 0 To (Targetbytes.Length - 1)
-
' Search the length of the target array
-
If Targetbytes(a) = SearchBytes(0) Then
-
' We found a match to the first byte of our comparitor
-
' Do all the rest match?
-
For b As Integer = 0 To (SearchBytes.Length - 1)
-
Dim WeHaveAWinner As Boolean = False
-
If Targetbytes(a + b) = SearchBytes(b) Then
-
If b = (SearchBytes.Length - 1) Then
-
Return a
-
End If
-
Continue For
-
Else
-
' break out of the 'b' loop since it doesn't match
-
Exit For
-
End If
-
Next
-
End If
-
Next
-
' If we got this far there was no match
-
Return (-1)
-
End Function
-
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
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 - // Returns the value of the NEXT byte after the match
-
// Or -1 if no match
-
public int ReturnLocationAfterFound(byte[] SearchBytes, byte[] Targetbytes)
-
{
-
for (int a = 0; a < Targetbytes.Length; a++)
-
{
-
// Search the length of the target array
-
if (Targetbytes[a] == SearchBytes[0])
-
{
-
// We found a match to the first byte of our comparitor
-
// Do all the rest match?
-
for (int b = 0; b < SearchBytes.Length; b++)
-
{
-
bool WeHaveAWinner = false;
-
if (Targetbytes[a + b] == SearchBytes[b])
-
{
-
WeHaveAWinner = true;// Keeps setting to true as long as they match
-
}
-
else
-
{
-
WeHaveAWinner = false;
-
break;// break out of the 'b' loop since it doesn't match
-
}
-
}
-
// Yep, this should have been outside of the 'for' loop construct
-
if (WeHaveAWinner) return a + b;// this is the location right after our match
-
}
-
}
-
// If we got this far there was no match
-
return -1;
-
}
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. - 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.
Sign in to post your reply or Sign up for a free account.
Similar topics |
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!'
|
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:
|
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:
|
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)
|
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.
| |
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);
|
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.
|
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
|
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
{
|
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...
|
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,...
| |
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...
|
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,...
|
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...
|
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();...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |
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
| |