Board index » cppbuilder » Determine the amount of bytes in a BYTE type buffer

Determine the amount of bytes in a BYTE type buffer


2007-04-22 06:02:26 AM
cppbuilder107
For the purposes of write a function that writes a REG_BINARY type data to
the registry I need to determine the byte size of the incoming data. Here
is my code:
void __fastcall TForm1::Button5Click(TObject *Sender)
{
TMemoryStream *Data = new TMemoryStream;
Data->LoadFromFile("hosts.txt");
//..open Key, etc
WriteREG_BINARY("Test", (BYTE *)Data->Memory);
}
//---------------------------------------------------------------------------
long __fastcall TRegIniFilePlus::WriteREG_BINARY(AnsiString Ident, BYTE *
Buffer)
{
return RegSetValueEx(CurrentKey, Ident.c_str(), 0, REG_BINARY, Buffer,
sizeof(Buffer));
}
Now I know I can pass the size to WriteREG_BINARY as another argument but I
dont want to do that.
Another scenario. Instead of passing TMemoryStream->Memory; if I have
buffer = new BYTE[1024], and I want to pass buffer to WriteREG_BINARY, how
would I determine the number of bytes in buffer?
-M-
 
 

Re:Determine the amount of bytes in a BYTE type buffer

Quote
long __fastcall TRegIniFilePlus::WriteREG_BINARY(AnsiString Ident, BYTE *
Buffer)
{
return RegSetValueEx(CurrentKey, Ident.c_str(), 0, REG_BINARY, Buffer,
sizeof(Buffer));
}
sizeof() in this case will return the size of the pointer. In 32-bit
systems this will be 4.
Quote
Now I know I can pass the size to WriteREG_BINARY as another argument but
I dont want to do that.
The only thing you can do is to encode the size into 'Buffer' somehow. You
can either preceed the data by a size indicator or end the buffer with an
end-of-buffer sequence (like NULL character to C strings). But, this isn't
good practice.
Can you explain why you can't pass the length of the buffer as another
argument? This function appears to be a generic writer. And generic
systems should be designed to be as open as possible (ie. provide a length
argument).
Quote
Another scenario. Instead of passing TMemoryStream->Memory;
If you're using TMemoryStream then you have access to the size of the
memory. I really will need to see why you don't want to have that extra
length argument before I'll be able to suggest anything else.
- Clayton
 

Re:Determine the amount of bytes in a BYTE type buffer

Quote
The only thing you can do is to encode the size into 'Buffer' somehow.
Can you explain why you can't pass the length of the buffer as another
argument?
I really will need to see why you don't want to have that extra length
argument before I'll be able to suggest anything else.
Clayton, thank you for your response.
The reason why I dont want to pass the size as an argument is because I want
to limit the hassle to developer; you see, I am constructing a Registry
Component. So it's a matter of asthetics.
I was hoping there was some sort of function out there that could count
bytes for me.
 

{smallsort}

Re:Determine the amount of bytes in a BYTE type buffer

