first off im using memory mapping so i can get used to working with memory mapping. any ways im opening up a file(test.txt) and trying to read each line in the buffer one by one and output line seperately into a messagebox. ok here it is:
Posted on 2002-01-15 16:57:51 by smurf
push ecx followed by pop ebx... use a mov instead.

Hrm, your code is a bit confusing. MapViewOfFile gives you a pointer
to the mapped file... you move this *pointer* into your buffer?
And then in the following code you seem to think you've moved
the contents of your file into the buffer... :confused:

I'll give you some pseudocode for handling a memory mapped without
copying first approach.

You'll need a "line buffer" which is large enough to hold the largest
input line you will encounter.

You'll ned a "old linestart" pointer (or index).

Start by setting your oldlinestart to 0 (assuming index).
Go trough the memory mapped file, until you hit 13.

Copy "currentindex - oldlinestart" bytes from "oldlinestart"
into your temp line buffer. Add a trailing 0. Now you have
one full line.

If next char is a 10, skip it.

Set oldlinestart to current index and repeat loop.
Posted on 2002-01-15 17:17:43 by f0dder
So What is your Question? Does it Work? (didnt compile it)

But i can say i see some oddities:

1) "buffer" needs to be only a DWORD since its a pointer to a page of memory (maped by the OS).

2) The File opeing process looks good, as does your code. (interesting approach ~ wierd Push/pop tho). But your closing should be in reverse order to how you opened the mapped file. Ie) Unmap, Close MapHandle, Close File Handle.

3) You *might* be running into problems with memory access rights as well, you try to modify the 13 code temporarily to null. This is fine, but if all else is still not working, make sure your have the creating flags set up to allow you to modify this page of memory (Since the Memory Paging system does intrinsically have bits to limit memory access rights ~ intel's design)

4) Can't hurt to check the handles for NULL to see if they are open... after API calles

Hope this is *some* help.
:alright:
NaN
Posted on 2002-01-15 17:19:35 by NaN

you try to modify the 13 code temporarily to null. This is fine

No, this is *not* fine. It's a very very hacky approach. If he had
read the whole file into a buffer, it would be okay. But causing unnecessary
diskaccess and file modification is *not* okay. Even though the
13->0->13 happens fast enough that the cache system doesn't
write the "0" to the file, the page will still be marked "dirty" and
*will* eventually be written back to disk.
Posted on 2002-01-15 17:25:33 by f0dder
Relax f0dder... /me chuckles at your "modest geniusness" :)

The man is learning something new.. I too would have went with a buffer (not because im thinking about cashes, but rather "tidy" code), but his *attempt* will work, so this is why i said it was "fine". ;)

NaN
Posted on 2002-01-15 18:01:41 by NaN
NaN, if he change the file mapping method, it might work... I'm just
saying it's a bad way to do it, and thus shouldn't be described as
looking good :).

I think I'll try making a little example of how it could be done...
Posted on 2002-01-16 03:44:29 by f0dder
There. It works. If file doesn't end with a blank line, the last line
will not be printed. You should be able to handle that yourself smurf,
it's not too hard. But I'm leaving it as a healthy little excersize for you.
Also, only CRLF is supported, not LF. It could be made to support
CRLF and LF files nicely if you filter out CR and process LF as end-of-line.

Now, since I copy to a temporary buffer, why not just use a big old buffer
and FileRead the entire file? Why not. In this example, it probably wont
matter too much. However, allocating a 100meg buffer to read a file that
will only be parsed in lines... it would probably be better to use filemapping
there. Definitely easier (and probably also have better performance) than
setting up some buffering scheme.
Posted on 2002-01-16 04:12:04 by f0dder
thanks guys.

well fodder i will be working with large files so i will need to do "filemapping". how would im implement it into the sample code you have provided already?
Posted on 2002-01-16 12:04:23 by smurf
Off the top of my head:

    [*] Open File Mapping (as you have done)
    [*] set two address pointers to the beginning
    [*] Use Instring Or Hutch's search algo, or even you own, to find the first instance of "13", starting from the second address pointer
    [*] Do basic EOF checking and no more instnaces of 13 checks
    [*] subtract the two address to get the lenght
    [*] memcopy into a buffer of a large enough length the from the first address pointer, up to the length calculated
    [*] inc over the 13 code on the second addr pointer
    [*] save this into the first addr pointer as well (move it up)
    [*] display string in message box from buffer
    [*] loop back to the third point


    Close down file mapping when all done...
    This looks long but it really isnt. I stuck in the basic EOF and 13 checks, as close as it should be, but in real code this may not necessarily be on one spot or even one tight "block". Just dont forget to do this in general. :)

    Anywho This is how i would do it.. To be honest, i have an OOP class that does all this for you called CFile. But i havent posted it yet cause i need to "comment" it thu. But if you think you would want to use the model, i will move on this... (It simplifies the above and much more into one line, kinda like an API)

    NaN
Posted on 2002-01-16 14:34:41 by NaN
Here is the sample code i made to test its out (uses a String Class too (CString), which allows you to dynamically create string buffers with the same amount of ease):



.data
LoadStr db "openme.txt",0



hInstance HINSTANCE ?
CommandLine LPSTR ?

hFile dd ?
hString dd ?


TEMP dd ?

.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax


mov TEMP, 64
mov hString, $NEWOBJECT( CString, TEMP)

mov hFile, $NEWOBJECT( CFile, addr LoadStr, CFILE_READ )
METHOD hFile, CFile, SetLineSize, 64

METHOD hString, CString, FillString, $METHOD( hFile, CFile, ReadLine )
mov ecx, $METHOD( hFile, CFile, ReadLine )

invoke MessageBox, NULL, ecx, $METHOD( hString, CString, Address ), MB_OK

DESTROY hFile
DESTROY hString


invoke ExitProcess,eax
end start


The example opens a File Maping to a text file, loads the first line of text into the string buffer, then loads the second line of text and places the pointer to ECX, then calls messagebox. I didnt loop or anything, but it would be easy to add it in.

One of the neat things is the fifth line:
METHOD hString, CString, FillString, $METHOD( hFile, CFile, ReadLine )

Does essentiall what my above post outlines. It Reads the next line of text (64 bytes max) and saves it into a buffer (hString) by using the buffer's instance method FillString. The $xx are inline commads (which allow this to happen).

NaN
Posted on 2002-01-16 14:52:28 by NaN