Announcement

Collapse
No announcement yet.

Some quick ideas on a CPP port

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Some quick ideas on a CPP port

    Hey again.

    Had such a great response on my last question so I thought I'd try it again.

    Currently porting some C++ code into PB... but I'm kind stuck.
    What the code does is to read some data from a shared memory of another program (not my program)
    and also edit that programs user files.. lock it, edit and then release it.

    Got the easy part ported, but I'm stuck at the point hwere I'm suppose to get data from the 'database'.

    I'll post the code and if some old C++ coder could take a look at the code and help me out I'd be grateful.

    Code:
    #include "stdafx.h"
    
    
    typedef struct _DATAITEM
    {
    	UINT	Uid;
    	UINT	Gid;
    	UINT	Mode;
    	UINT	Crc32;
    
    	PCHAR	FileName;
    	UINT	l_FileName;
    	UINT	Hash;
    
    	LPVOID	Context;
    	UINT	l_Context;
    
    } DATAITEM, * LPDATAITEM, ** DATABASE;
    
    HANDLE	pHeap;
    
    
    UINT Database_Read(HANDLE FileHandle, DATABASE *lpDataBase)
    {
    	LPDATAITEM	DataItem;
    	DATABASE	DataBase;
    	DWORD		Read;
    	PUINT		Table, Offset;
    	UINT		l_FileName, l_Context;
    	UINT		i_Size, b_Size, db_Size, db_Version, b_Crc32, t_Size, i_Read;
    
    
    	t_Size		= 512;
    	i_Read		= 0;
    	Table		= (PUINT)HeapAlloc(pHeap, NULL, t_Size * sizeof(UINT));
    	*lpDataBase	= NULL;
    
    	if (! Table)
    	{
    		// Could not allocate memory
    		return 0;
    	}
    
    	if (! ReadFile(FileHandle, Table,2 * sizeof(UINT), &Read ,NULL))
    	{
    		// Could not read from file
    		goto CLEANUP;
    	}
    
    	db_Version	= Table[0];
    	db_Size		= Table[1];
    
    	if (db_Version != 0)
    	{
    		//	Current database version is always zero
    		goto CLEANUP;
    	}
    
    	DataBase	= (DATABASE)HeapAlloc(pHeap, NULL, sizeof(LPDATAITEM) * db_Size);
    
    	if (! DataBase)
    	{
    		//	Could not allocate enough memory
    		goto CLEANUP;
    	}
    
    	for (; <IMG SRC="http://www.powerbasic.com/support/forums/wink.gif" ALT="wink">
    	{
    		if (! ReadFile(FileHandle, Table, 2 * sizeof(UINT), &Read, NULL) &#0124; &#0124; Read != 2 * sizeof(UINT))
    		{
    			// Could not read (enough?)
    			break;
    		}
    
    		// Get block size
    		b_Size	= Table[0];
    		// Get block crc32
    		b_Crc32	= Table[1];
    		//	Reduce block size (Block size & Crc variables are included in block size)
    		b_Size	-= sizeof(UINT) * 2;
    
    		if (b_Size > (t_Size * sizeof(UINT)))
    		{
    			t_Size	= b_Size / sizeof(UINT) + 10;
    			//	Free memory
    			HeapFree(pHeap, NULL, Table);
    			//	Allocate memory
    			Table	= (PUINT)HeapAlloc(pHeap, NULL, t_Size * sizeof(UINT));
    
    			if (! Table)
    			{
    				// Could not allocate memory
    				break;
    			}
    		}
    
    		if (! ReadFile(FileHandle, Table, b_Size, &Read, NULL) &#0124; &#0124; Read != b_Size)
    		{
    			// Could not read (enough?)
    			break;
    		}
    
    		// Here we could calculate crc32 for the block and compare it against stored crc
    		for (Offset=Table;b_Size;b_Size -= i_Size)
    		{
    			i_Size		= Offset[0];
    			l_FileName	= Offset[1];
    			l_Context	= i_Size - l_FileName - 7 * sizeof(UINT);
    
    			//	Allocate new entry in database
    			DataItem	= (LPDATAITEM)HeapAlloc(pHeap, NULL, sizeof(DATAITEM) + l_FileName + l_Context);
    
    			if (! DataItem)
    			{
    				//	Could not allocate memory
    				break;
    			}
    
    			DataBase[i_Read++]	= DataItem;
    			//	Initialize pointers
    			DataItem->FileName	= (PCHAR)&DataItem[1];
    			DataItem->Context	= (LPVOID)((ULONG)&DataItem[1] + l_FileName);
    			//	Copy contents
    			DataItem->Uid			= Offset[2];
    			DataItem->Gid			= Offset[3];
    			DataItem->Mode			= Offset[4];
    			DataItem->Crc32			= Offset[5];
    			DataItem->Hash			= Offset[6];
    			DataItem->l_FileName	= l_FileName;
    			DataItem->l_Context		= l_Context;
    			//	FileName does not get zero padding
    			CopyMemory(DataItem->FileName, (PCHAR)&Offset[7], l_FileName);
    			CopyMemory(DataItem->Context, (LPVOID)((ULONG)&Offset[7] + l_FileName), l_Context);
    
    			// Move offset
    			Offset		= (PUINT)((ULONG)Offset + i_Size);
    		}
    	}
    
    	//	Set pointer
    	*lpDataBase	= DataBase;
    
    CLEANUP:
    	HeapFree(pHeap, NULL, Table);
    	return i_Read;
    }
    
    VOID Database_Free(DATABASE DataBase, DWORD Size)
    {
    	//	Free memory
    	while (Size--)
    	{
    		HeapFree(pHeap, NULL, DataBase[Size]);
    	}
    	HeapFree(pHeap, NULL, DataBase);
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
    	DATABASE	DataBase;
    	HANDLE		FileHandle;
    	PCHAR		FileName;
    	UINT		Size;
    
    	pHeap		= GetProcessHeap();
    	FileName	= "d:\\path\\to\\site\\home\\.THEFILE";
    
    	FileHandle	= CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
    		OPEN_EXISTING, NULL, NULL);
    
    	if (FileHandle != INVALID_HANDLE_VALUE)
    	{
    		//	We should lock file here
    		Size	= Database_Read(FileHandle, &DataBase);
    		//	And unlock it here
    		CloseHandle(FileHandle);
    		//	Use database here
    		if (Size) MessageBox(NULL, "YEP", "GOD YOU ARE", NULL);	
    		//	Free database
    		Database_Free(DataBase, Size);
    	}
    	return 0;
    }
    I got some of the code ported.. but since I can't get it to get any info from the code it's more or less useless.
    Any help would be appreciated.

    (If I wasn't clear enough I'd like some help on how to read the data UID, GID, MODE, HASH and all the other info)


    ----------------
    Dennis

    ------------------

  • #2
    Don't know much C++, but can always guess wildly: <IMG SRC="http://www.powerbasic.com/support/forums/smile.gif" ALT="smile">

    UINT = Unsigned 32-bit Integer = DWORD in PB.

    PUINT = DWORD PTR.

    "db_Version = Table[0]" should become "db_Version = @Table[0]", since
    Table is declared as DWORD PTR.

    PCHAR = ASCIIZ, but since no length is given, I don't know - maybe
    FileName AS ASCIIZ * %MAX_PATH ? Or ASCIIZ PTR?

    "typedef struct _DATAITEM" = TYPE DATAITEM

    "} DATAITEM, * LPDATAITEM, ** DATABASE;" = END TYPE

    "HANDLE pHeap;" is probably GLOBAL pHeap AS DWORD.

    Some variables need to be renamed. "Read" is a PB keyword, so rename to
    something like "dwRead" instead.

    DataItem should be DATAITEM PTR and lpDataBase seems to be DATABASE PTR.
    But "DataBase AS DATABASE" will fail, so rename, like "dBase AS DATABASE".

    DataItem->FileName is a member in the DATAITEM structure - in PB it looks
    like DataItem.FileName.

    "if (! DataItem)" = "IF NOT DataItem THEN"

    sizeof(UINT) is 4 (bytes). Don't think we can do SIZEOF(DWORD) in PB,
    but safe enough to hard-code 4 there.. <IMG SRC="http://www.powerbasic.com/support/forums/smile.gif" ALT="smile">

    Function calls like HeapAlloc and ReadFile, etc, have been used enough
    many times in codes around here, so easy enough to search for them to
    see how they looks in PB.

    ULONG is a funny one. Never seen that before, but should be same as
    UINT = DWORD. I guess..


    ------------------
    http://www.tolkenxp.com/pb
    Download: incLean, PBcodec, custom controls and code, etc.
    Borje Hagsten - [email protected]



    [This message has been edited by Borje Hagsten (edited May 26, 2003).]

    Comment


    • #3
      Thanks Borje (tack)

      I got a bit further with the declarations now.
      Haven't tried all of the stuff you posted but I will as soon as I 'wake up'.


      ------------------
      Dennis

      ------------------

      Comment


      • #4
        What the code does is to read some data from a shared memory of another program
        Looks like it's reading a mailslot..regular BASIC language file access functions should be able to do this job in about one-tenth the number of code lines.

        (Let me wake up a little, too, but don't start converting this verb-for-verb just yet).

        Later...

        Nah, it's just reading a disk file (those double-backslashes had me going for a minute) and returning an array of dataitem UDTs.

        BASIC code something like..
        Code:
          hFILE    = FreeFile
          OPEN thefile for BINARY as hfile BASE=0
          SEEK hFile, 0
          GET$ hFile, LOF(hFile), W$
          nRecords = LEN(W$)\ SIZEOF(dataitem)
          REDIM  items (nRecords-1) AS dataitem AT STRPTR(W$)
          ...
        You'll have to add back that database 'version' checking, but let the PB compiler handle all the memory allocation.. it will make your job a lot easier..

        MCM




        [This message has been edited by Michael Mattias (edited May 26, 2003).]
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Thank you Michael.

          I tried your snippet out and I think I got all the declarations out but
          I think I could use some more help on how to get it to work.

          So if you don't my guiding my through it I'd really appreciate it.


          -----------------_
          Dennis

          ------------------

          Comment


          • #6
            I think I could use some more help on how to get it to work.
            Can't "get it to work" unless we know "what it is supposed to do."

            FWIW, I am a long-time critic of "verb-for-verb" conversions. I think this method(?) of porting is a Loser.

            In this case, you can replace about 50 lines of 'C' code with about 10 lines of BASIC code and not have to worry about de-allocating the memory you need - the compiler will handle that. Sounds like you are already way ahead.

            Once you have the items() array, any place the rest of the application references "pHeap" (pointer to start of array data) you use VARPTR(items(0))

            My example uses an ABSOLUTE array (DIM ..AT..); you might be more comfy creating a BASIC array the "conventional" way and working with that.

            MCM




            [This message has been edited by Michael Mattias (edited May 27, 2003).]
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment

            Working...
            X