1. 64 bit integers (accessing files > 4Gb)

How do I access file data > 4Gb?

The Windows API has SetFilePointerEx() but it requires large integers.
Is it possible to deal with large ints in Eu using atoms?

Chris Bensler
~ The difference between ordinary and extraordinary is that little extra ~
http://empire.iwireweb.com - Empire for Euphoria

new topic     » topic index » view message » categorize

2. Re: 64 bit integers (accessing files > 4Gb)

Chris Bensler wrote:
> 
> How do I access file data > 4Gb?
> 
> The Windows API has SetFilePointerEx() but it requires large integers.
> Is it possible to deal with large ints in Eu using atoms?
> 
> Chris Bensler
> ~ The difference between ordinary and extraordinary is that little extra ~
> <a href="http://empire.iwireweb.com">http://empire.iwireweb.com</a> - Empire
> for Euphoria

I didn't test this, but....

In the wrapper for your routine, replace the large_integer by a C_LONG and 
a C_ULONG. Then, pass the high dword in the C_LONG and the low dword in the 
C_LONG, both using atoms as usual. This results in

constant kernel32=open_dll("kernel32.dll"),
sfpx=define_c_func(kernel32,"SetFilePointerEx",
  {C_POINTER,C_LONG,C_ULONG,C_POINTER,C_ULONG},C_BOOL)


You'd pass 5 atoms to c_func() when calling the function. You'd also 
poke4() 2 atoms at the place pointed to by the 4th arg, which is the
lpNewFilePointer parameter. 

If the large integer is pushed on the stack, which I expect on 32 bit 
machines, this hack should work, since it generates the stack layout the 
routine expects. Perhaps using a "+" to force a _cdecl call is safer. 
Again, I haven't tested this...

HTH
CChris

new topic     » goto parent     » topic index » view message » categorize

3. Re: 64 bit integers (accessing files > 4Gb)

CChris wrote:
> 
> Chris Bensler wrote:
> > 
> > How do I access file data > 4Gb?
> > 
> > The Windows API has SetFilePointerEx() but it requires large integers.
> > Is it possible to deal with large ints in Eu using atoms?
> > 
> 
> I didn't test this, but....
> 
> In the wrapper for your routine, replace the large_integer by a C_LONG and 
> a C_ULONG. Then, pass the high dword in the C_LONG and the low dword in the
> 
> C_LONG, both using atoms as usual. This results in
> 
> }}}
<eucode>
> constant kernel32=open_dll("kernel32.dll"),
> sfpx=define_c_func(kernel32,"SetFilePointerEx",
>   {C_POINTER,C_LONG,C_ULONG,C_POINTER,C_ULONG},C_BOOL)
> </eucode>
{{{

> 
> You'd pass 5 atoms to c_func() when calling the function. You'd also 
> poke4() 2 atoms at the place pointed to by the 4th arg, which is the
> lpNewFilePointer parameter. 
> 
> If the large integer is pushed on the stack, which I expect on 32 bit 
> machines, this hack should work, since it generates the stack layout the 
> routine expects. Perhaps using a "+" to force a _cdecl call is safer. 
> Again, I haven't tested this...

No, definitely do *not* use cdecl for calling the Win32 API.  Otherwise,
your directions are correct.  I've used these functions before, and you
can simply break up the LARGE_INTEGER into two 32-bit integers.  You
just have to 'manually' do the 64-bit math and increment the high
dword yourself.

Matt

new topic     » goto parent     » topic index » view message » categorize

4. Re: 64 bit integers (accessing files > 4Gb)

Chris Bensler wrote:
> 
> How do I access file data > 4Gb?
> 
> The Windows API has SetFilePointerEx() but it requires large integers.
> Is it possible to deal with large ints in Eu using atoms?
> 
> Chris Bensler
> ~ The difference between ordinary and extraordinary is that little extra ~
> <a href="http://empire.iwireweb.com">http://empire.iwireweb.com</a> - Empire
> for Euphoria

I replied too fast:

Since C pushes args right to left, the high dword of the large integer 
should be in the third argument, and the low dword in the second argument.

CChris

new topic     » goto parent     » topic index » view message » categorize

5. Re: 64 bit integers (accessing files > 4Gb)

Matt Lewis wrote:
> 
> CChris wrote:
> > 
> No, definitely do *not* use cdecl for calling the Win32 API.  Otherwise,
> your directions are correct.  I've used these functions before, and you
> can simply break up the LARGE_INTEGER into two 32-bit integers.  You
> just have to 'manually' do the 64-bit math and increment the high
> dword yourself.

Thanks guys. That's what I thought. I already implemented that method before
posting and it apeared to work, but I have no files large enough to verify.

Will an atom sufficiently store a large integer without loss of accuracy?
I'd rather not have to deal with increments.
Some basic testing shows that an atom will accurately store integer values up to
about 8 or 9 Petabytes.

Another question.
I assumed that remainder(li,#100000000) would result in the lo dword, but
apparently not. Is that bit of code wrong? Does remainder() not handle values
that large? lo_word = remainder(long,#10000) works.

lo = li - (hi*#100000000) seems to be correct, but requires first calculating
the hi dword.

Last Q:
Is the lo dword signed or is the high dword?


Chris Bensler
~ The difference between ordinary and extraordinary is that little extra ~
http://empire.iwireweb.com - Empire for Euphoria

new topic     » goto parent     » topic index » view message » categorize

6. Re: 64 bit integers (accessing files > 4Gb)

Chris Bensler wrote:
> 
> Matt Lewis wrote:
> > 
> > CChris wrote:
> > > 
> > No, definitely do *not* use cdecl for calling the Win32 API.  Otherwise,
> > your directions are correct.  I've used these functions before, and you
> > can simply break up the LARGE_INTEGER into two 32-bit integers.  You
> > just have to 'manually' do the 64-bit math and increment the high
> > dword yourself.
> 
> Thanks guys. That's what I thought. I already implemented that method before
> posting and it apeared to work, but I have no files large enough to verify.
> 
> Will an atom sufficiently store a large integer without loss of accuracy?
> I'd rather not have to deal with increments.
> Some basic testing shows that an atom will accurately store integer values up
> to about 8 or 9 Petabytes.
> 

Up to power(2,53)-1, the answer is yes.
However, SetFilePointerEx() won't understand if you pass it a double.

> Another question.
> I assumed that remainder(li,#100000000) would result in the lo dword, but
> apparently
> not. Is that bit of code wrong? Does remainder() not handle values that large?
> lo_word = remainder(long,#10000) works.
> 
> lo = li - (hi*#100000000) seems to be correct, but requires first calculating
> the hi dword.
> 
> Last Q:
> Is the lo dword signed or is the high dword?
> 

Both. In 16 bit world, -4 is FFFC: FF is signed (-1) and FC is signed (-4).
Same in 64 bit world with more bits.

CChris

> 
> Chris Bensler
> ~ The difference between ordinary and extraordinary is that little extra ~
> <a href="http://empire.iwireweb.com">http://empire.iwireweb.com</a> - Empire
> for Euphoria

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu