Calling File Extensions (FSRW)
oodes
Posts: 131
Using the fsrw object for file read/write from an sd card. I'm looking for a way to call a file with a certain file extension regardless of the file name
[code]
r := sdfat.popen(string("Upgrade.eep"), "r") 'returns a 0 if the file Upgrade.eep is present.
if r == 0
UpgradeSoftware
[\code]
What im looking for is a way to call any file with the extension .eep regardless of the name like 'anyname.eep' . As long as the file has the extension .eep it will be opened.
Any ideas?
Thanks
Des
The popen section of fsrw is as below
[code]
pub popen(s, mode) : r | i, sentinel, dirptr, freeentry
{{
' Close any currently open file, and open a new one with the given
' file name and mode. Mode can be "r" "w" "a" or "d" (delete).
' If the file is opened successfully, 0 will be returned. If the
' file did not exist, and the mode was not "w" or "a", -1 will be
' returned. Otherwise abort will be called with a negative error
' code.
}}
pclose
i := 0
repeat while (i<8 and byte and byte <> ".")
padname[i++] := uc(byte[s++])
repeat while (i<8)
padname[i++] := " "
repeat while (byte and byte <> ".")
s++
if (byte == ".")
s++
repeat while (i<11 and byte)
padname[i++] := uc(byte[s++])
repeat while (i < 11)
padname[i++] := " "
sentinel := 0
freeentry := 0
repeat dirptr from rootdir to rootdirend - DIRSIZE step DIRSIZE
s := readbytec(dirptr)
if (freeentry == 0 and (byte == 0 or byte == $e5))
freeentry := dirptr
if (byte == 0)
sentinel := dirptr
quit
repeat i from 0 to 10
if (padname <> byte)
quit
if (i == 11 and 0 == (byte[$0b] & $18)) ' this always returns
fclust := brword(s+$1a)
if (filesystem == 2)
fclust += brword(s+$14) << 16
firstcluster := fclust
filesize := brlong(s+$1c)
if (mode == "r")
frem := (clustersize) <# (filesize)
return 0
if (byte[11] & $d9)
abort(-6) ' no permission to write
if (mode == "d")
brwword(s, $e5)
if (fclust)
freeclusters(fclust)
flushifdirty
return 0
if (mode == "w")
brwword(s+$1a, 0)
brwword(s+$14, 0)
brwlong(s+$1c, 0)
writelink := 0
direntry := dirptr
if (fclust)
freeclusters(fclust)
bufend := SECTORSIZE
fclust := 0
filesize := 0
frem := 0
return 0
elseif (mode == "a")
' this code will eventually be moved to seek
frem := filesize
freeentry := clustersize
if (fclust => endofchain)
fclust := 0
repeat while (frem > freeentry)
if (fclust < 2)
abort(-7) ' eof repeat while following chain
fclust := nextcluster
frem -= freeentry
floc := filesize & constant(!(SECTORSIZE - 1))
bufend := SECTORSIZE
bufat := frem & constant(SECTORSIZE - 1)
writelink := 0
direntry := dirptr
if (bufat)
sdspi.readblock(datablock, @buf)
frem := freeentry - (floc & (freeentry - 1))
else
if (fclust < 2 or frem == freeentry)
frem := 0
else
frem := freeentry - (floc & (freeentry - 1))
if (fclust => 2)
followchain
return 0
else
abort(-3) ' bad argument
if (mode <> "w" and mode <> "a")
return -1 ' not found
direntry := freeentry
if (direntry == 0)
abort(-2) ' no empty directory entry
' write (or new append): create valid directory entry
s := readbytec(direntry)
bytefill(s, 0, DIRSIZE)
bytemove(s, @padname, 11)
brwword(s+$1a, 0)
brwword(s+$14, 0)
i := pdate
brwlong(s+$e, i) ' write create time and date
brwlong(s+$16, i) ' write last modified date and time
if (direntry == sentinel and direntry + DIRSIZE < rootdirend)
brwword(readbytec(direntry+DIRSIZE), 0)
flushifdirty
writelink := 0
fclust := 0
bufend := SECTORSIZE
' return r (default return)
[\code]
[code]
r := sdfat.popen(string("Upgrade.eep"), "r") 'returns a 0 if the file Upgrade.eep is present.
if r == 0
UpgradeSoftware
[\code]
What im looking for is a way to call any file with the extension .eep regardless of the name like 'anyname.eep' . As long as the file has the extension .eep it will be opened.
Any ideas?
Thanks
Des
The popen section of fsrw is as below
[code]
pub popen(s, mode) : r | i, sentinel, dirptr, freeentry
{{
' Close any currently open file, and open a new one with the given
' file name and mode. Mode can be "r" "w" "a" or "d" (delete).
' If the file is opened successfully, 0 will be returned. If the
' file did not exist, and the mode was not "w" or "a", -1 will be
' returned. Otherwise abort will be called with a negative error
' code.
}}
pclose
i := 0
repeat while (i<8 and byte and byte <> ".")
padname[i++] := uc(byte[s++])
repeat while (i<8)
padname[i++] := " "
repeat while (byte and byte <> ".")
s++
if (byte == ".")
s++
repeat while (i<11 and byte)
padname[i++] := uc(byte[s++])
repeat while (i < 11)
padname[i++] := " "
sentinel := 0
freeentry := 0
repeat dirptr from rootdir to rootdirend - DIRSIZE step DIRSIZE
s := readbytec(dirptr)
if (freeentry == 0 and (byte == 0 or byte == $e5))
freeentry := dirptr
if (byte == 0)
sentinel := dirptr
quit
repeat i from 0 to 10
if (padname <> byte)
quit
if (i == 11 and 0 == (byte[$0b] & $18)) ' this always returns
fclust := brword(s+$1a)
if (filesystem == 2)
fclust += brword(s+$14) << 16
firstcluster := fclust
filesize := brlong(s+$1c)
if (mode == "r")
frem := (clustersize) <# (filesize)
return 0
if (byte[11] & $d9)
abort(-6) ' no permission to write
if (mode == "d")
brwword(s, $e5)
if (fclust)
freeclusters(fclust)
flushifdirty
return 0
if (mode == "w")
brwword(s+$1a, 0)
brwword(s+$14, 0)
brwlong(s+$1c, 0)
writelink := 0
direntry := dirptr
if (fclust)
freeclusters(fclust)
bufend := SECTORSIZE
fclust := 0
filesize := 0
frem := 0
return 0
elseif (mode == "a")
' this code will eventually be moved to seek
frem := filesize
freeentry := clustersize
if (fclust => endofchain)
fclust := 0
repeat while (frem > freeentry)
if (fclust < 2)
abort(-7) ' eof repeat while following chain
fclust := nextcluster
frem -= freeentry
floc := filesize & constant(!(SECTORSIZE - 1))
bufend := SECTORSIZE
bufat := frem & constant(SECTORSIZE - 1)
writelink := 0
direntry := dirptr
if (bufat)
sdspi.readblock(datablock, @buf)
frem := freeentry - (floc & (freeentry - 1))
else
if (fclust < 2 or frem == freeentry)
frem := 0
else
frem := freeentry - (floc & (freeentry - 1))
if (fclust => 2)
followchain
return 0
else
abort(-3) ' bad argument
if (mode <> "w" and mode <> "a")
return -1 ' not found
direntry := freeentry
if (direntry == 0)
abort(-2) ' no empty directory entry
' write (or new append): create valid directory entry
s := readbytec(direntry)
bytefill(s, 0, DIRSIZE)
bytemove(s, @padname, 11)
brwword(s+$1a, 0)
brwword(s+$14, 0)
i := pdate
brwlong(s+$e, i) ' write create time and date
brwlong(s+$16, i) ' write last modified date and time
if (direntry == sentinel and direntry + DIRSIZE < rootdirend)
brwword(readbytec(direntry+DIRSIZE), 0)
flushifdirty
writelink := 0
fclust := 0
bufend := SECTORSIZE
' return r (default return)
[\code]
Comments
I tend to use SWAP-files if an SD card is available, as this gives a lot of memory. So, in one of my early test-programs showing images stored on SD on a 320x200 LCD-display I first loop over the directory, store the filenames in my SWAP-file and then in the display-loop get the filenames from there, because SWAP file works without interference of the other FSRW functions.
http://forums.parallax.com/showthread.php/117573-Virtual-Memory
http://www.google.de/url?sa=t&rct=j&q=vmem%20site%3Aforums.parallax.com&source=web&cd=1&cad=rja&ved=0CDAQFjAA&url=http%3A%2F%2Fforums.parallax.com%2Fattachment.php%3Fattachmentid%3D65649%26d%3D1260162407&ei=Cv4UUdm5G4mG4gSL34GIAg&usg=AFQjCNG-3uQLDSqCwruqmqzERNuegxXbpA&bvm=bv.42080656,d.Yms
Can post some code this evening.
Find the files:
Then the display loop looks like that:
BMP_BASE is simply an address inside of the SWAP-file which I decided to be used as a filename-buffer.
That worked perfectly ,
Thanks
Des
Cheers,
Andreas