Quote
The reason why I dont want to pass the size as an argument is because I
want to limit the hassle to developer; you see, I am constructing a
Registry Component. So it's a matter of asthetics.
By not providing a way for the developer to indicate to your function the
number of bytes in the array you are actually doing the opposite. A hassle
would be the suggestions I proposed last time about prepending or appending
some sort of length indicator.
Quote
I was hoping there was some sort of function out there that could count
bytes for me.
There would be no way for the code to know how many bytes are in the array.
Even if you could access the memory manager to know how many bytes were
reserved for the array this might not be the number the developer intends to
write to the registry.
TRegIniFilePlus* rifp = new TRegIniFilePlus;
BYTE buffer[1024];
memcpy(buffer, "0123456789ABCDEF", 16);
rifp->WriteREG_BINARY("foo", buffer);
Even though 'buffer' can legally hold 1024 bytes it only has 16. How should
your code behave? When you work with a fundamental data type you need to
let the developer have control over that.
In these situations it is best to provide several overloaded versions of
your method. You can support NULL terminated C strings, TMemoryStream, or
some other custom structure type, plus your generic method which is called
by the other overloaded methods:
long __fastcall TRegIniFilePlus::WriteREG_BINARY(AnsiString Ident,
BYTE* Buffer, unsigned Length)
{
return RegSetValueEx(CurrentKey, Ident.c_str(), 0, REG_BINARY,
Buffer, Length);
}
long __fastcall TRegIniFilePlus::WriteREG_BINARY(AnsiString Ident,
char* Value)
{
WriteREG_BINARY(Ident, (BYTE*) Value, strlen(Value));
}
long __fastcall TRegIniFilePlus::WriteREG_BINARY(AnsiString Ident,
TMemoryStream* Stream)
{
WriteREG_BINARY(Ident, (BYTE*) Stream->Memory, Stream->Size);
}
long __fastcall TRegIniFilePlus::WriteREG_BINARY(AnsiString Ident,
TStream* Stream)
{
// This method is a little less efficient than the previous method
// but allows your code to work with any TStream descendant
BYTE* buffer = new BYTE[Stream->Size];
Stream->Position = 0;
Stream->Read(buffer, Stream->Size);
WriteREG_BINARY(Ident,buffer, Stream->Size);
delete[] buffer;
}
... etc ...
- Clayton
 

Re:Determine the amount of bytes in a BYTE type buffer

"Maurice Anderson" < XXXX@XXXXX.COM >wrote in message
Quote
>The only thing you can do is to encode the size into 'Buffer' somehow.
>Can you explain why you can't pass the length of the buffer as another
>argument?

>I really will need to see why you don't want to have that extra length
>argument before I'll be able to suggest anything else.

Clayton, thank you for your response.

The reason why I dont want to pass the size as an argument is because I
want to limit the hassle to developer; you see, I am constructing a
Registry Component. So it's a matter of asthetics.

I was hoping there was some sort of function out there that could count
bytes for me.
If you want to pass a buffer by a pointer than you need to listen
to Clayton's suggestions. Why not just use a std::list or vector
and have the function take a reference to it.
 

Re:Determine the amount of bytes in a BYTE type buffer

Quote
Why not just use a std::list or vector and have the function take a
reference to it.
I dont know how to do that.
 

Re:Determine the amount of bytes in a BYTE type buffer

Clayton thanks again for your response and your ideas. Please see below for
some of the answers to your questions.
Quote
this might not be the number the developer intends to write to the
registry.
That is true, but my way would have the developer has to send over the
amount of bytes he really intends to write. I mean what good would it do
for the person to allocate a buffer that holds 1024 bytes but then send only
16? Why would anyone want to do that? Why not simply spend your coding
time sending over what you really intend to write in the 1st place? At the
end of the day, my method would have to do the work to convert and write 16
bytes anyway ...
Quote
In these situations it is best to provide several overloaded versions of
your method
True, but I figure if I use a single function with the lowest denominator
for writing to the registry, then all that you list could be done anyway;
plus it makes for a simpler component all together. One less method in a
class is one less piece of clutter to look at.
As a low-end developer myself, I have found annoying, the inclusion of so
many ways of doing a particular method; with the differences being only a
slight from one variation to the other. For example, take my component, the
developer could easily send over the text in a buffer just as easily as I
could write an over-loaded method for doing the same thing. And from a
philosophical point of view, I have always viewed components as a way to
simplify complex or routine tasks but not necessarily a way to minimize the
developer's coding responsibilities per se. Simplier components equal
greater functionality.
So once again, would you know of a way or have on hand, a function, or have
some code showing how to figure out the number of bytes in a simply buffer?
Thanks
 

Re:Determine the amount of bytes in a BYTE type buffer

