MacOS X + BlitzMax and CopyFile

BlitzMax Forums/BlitzMax Programming/MacOS X + BlitzMax and CopyFile

MacSven(Posted 2011) [#1]
Is it true that i cant copy Files Larger than 2GB under Blitzmax?
And has anyone a solution under MacOS X for this problem!


ima747(Posted 2011) [#2]
Just tried, you can't copy a 3.96gb file, so I would assume the 2GB limit is legit. This was under OS X.

Not sure exactly why that limit might be there, except that there is a similar limit in OS X for copying TO fat32 formatted discs. Not sure if they're related but that's the only thing similar that pops to mind...

A work around would possibly be to pipe the data from one stream to another... open the source file, and write it's contents to the destination. Untested, but I don't think there's a specific file size problem, and since you're streaming the data it's not going to eat the ram or anything...


ima747(Posted 2011) [#3]
Actually, after poking together a test it looks like it's a problem with the copy methods, they don't seem to want to read from something too big... I'm guessing the size blows out a variable.


ima747(Posted 2011) [#4]
Could also be a safety catch to just not have to worry about drive formats that don't support large files (plenty exist). So rather than having to run a drive format test to see if it's allowed they just assumed it wasn't all the time...


TaskMaster(Posted 2011) [#5]
The stream pointers are integers, so they overload at the 2GB limit.

I ran into this problem when making backup software for my company. I ended up calling the Windows API to do all of the File Manipulation like copying, getting the size, date, time, etc...


xlsior(Posted 2011) [#6]
What Taskmaster said.

Blitzmax internally uses normal signed integers for of its operations,
This means that when used as a stream pointer, it overflows once it hits 2GB since the integer can't contain a positive value larger than 2,147,483,647

Using the OS provided API's is the quickest workaround for this limitation...


Volker(Posted 2011) [#7]
Hi MacSeven,

there was a discussion in the german blitz forum:
http://www.blitzforum.de/forum/viewtopic.php?t=35509&highlight=

mpmxyz (I hope it's not his real name) changed the pub.StdC to work with files over 2gb, but he couldn't test it on Mac.


Leon Drake(Posted 2011) [#8]
good ol macs


xlsior(Posted 2011) [#9]
good ol macs


It's not a Mac limitation, it's a blitzmax limitation -- the same thing happens under Windows.


Brucey(Posted 2011) [#10]
... and Linux...

good ol Leon ?


MacSven(Posted 2011) [#11]
I have changed the code from the german blitz forum side, but it should not work.
Have anyone another idea?


xlsior(Posted 2011) [#12]
it should not work (but does), or it doesn't work?


MacSven(Posted 2011) [#13]
Under MacOS X it doesn't work!


SLotman(Posted 2011) [#14]
Have you guys tried to open stream.bmx and change all "int"s to "long"s? That should at least reaise the limit and make the copy with streams work.

Probably one should also change on put.stdc, stdc.bmx this:

Function fread_( buf:Byte Ptr,size,count,c_stream )="fread"
Function fwrite_( buf:Byte Ptr,size,count,c_stream )="fwrite"
Function fflush_( c_stream )="fflush"
Function fseek_( c_stream,offset,origin )="fseek"


to

Function fread_( buf:Byte Ptr,size:long,count:long,c_stream )="fread"
Function fwrite_( buf:Byte Ptr,size:long,count:long,c_stream )="fwrite"
Function fflush_( c_stream )="fflush"
Function fseek_( c_stream,offset:long,origin:long )="fseek"


Just guessing here...

Last edited 2011


MacSven(Posted 2011) [#15]
Tested and doesn't work!


SLotman(Posted 2011) [#16]
Have you rebuilt the modules after making the changes...?


MacSven(Posted 2011) [#17]
Yes!


MacSven(Posted 2011) [#18]
I find something in the Apple Developer Class Reverence, it calles NSFileManager.
I will try to program a module!


MacSven(Posted 2011) [#19]
Found this:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSString* src = @"/Users/xxxxxxx/Desktop/testdir";
NSString* target = @"/Users/xxxxxxx/Desktop/readonlyfilecopy/testdir";
NSError* error = nil;

[[NSFileManager defaultManager] copyItemAtPath:src toPath:target error:&error];

if (error) {
NSLog(@"%@", error);
NSLog(@"%@", [error userInfo]);
}

[pool drain];
return 0;
}

from here:

http://stackoverflow.com/questions/4318406/nsfilemanager-copyitematpathtopatherror-fails-with-read-only-folder

In XCode it works!

And here the NSFilemanager Reference:

http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/NSFileManager_Class.pdf

Last edited 2011

Last edited 2011


MacSven(Posted 2011) [#20]
Need Help!

Trying to build a module:

filesystem64.m

#import <Foundation/NSString.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSPathUtilities.h>
#import <Foundation/NSProcessInfo.h>

int CopyFileLong (NSString* source,NSString* dest){

	printf("Source /S",source);
	printf("Dest   /S",dest);

	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	NSFileManager *fm;
	BOOL isDir;
	NSProcessInfo *proc = [NSProcessInfo processInfo];
	NSArray *args = [proc arguments];
	
	fm = [NSFileManager defaultManager];
	[fm fileExistsAtPath:dest isDirectory:&isDir];
	if (isDir) dest = [dest stringByAppendingPathComponent:[source lastPathComponent]];

	if ([fm isReadableFileAtPath:source] == NO)
	{
		printf("%s => %s (Failed!)\n",[[source lastPathComponent] UTF8String],[dest UTF8String]);
	}
//	[fm removeItemAtPath:dest error:NULL];
	[fm copyItemAtPath:source toPath:dest error:NULL];
	printf("%s => %s (Success!)\n",[[source lastPathComponent] UTF8String],[dest UTF8String]);
    [pool drain];
    return 0;
}


filesystem64.bmx (the module)

Import "filesystem64.m"

Extern
	Function CopyFileLong(src:String,target:String)
EndExtern


if i build the module no error will be happend, after i use it in a bmax app it crashes:

Import macsven.filesystem64

Global src:String="/Volumes/Daten/test"
Global target:String="/Volumes/Medien/test"

copyfileLong src,target


Crashreporter:


Process: test [1098]
Path: /Applications/BlitzMax/mod/macsven.mod/filesystem64.mod/test.app/Contents/MacOS/test
Identifier: test
Version: ??? (???)
Code Type: X86 (Native)
Parent Process: bmk [1088]

Date/Time: 2011-02-28 20:34:39.987 +0100
OS Version: Mac OS X 10.6.6 (10J567)
Report Version: 6

Interval Since Last Report: 948503 sec
Crashes Since Last Report: 51
Per-App Crashes Since Last Report: 15
Anonymous UUID: F9AA795B-8A10-4AB6-AD8A-FD18E54B0B4A

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x000000008215d868
Crashed Thread: 0 Dispatch queue: com.apple.main-thread

Application Specific Information:
objc_msgSend() selector name: length


Thread 0 Crashed: Dispatch queue: com.apple.main-thread
0 libobjc.A.dylib 0x930d8ee4 objc_msgSend + 36
1 test 0x00002bfb CopyFileLong + 203
2 test 0x00002ae2 12 + 222
3 test 0x0000236a 4 + 20
4 test 0x0000249e run + 78
5 com.apple.Foundation 0x903024df _nsnote_callback + 176
6 com.apple.CoreFoundation 0x92ad1793 __CFXNotificationPost + 947
7 com.apple.CoreFoundation 0x92ad119a _CFXNotificationPostNotification + 186
8 com.apple.Foundation 0x902f7384 -[NSNotificationCenter postNotificationName:object:userInfo:] + 128
9 com.apple.Foundation 0x90304789 -[NSNotificationCenter postNotificationName:object:] + 56
10 com.apple.AppKit 0x91991422 -[NSApplication _postDidFinishNotification] + 125
11 com.apple.AppKit 0x91991332 -[NSApplication _sendFinishLaunchingNotification] + 74
12 com.apple.AppKit 0x91ae84ed -[NSApplication(NSAppleEventHandling) _handleAEOpen:] + 274
13 com.apple.AppKit 0x91ae810d -[NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:] + 101
14 com.apple.Foundation 0x903377a4 -[NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:] + 511
15 com.apple.Foundation 0x90337568 _NSAppleEventManagerGenericHandler + 228
16 com.apple.AE 0x9097ef58 aeDispatchAppleEvent(AEDesc const*, AEDesc*, unsigned long, unsigned char*) + 166
17 com.apple.AE 0x9097ee57 dispatchEventAndSendReply(AEDesc const*, AEDesc*) + 43
18 com.apple.AE 0x9097ed61 aeProcessAppleEvent + 197
19 com.apple.HIToolbox 0x93d3e389 AEProcessAppleEvent + 50
20 com.apple.AppKit 0x919619ca _DPSNextEvent + 1420
21 com.apple.AppKit 0x91960fce -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 156
22 com.apple.AppKit 0x91923247 -[NSApplication run] + 821
23 test 0x000029c7 main + 999
24 test 0x00001e59 _start + 208
25 test 0x00001d88 start + 40

Thread 1: Dispatch queue: com.apple.libdispatch-manager
0 libSystem.B.dylib 0x92527982 kevent + 10
1 libSystem.B.dylib 0x9252809c _dispatch_mgr_invoke + 215
2 libSystem.B.dylib 0x92527559 _dispatch_queue_invoke + 163
3 libSystem.B.dylib 0x925272fe _dispatch_worker_thread2 + 240
4 libSystem.B.dylib 0x92526d81 _pthread_wqthread + 390
5 libSystem.B.dylib 0x92526bc6 start_wqthread + 30

Thread 2:
0 libSystem.B.dylib 0x92526a12 __workq_kernreturn + 10
1 libSystem.B.dylib 0x92526fa8 _pthread_wqthread + 941
2 libSystem.B.dylib 0x92526bc6 start_wqthread + 30

Thread 3:
0 libSystem.B.dylib 0x92526a12 __workq_kernreturn + 10
1 libSystem.B.dylib 0x92526fa8 _pthread_wqthread + 941
2 libSystem.B.dylib 0x92526bc6 start_wqthread + 30

Thread 0 crashed with X86 Thread State (32-bit):
eax: 0x0011ebb0 ebx: 0x902fb493 ecx: 0x920f8980 edx: 0x20818040
edi: 0x000fd760 esi: 0xe8e58955 ebp: 0xbfffebf8 esp: 0xbfffe334
ss: 0x0000001f efl: 0x00010202 eip: 0x930d8ee4 cs: 0x00000017
ds: 0x0000001f es: 0x0000001f fs: 0x00000000 gs: 0x00000037
cr2: 0x8215d868

Last edited 2011


Brucey(Posted 2011) [#21]
Have you guys tried to open stream.bmx and change all "int"s to "long"s


int = long

:o)


ima747(Posted 2011) [#22]
filesystem64.m

#import <Foundation/NSFileManager.h>
#import <brl.mod/blitz.mod/blitz.h>

BOOL CopyFileLarge (BBString *source,BBString *dest){
	return [[NSFileManager defaultManager] copyItemAtPath:NSStringFromBBString(source) toPath:NSStringFromBBString(dest) error:NULL];
}


Appologies if making it a 1 liner makes it hard to read.

some syntax errors (case sensitivity), some un-used stuff (try compiling things in XCode, it throws some helpful warnings :0), some un-included stuff (like stdio.h for printf, etc.), and one fatal assumption (NSStrings are not BBStrings, gotta use the blitz conversion function to make them play nice). I also removed the error tests and extension appender because you can/should do that before calling the copy (if I say copy it and drop the extension I don't want the copy function adding it back in) and the NSFileManager will report if it worked or not, if you tell it to copy something that doesn't exist it won't explode, just return a failure. It also returns a BOOL since that's what the file manager returns.

It just copied a 3.78gb dmg disc image (xcode 3.2.5) with no problems.

Also, when working on mixed code I find it easier to build it outside of a module (just a BMX that's doing the extern Function declaration at the top) so I don't have to build (which doesn't give me useful errors most of the time), just compile, debug, recompile. I also edit the alt source in XCode so I get correct syntax highlighting. BMX can handle C alright but for Objective C you're SOL.

I renamed it to CopyFileLarge since file systems supporting files > 2gb are typically referred to as having "large file support". Long to me implies variables of type Long...

Last edited 2011


SLotman(Posted 2011) [#23]
int = long

:o)



From Blitzmax help:
8 bit unsigned integer Byte: 0 to 255 
16 bit unsigned integer Short: 0 to 65535 
32 bit signed integer Int: -2^31 to +2^31-1 
64 bit signed integer Long: -2^63 to +2^63-1 

So Long in bmax is much bigger than ints...
(I know, you probably meant int on bmax = long in C)

Last edited 2011


MacSven(Posted 2011) [#24]
Thanx this is it so simple, and it works!


burpy(Posted 2013) [#25]
I hope Im not too late - Can someone who has made this work explain how I implement it? Im not too hot on interfacing via externs and all that. Thanks


*(Posted 2013) [#26]
Couldnt you just stream data to a bank or load of banks then write the banks to the target file :)