Portability of this snipplet

B

brandon

Note: I'm not very familiar with C++, only C.
The following description and code snippet are from
http://freedos-32.sourceforge.net/lean/specification.php
It's about calculating the checksum for a LEAN file system structure.

"...The sensitive structure must be cast to an array of 32-bit unsigned
integers, then each element of this array must be summed, rotating the
sum one bit to right at every iteration... The data parameter is a
pointer to the sensitive structure, including the checksum field in its
first 4 bytes. The size parameter is the size in bytes of the structure
pointed by data, including the 4 bytes for the checksum field... The
function skips the first 4 bytes when computing the checksum."

uint32_t computeChecksum(const void* data, size_t size)
{
uint32_t res = 0;
const uint32_t* d = static_cast<const uint32_t*>(data);
assert((size & (sizeof(uint32_t) - 1)) == 0);
size /= sizeof(uint32_t);
for (size_t i = 1; i != size; ++i) res = (res << 31) + (res >> 1)
+ d;
return res;
}

The structure consists of uint32_t's and uint64_t's. Doesn't this snippet
rely on the structure being stored in memory in a particular, machine/
compiler specific way (e.g. endianness)?
Thanks.
 
J

Jorgen Grahn

Note: I'm not very familiar with C++, only C.
The following description and code snippet are from
http://freedos-32.sourceforge.net/lean/specification.php
It's about calculating the checksum for a LEAN file system structure.

"...The sensitive structure must be cast to an array of 32-bit unsigned
integers, then each element of this array must be summed, rotating the
sum one bit to right at every iteration... The data parameter is a
pointer to the sensitive structure, including the checksum field in its
first 4 bytes. The size parameter is the size in bytes of the structure
pointed by data, including the 4 bytes for the checksum field... The
function skips the first 4 bytes when computing the checksum."

uint32_t computeChecksum(const void* data, size_t size)
{
uint32_t res = 0;
const uint32_t* d = static_cast<const uint32_t*>(data);
assert((size & (sizeof(uint32_t) - 1)) == 0);
size /= sizeof(uint32_t);
for (size_t i = 1; i != size; ++i) res = (res << 31) + (res >> 1)
+ d;
return res;
}

The structure consists of uint32_t's and uint64_t's. Doesn't this snippet
rely on the structure being stored in memory in a particular, machine/
compiler specific way (e.g. endianness)?
Thanks.


Don't know about that, but one obvious thing is that 'data' needs to
be properly aligned. On some (most?) architectures, reading words from
odd addresses will cause a crash. On others, it will be really, really
slow.

/Jorgen
 
B

Bo Persson

brandon said:
Note: I'm not very familiar with C++, only C.
The following description and code snippet are from
http://freedos-32.sourceforge.net/lean/specification.php
It's about calculating the checksum for a LEAN file system
structure.

"...The sensitive structure must be cast to an array of 32-bit
unsigned integers, then each element of this array must be summed,
rotating the sum one bit to right at every iteration... The data
parameter is a pointer to the sensitive structure, including the
checksum field in its first 4 bytes. The size parameter is the size
in bytes of the structure pointed by data, including the 4 bytes
for the checksum field... The function skips the first 4 bytes when
computing the checksum."

uint32_t computeChecksum(const void* data, size_t size)
{
uint32_t res = 0;
const uint32_t* d = static_cast<const uint32_t*>(data);
assert((size & (sizeof(uint32_t) - 1)) == 0);
size /= sizeof(uint32_t);
for (size_t i = 1; i != size; ++i) res = (res << 31) + (res >> 1)
+ d;
return res;
}

The structure consists of uint32_t's and uint64_t's. Doesn't this
snippet rely on the structure being stored in memory in a
particular, machine/ compiler specific way (e.g. endianness)?
Thanks.


It does depend on how the 'data' was stored - as single bytes or as
32-bit values. Are you reding the same way they were stored? It will
definitely not be read the same way on all systems having a 32 bit
integer type.

The code also depends on the system actually having a unit32_t data
type, which is optional. Perhaps not a big problem for a product
called freedos-32? :)


Bo Persson
 
B

brandon

brandon said:
Note: I'm not very familiar with C++, only C. The following description
and code snippet are from
http://freedos-32.sourceforge.net/lean/specification.php It's about
calculating the checksum for a LEAN file system structure.

"...The sensitive structure must be cast to an array of 32-bit unsigned
integers, then each element of this array must be summed, rotating the
sum one bit to right at every iteration... The data parameter is a
pointer to the sensitive structure, including the checksum field in its
first 4 bytes. The size parameter is the size in bytes of the structure
pointed by data, including the 4 bytes for the checksum field... The
function skips the first 4 bytes when computing the checksum."

uint32_t computeChecksum(const void* data, size_t size) {
uint32_t res = 0;
const uint32_t* d = static_cast<const uint32_t*>(data); assert((size &
(sizeof(uint32_t) - 1)) == 0); size /= sizeof(uint32_t);
for (size_t i = 1; i != size; ++i) res = (res << 31) + (res >> 1) +
d;
return res;
}

The structure consists of uint32_t's and uint64_t's. Doesn't this
snippet rely on the structure being stored in memory in a particular,
machine/ compiler specific way (e.g. endianness)? Thanks.


It does depend on how the 'data' was stored - as single bytes or as
32-bit values. Are you reding the same way they were stored? It will
definitely not be read the same way on all systems having a 32 bit
integer type.

The code also depends on the system actually having a unit32_t data
type, which is optional. Perhaps not a big problem for a product called
freedos-32? :)


Bo Persson


Alright, I guess I have to create a function for each structure that will
dump them into an array. From there I can calculate the checksum, and
directly write the structure to the disk. Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top