Maurice Anderson wrote:
Quote
That is true, but my way would have the developer has to send over the
amount of bytes he really intends to write.
Ok, how is he going to tell you how many he intends to give you?
Quote
I mean what good would it do
for the person to allocate a buffer that holds 1024 bytes but then send only
16? Why would anyone want to do that? Why not simply spend your coding
time sending over what you really intend to write in the 1st place?
Because he has no idea how large it is going to be, or is building in
customization. (It is also easier to be sloppy than to manually count
the bytes)
char buffer[1024];
DWORD bytes_read;
ReadFile( f, buffer, sizeof(buffer), &bytes_read, 0 );
rifp->WriteREG_BINARY("foo", buffer);
How much data was read?
How much are we going to put in the registry?
So now (assuming you succeed in your quest), I have to add
char* extrawork = new char[bytes_read];
memcpy( extra_work, buffer, bytes_read );
rifp->WriteREG_BINARY("foo", extra_work);
delete[]extra_work;
Much simpler to write
rifp->WriteREG_BINARY("foo", buffer, bytes_read );
don't you think?
Quote
So once again, would you know of a way or have on hand, a function, or have
some code showing how to figure out the number of bytes in a simply buffer?
No.
If libraries could read programmers minds, don't you think everyone
would be doing it?
 

Re:Determine the amount of bytes in a BYTE type buffer

Quote
Ok, how is he going to tell you how many he intends to give you?
By passing over a full buffer each and every time - not a partial fill.
Bob, I think you misunderstood my point in this sentence. I wasn't talking
about a byte count argument here, but rather whether or not to send a full
or partially full buffer each and every call.
Quote
Because he has no idea how large it is going to be
Well the original data size or the source of that data is irrelevant to my
component. That's the developer's problem. All my component cares about is
that a full buffer of any size comes through for it to write to the
registry.
Quote
rifp->WriteREG_BINARY("foo", buffer);>How much data was read?
I dont care how much was read into the buffer or by what contraption it is
read into. All I want is a full buffer and a way to read the bytes in the
buffer once it arrives in my component.
Quote
char* extrawork = new char[bytes_read]; memcpy( extra_work, buffer,
bytes_read );
My post didn't imply the developer had to do any extra work. You seem to
think it can't be done without the byte count sent in the buffer as "extra
work". All I said is I wanted to count the bytes i didnt ask for the dev.
to add any count fields to the buffer at all.
Quote
If libraries could read programmers minds, don't you think everyone would
be doing it?
All I want is a full buffer passed and a way to count the bytes in it?
Surely there must be way of doing it. By means of the>>or other bitwise
operators maybe?
 

Re:Determine the amount of bytes in a BYTE type buffer

"Maurice Anderson" < XXXX@XXXXX.COM >wrote in message
Quote
Well the original data size or the source of that data is irrelevant to my
component. That's the developer's problem. All my component cares about
is that a full buffer of any size comes through for it to write to the
registry.
As others have already told you, there is no way to do that without having
more information. How would you propose to count the bytes? i.e., how
would you know when you are done counting? There are only two ways (that I
know of) to do that, and both of them require additional information:
1) The number of bytes must be known ahead of time (by either prepending the
byte count to the data, or via a separate argument), OR
2) If the data permits, a sentinel character (or sequence of characters) at
the end of the data that says, in effect, "this is the end of the data."
Method (1) is used almost exclusively in every computer programming language
ever developed. Method (2) is used very rarely, and it is rare because
there is very often no way to identify the end of the data with a character
(or sequence of characters) whose value(s) cannot also be valid data.
You simply have no choice but to use one or the other (most probably method
1). If you find another way (unless I am missing something obvious), you
would be doing something that expert/genius computer scientists have yet to
discover in over 50 years of computer science.
As an aside, if performance is of any importance at all, it is much faster
to know the data size ahead of time rather than to count it prior to using
it, especially if it is large, which effectively eliminates method (2) and
brings your right back to method (1).
- Dennis
 

Re:Determine the amount of bytes in a BYTE type buffer

