Page 1 of 1

NXC: fopen() vs. OpenFileRead() or CreateFile()

Posted: 14 Feb 2011, 17:04
by HaWe
hi,
is it possible using the ANSI C command fopen(...) in NXC to get a call result (in case of an fopen error) as if using OpenFileRead() or CreateFile() ?

ps: in ANSI C in case of an fopen error NULL will be returned, with NXC I get "1"(strangely) :

Code: Select all

task main(){
  int fhandle;

  fhandle=fopen("no_such.file", "r"); // file open -read
  NumOut(0,0,fhandle);

  while (true);
}

Re: NXC: fopen() vs. OpenFileRead() or CreateFile()

Posted: 15 Feb 2011, 13:55
by HaWe
ps
(and one additional question, perhaps this topic was overlooked:)
I'm not only curious about this return code for a file open error, but also about the filesize issue:

CreateFile() needs a file size to be pre-calculated, fopen ("...", "w") doesn't:
is there no need to have it when using fopen - or where or how has to be done this?

Re: NXC: fopen() vs. OpenFileRead() or CreateFile()

Posted: 15 Feb 2011, 19:59
by afanofosc
I had to look this up in NXCDefs.h, which anyone can do on their own, of course.

Code: Select all

byte fopen(string filename, const string mode) {
  byte handle;
  int fsize;
  switch(mode) {
    case "r" :
      OpenFileRead(filename, fsize, handle);
      break;
    case "w" :
      fsize = 1024;
      CreateFile(filename, fsize, handle);
      break;
    case "a" :
      OpenFileAppend(filename, fsize, handle);
      break;
    default:
      handle = NULL;
  }
  return handle;
}
NULL is #defined to be 0 in NBCCommon.h so you will get 0 if you pass in something other than "r", "w", or "a". But if an error occurs in OpenFileAppend, CreateFile or OpenFileRead the current implementation of this function does not check the return code and set handle to NULL if an error occurs. I should probably change that.

As you can see this function always creates a file that is 1024 bytes long.

John Hansen

Re: NXC: fopen() vs. OpenFileRead() or CreateFile()

Posted: 15 Feb 2011, 20:12
by HaWe
what will happen if my file needs to be 4*512=2048 bytes big and I use fopen?

Re: NXC: fopen() vs. OpenFileRead() or CreateFile()

Posted: 15 Feb 2011, 20:27
by mightor
doc-helmut wrote:what will happen if my file needs to be 4*512=2048 bytes big and I use fopen?
Then you don't use fopen. Pretty easy.

You wouldn't use a fork to eat your soup.

- Xander

Re: NXC: fopen() vs. OpenFileRead() or CreateFile()

Posted: 15 Feb 2011, 20:39
by HaWe
hm. Then I'd prefer to have a "real" spoon (a real C fopen ) and no fork (no "CreateFile") instead. ;)

Re: NXC: fopen() vs. OpenFileRead() or CreateFile()

Posted: 16 Feb 2011, 00:47
by afanofosc
The NXT firmware support for writing to files does not allow you to create the file empty (which the real fopen does) and have it grow magically as you write to it. Instead, the NXT firmware requires that you specify the maximum file size at the time the file is created. So either I would need to have fopen take a file size which it would not use when opening an existing file for reading/appending or I would have it create a file with a default size that you would later need to resize using ResizeFile to whatever size you prefer. Note that there is a fairly serious bug in ResizeFile in the currently available version that has been fixed in the not yet released version of the NXC compiler. I could have an API function that sets the default file size and then use that value in fopen. I'm not totally against that sort of idea. Or you could take the code I posted and write your own ACDC_fopen function that does exactly what you want.

John Hansen

Re: NXC: fopen() vs. OpenFileRead() or CreateFile()

Posted: 16 Feb 2011, 02:25
by muntoo
Temporary fix:

Code: Select all

inline byte fopen(string filename, const string mode, unsigned long fsize=1024) {
  byte handle;
  switch(mode) {
    case "r" :
      OpenFileRead(filename, fsize, handle);
      break;
    case "w" :
      CreateFile(filename, fsize, handle);
      break;
    case "a" :
      OpenFileAppend(filename, fsize, handle);
      break;
    default:
      handle = NULL;
  }
  return handle;
}

Re: NXC: fopen() vs. OpenFileRead() or CreateFile()

Posted: 16 Feb 2011, 07:41
by HaWe
John,
thx for your reply.
I actually had no idea that fopen in NXC is just a workaraound using non-C-keywords - I assumed fopen as the ANSI C keyword was the genuine NXC keyword too.
As NXC-fopen now has no advantages to the non-C keywords CreateFile, FileopenRead, Fileopenwrite I of course may use them as well (the goal is to minimize and standardize the code, not to blow it up (@muntoo... ;))))
The fopen issue (and the same acc to get, put, fget, fput) was only because I sometimes read "real ANSI C code sources" which I then have to change to the NXC tongue when necessary. The less I have to change, the less work has to be done.

But I'm still dreaming of real C stdio input/output streams and functions also for NXC (even if having to change the fw when necessary - my personal ceterum censeo...). ;)

Re: NXC: fopen() vs. OpenFileRead() or CreateFile()

Posted: 16 Feb 2011, 17:39
by spillerrec
You could make your own fopen() which creates a file with fsize=0. Then rewrite the write commands so that it:
  • renames the file
  • creates a new file which size is the renamed file's size + the size of the data you want to write
  • copy the data from the renamed file into this one
  • add the new data
  • delete the renamed file
Done, now you have C-like behavior. Very inefficient, but standardized.