Shop OBEX P1 Docs P2 Docs Learn Events
fsrw — Parallax Forums

fsrw

Dave HeinDave Hein Posts: 6,347
edited 2010-04-29 02:53 in Propeller 1
I have been working with fsrw 2.6, and it has been working nicely.· There are a few things that I would like to do with it, but it doesn't seem to support· some of the functions I would like to do.

The directory function nextfile returns the file name, but I would also like to get the file size for a directory listing.· It seems like the only way to do this is to first get all the file names, and then open each one·individually to get the file size.· Is there an easier way to to that?

fsrw only allows one file to be open at a time.· I noticed that some of the variables and a buffer are in a VAR section, and other variables and another buffer are in the DAT section.· In theory, I could have multiple instances of the fsrw VAR sections.· Would this allow for multiple files to be opened at the same time?· Has anybody made a version of fsrw that uses a pointer to a "struct" containing the variables and buffers?· This would allow for multiple opened files.

Has anybody done subdirectories with fsrw?· That would be a nice feature also.

Dave

Comments

  • lonesocklonesock Posts: 917
    edited 2010-04-27 20:29
    FSRW 2.6 does support multiple files at once. Just declare an array of FSRW object, and mount the first one. That is how you would check the filesize in a directory as well.

    ' opening the dir is just like opening a file
        sdfat.opendir
        repeat while 0 == sdfat.nextfile(@tbuf)
          ' show the filename
          term.str( @tbuf )
          repeat 15 - strsize( @tbuf )
            term.tx( " " )
          ' so I need a second file to open and query filesize
          sdfat[noparse][[/noparse] 1 ].popen( @tbuf, "r" )
          term.dec( sdfat[noparse][[/noparse] 1 ].get_filesize )
          sdfat[noparse][[/noparse] 1 ].pclose      
          term.str( string( " bytes", $0D ) )
    



    FSRW does not currently support subdirectories.

    Jonathan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • KyeKye Posts: 2,200
    edited 2010-04-27 20:33
    In four weeks. Your wishes will come true.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • lonesocklonesock Posts: 917
    edited 2010-04-27 20:52
    Kye said...
    In four weeks. Your wishes will come true.
    Firefly is back on the air?!? [noparse][[/noparse]8^)

    Seriously, though, Kye does good work, and he's working on a FAT16/32 driver as well. I'm currently working on the FSRW block driver (in my spare time wink.gif to make a minimal version (size-wise), without sacrificing much in the way of speed.

    Jonathan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-04-27 22:24
    lonesock said...
    Firefly is back on the air?!? [noparse][[/noparse]8^)

    I thought I was the only one still holding that grudge! -- I still raise a fist in anger when I drive by the FOX lot...

    Thanks for the tip on multiple files with FSRW.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • FMMT666FMMT666 Posts: 14
    edited 2010-04-27 22:35
    Kye said...
    In four weeks. Your wishes will come true.

    Well, this sounds promising...
    Kye, tell us more =)


    Axel
  • rokickirokicki Posts: 1,000
    edited 2010-04-27 23:22
    It would be pretty easy to pick up the size (and other attributes) during nextfile(). Just look at the layout
    (see the Wikipedia entry for FAT), and look at what next file does (reads 32 bytes, probably), and then
    figure out how to find the file size from the 32-byte directory entry.
  • KyeKye Posts: 2,200
    edited 2010-04-28 00:57
    @FMMT666 - Refer to http://forums.parallax.com/forums/default.aspx?f=25&m=416556

    However, that version is still buggy. I'll be releasing a better version in about 4 weeks give or take.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-04-28 21:07
    Rokicki said...
    It would be pretty easy to pick up the size (and other attributes) during nextfile(). Just look at the layout
    (see the Wikipedia entry for FAT), and look at what next file does (reads 32 bytes, probably), and then
    figure out how to find the file size from the 32-byte directory entry.I looked at the directory format, and it does look pretty straight-forward.· I'll change the nextfile method to return the filesize and attribute bits.
    I looked at the directory format, and it does look pretty straight-forward.· I'll change the nextfile method to return the filesize and attribute bits.

    lonesock said...
    FSRW 2.6 does support multiple files at once. Just declare an array of FSRW object, and mount the first one. That is how you would check the filesize in a directory as well.

    ' opening the dir is just like opening a file
        sdfat.opendir
        repeat while 0 == sdfat.nextfile(@tbuf)
          ' show the filename
          term.str( @tbuf )
          repeat 15 - strsize( @tbuf )
            term.tx( " " )
          ' so I need a second file to open and query filesize
          sdfat[noparse][[/noparse] 1 ].popen( @tbuf, "r" )
          term.dec( sdfat[noparse][[/noparse] 1 ].get_filesize )
          sdfat[noparse][[/noparse] 1 ].pclose      
          term.str( string( " bytes", $0D ) )
    


    Thanks for the tip on using multiple instances of FSRW.· I'll give it a try.· In reading the FSRW code it looks like the VAR data should be initialized to zero before using the second instance.· However, I believe the Spin loader zeroes out everything after the end of the program space, so this is probably done by the loader.

    I am thinking about creating a modified version of FSRW that would define the VAR variables in the DAT section instead.· I would then add a couple of methods that would swap in and out the 10 "VAR" state variables from user memory.· This would allow an unlimited number of files to be opened at the same time.· An addition varaible would also be needed that would point to a 512-byte data block for each open file.

    Once concern I have is that there is only one copy of buf2.· It seems that there would be a lot of thrashing in buf2 if multiple files were accessed at the same time.

    Dave
  • rokickirokicki Posts: 1,000
    edited 2010-04-28 23:43
    Yes, Spin clears the vars at start.

    What are you intending to achieve by your modified fsrw? Right now you can open as many files at the same time as you declare.
    This could be one or ten. By "user memory" do you mean, perhaps, external memory or some such? Can you give us a big picture
    here on what you're trying to achieve?

    The one copy of buf2 should be sufficient in normal use. If you use a reasonable cluster size, all should be well. It is true that using
    multiple metadata buffers might help in some situations, but the metadata buffer is only used on open, close (for write), seek,
    and whenever you cross a cluster boundary on read/write (which, with 32K clusters, is not that frequent).
  • pullmollpullmoll Posts: 817
    edited 2010-04-29 01:07
    Dave Hein said...
    I'll change the nextfile method to return the filesize and attribute bits.

    In case you want to access the date and time fields, here's a code snippet to convert them into a readable format. dent points to a directory entry and dtbuff to a string buffer of at least 20 bytes.
    CON
        dent_name          =    $00        ' filename
        dent_ext        =    $08        ' extension
        dent_attr        =    $0b        ' file attributes
        dent_attr_R        =    $01        ' read only attribute
        dent_attr_H        =    $02        ' hidden attribute
        dent_attr_S        =    $04        ' system attribute
        dent_attr_L        =    $08        ' volume label attribute
        dent_attr_D        =    $10        ' directory attribute
        dent_attr_A        =    $20        ' archive attribute
        dent_attr_VSE        =    $0f        ' attribute of long filename entries
        dent_case        =    $0c        ' filename case of short filename (FAT32)
        dent_case_f        =    $08        ' filename is lowercase
        dent_case_e        =    $10        ' extension is lowercase
        dent_ctime_ms        =    $0d        ' creation time milliseconds (FAT32)
        dent_ctime        =    $0e        ' creation time (DOS time format)
        dent_cdate        =    $10        ' creation date (DOS date format)
        dent_adate        =    $12        ' last access date (DOS date format)
        dent_clush        =    $14        ' start cluster high (FAT32!?)
        dent_mtime        =    $16        ' modification time (DOS time format)
        dent_mdate        =    $18        ' modification date (DOS date format)
        dent_clusl        =    $1a        ' start cluster low
        dent_fsize        =    $1c        ' filesize (long)
        dent_bytes        =    $20        ' bytes per directory entry
    
    PUB get_dent_date_time(dent, dtbuff) | pos, date, time, y, m, d, hh, mm, ss
        date := getword(dent, dent_cdate)
        time := getword(dent, dent_ctime)
        y := (date >> 9) + 1980
        m := (date >> 5) & 15
        d := date & 31
        hh := (time >> 11) & 31
        mm := (time >> 5) & 63
        ss := (time & 31) * 2
        pos := 0
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + y / 1000
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + (y / 100) // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + (y / 10) // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + y // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "-"
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + (m / 10) // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + m // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "-"
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + (d / 10) // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + d // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := " "
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + (hh / 10) // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + hh // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := ":"
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + (mm / 10) // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + mm // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := ":"
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + (ss / 10) // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos++] := "0" + ss // 10
        byte[noparse][[/noparse]dtbuff][noparse][[/noparse]pos] := 0
    
    PRI getword(buff, offs)
        result := byte[noparse][[/noparse]buff][noparse][[/noparse]offs] + 256*byte[noparse][[/noparse]buff][noparse][[/noparse]offs+1]
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Pullmoll's Propeller Projects

    Post Edited (pullmoll) : 4/29/2010 1:32:30 AM GMT
  • Dave HeinDave Hein Posts: 6,347
    edited 2010-04-29 02:53
    rokicki said...
    ...
    What are you intending to achieve by your modified fsrw? Right now you can open as many files at the same time as you declare.
    This could be one or ten. By "user memory" do you mean, perhaps, external memory or some such? Can you give us a big picture
    here on what you're trying to achieve?
    ...
    I'm adding file support to CLIB, which includes fopen, fclose, fread, fwrite, etc.· An fopen returns a stream pointer that is used with all the other file functions.· In my EEProm file system, the fopen routine mallocs a chunk of memory that contains the state variables and buffers for an instance.· An fclose frees up this memory.· I was hoping to do a similar thing with fsrw.
    I think for now I will use the object array technique.· I think an array of four fsrw objects should be sufficient.· An fopen will return the index of the next available fsrw object, and an fclose will free up that instance.
    Pullmoll, thanks for the code on converting the date and time·information.· I'm not planning on using the date/time information right now, but maybe in the future.
    Dave

    Post Edited (Dave Hein) : 4/29/2010 3:00:18 AM GMT
Sign In or Register to comment.