views:

73

answers:

2

Hi, I am working in 64 bit x_86 64 bit OSX system.

I am reading the file of legacy database. It is loaded to a memory block and using offsets it read to the structures. It is written in 32 bit mode.

So in order to read properly in 64 bit mode, I want to add n bytes to the base address of a structure.

Since pointer incement

increment does not help me to do it As it is in 64 bit mode every pointer is b byte long.

Regards, Dhana.

I have posted some code here. I guess it is right..

   struct CamNodeTag { 
          CamNodeTag  *nextCam; // next cam
          SInt32 numMake; 
          char  *menuMake; 
    }; 

    long pBaseAddr; // this is long so we an offset bytes from it.

    //Get the size of of the structure in 32 bit environment.//in 64 bit envi it is 20 bytes.
    int CamNodeTagSizeIn32BitMode = 12;


    //Do it in a while loop..
 int i=0;
 CamNodeTag * pNode = (CamNodeTag *)(pBaseAddr + i*CamNodeTagSizeIn32BitMode);

while(pNode !=NULL)
{
    //Do the cam stuff here..

// to get the next node, we add the base addr to the offset


//This will give next cam
 i++;
   pNode = (CamNodeTag *)(pBaseAddr + i*CamNodeTagSizeIn32BitMode);

}
+1  A: 

I recommend instead that you read the file from disk using functions that you write such as read_uint32_whatever_endian(FILE*) and such, and store these in your new 64bit in-memory structs.

This insulates your new code from the choices the compiler makes about the memory layout of your structures.

On a modern machine, the performance cost of such parsing is so minimal that I am sure you can hardly measure it.

Whilst there is a slight corner-case where nmaped large database files that store the same binary structure as the compiler's in-memory representation is a plus, this case is not worth much in practice.

The benefits of a different serialisation on disk to in memory provide plenty of practical pluses:

  • it's portable - you can run your code on different processors with different word-sizes and different endians without issues
  • you can extend the structures at any time - you could make the in-memory structures into objects with methods and such, even virtual C++ methods, and other benefits of object oriented design; you can also add members that don't get serialised, such as pointers and other fields, and you can support new database file versions easily
Will
Issue here is i did not create or wrote this file. And this is a read only file .
Dhanaraj
@Dhanaraj: What Will is suggesting is an encapsulation of how you *read* your data, there is no writing involved.
unwind
+1  A: 

In order to advance a pointer by something other than it's native size, you have to cast to char *.

To read from a file that uses 32 bit values as "pointers" using a 64 bit processor, you have to redefine your structures so that fields that used to be pointers are still 32 bits in size.

typedef int Off32; // our "pointers" need to be 32 bit ints rather than pointers.

struct CamNodeTag { 
   Off32  nextCam; // next cam
   SInt32 numMake; 
   Off32  menuMake; 
}; 

char * pBaseAddr; // this is char * so we an offset bytes from it.

// set this to point to the first node.
CamNodeTag * pNode = (CamNodeTag *)(pBaseAddr + first_node_offset);

// to get the next node, we add the base addr to the offset
// in the structure.

pNode = (CamNodeTag *)(pBaseAddr + pNode->nextCam);

// assuming that the menuMake pointer is also an offset from the base
// use this code to get the actual pointer.
//
char * pMenu = (pBaseAddr + pNode->menuMake);
John Knoeller
Sorry i am unable indent this code in comment section..char * (Or any pointer) takes 8 bytes in 64 bit system.CamNodeTag * pNode = (CamNodeTag *)(pBaseAddr + first_node_offset);Here it is like ((CamNodeTag *)(pBaseAddr + (first_node_offset*8bytes));So instead long baseAddr = (long) pBaseAddr;then((CamNodeTag *)(baseAddr + first_node_offset);It should work fine.
Dhanaraj
@Dhanaraj: you can edit your original post.
John Knoeller