Quote
I mean what good would it do for the person to allocate a buffer that
holds 1024 bytes but then send
only 16? Why would anyone want to do that?
It isn't a matter of wanting to do it. Sometimes it is a) easier b) more
efficient c) less code (etc) to set aside a buffer of some maximum size.
Some algorithms require this. For instance, the Windows file system has a
maximum filename size (MAX_PATH):
char filename[MAX_PATH + 1];
// call some API that passes back the name into 'filename'
Quote
True, but I figure if I use a single function with the lowest denominator
for writing to the registry
The lowest common denominator should always provide the most control to the
programmer. Since we've already concluded that there is no way of knowing
how large your buffer is (unless you encode it into the buffer somehow)
there *must* be a length argument for the developer to use.
Quote
As a low-end developer myself, I have found annoying, the inclusion of so
many ways of doing a particular method; with the differences being only a
slight from one variation to the other.
I think you'll find if you dig into those classes the additional behavior is
not superfluous.
Quote
For example, take my component,
the developer could easily send over the text in a buffer just as easily
as I could write an over-loaded method for doing the same thing.
This is a balancing act. For the class you are designing I agree that
overloaded methods don't really help much. The point of writing binary data
is that none of the other types will work (WriteString, WriteInteger,
WriteDate, etc). But consider this: Each of those methods is really an
overloaded method of the concept "WriteData" (aka RegSetValue). What if
TRegistry only provided that one method and made the programmer use it?
void TRegistry::WriteData(String Ident, void* Data, DWORD Length,
DWORD DataType);
There would be "less clutter" but it would effectively make the class
worthless since the programmer would be wasting his/her time looking up
DataType definitions (REG_SZ, etc).
Quote
Simplier components equal greater functionality.
Your job as the class designer is figuring out what is required and what is
gravey.
Quote
So once again, would you know of a way or have on hand, a function, or
have some code showing how to figure out the number of bytes in a simply
buffer?
As I previously answered (and others in this thread), there is no way of
knowing the size of an array of a rudimentary/fundamental data type. That
is one of the reasons why the higher level data types have been created.
They address that issue by encapsulating such details into the class.
- Clayton
 

Re:Determine the amount of bytes in a BYTE type buffer

Clayton, Bob, Dennis, Duane, all you guys are great, thanks for all you
insight and teaching. I think I now understand why one cannot inherently
get a buffer size without a size variable.
The answer is that a buffer is just a pointer to a snapshot of a piece of
memory from a "pile" of memory on the system. Presumably, there is memory
on either side of the buffer block as well, probably filled with bytes of
data as well; maybe even the OS. Therefore, we would need to know where
"our" block in that heap begins and ends. Am I correct?
 

Re:Determine the amount of bytes in a BYTE type buffer

"Maurice Anderson" < XXXX@XXXXX.COM >wrote in message
Quote
Clayton, Bob, Dennis, Duane, all you guys are great, thanks for all you
insight and teaching. I think I now understand why one cannot inherently
get a buffer size without a size variable.



The answer is that a buffer is just a pointer to a snapshot of a piece of
memory from a "pile" of memory on the system. Presumably, there is memory
on either side of the buffer block as well, probably filled with bytes of
data as well; maybe even the OS. Therefore, we would need to know where
"our" block in that heap begins and ends. Am I correct?
Yes, that is basically correct. Memory is just one big mass of bytes. You
could think of memory like a number line, and a pointer like a number on
that line. When memory is allocated to your program, all you get back is a
number (i.e. a pointer), and the amount of memory you've asked for gets
reserved for your use, beginning at that number and continuing for however
many bytes you asked for.
Suppose, for example, that you asked for 10 bytes of memory and the memory
manager gave you back the number 50. All that means is that you have 10
bytes of memory reserved for your use starting at location 50 and continuing
through location 59. Memory before and after your reserved space is not
available for your use, but there is no hard boundary to prevent you from
reading or writing beyond your reserved space. If hard boundaries existed,
then you could read and write to your heart's content until you ran up
against one of those boundaries. However, because that is not the case,
reading or writing beyond the boundaries of the memory reserved for your use
runs the (likely) risk that you will corrupt something in either your
program or in another program.
Now, Windows does have mechanisms in place to help prevent you from reading
or writing memory that is outside your application's memory space. For
instance, any attempt to read or write memory that you do not own will
result in an "access violation." But within your own application's memory
space, you can pretty much read/write anywhere you want to (that is not to
say you *should* however!!), and that is why it is important for you to know
the size of the memory you are working with. As soon as you go outside of
your reserved space, you are in unknown territory and anything can (and
will) happen!
- Dennis