Page 1 of 1
FAT spacing
Posted: Thu Apr 12, 2007 1:58 pm
by GLneo
hi, I'm now fixing up my fat driver and i am having alot of trouble with making a function that gets a string and returns a string with the 8.3 spacing, like this:
cool.bin will return cool****bin
* are spaces
i thought this would be easy but it is very hard, the code i have now is:
Code: Select all
#include <stdio.h>
#include <stdlib.h>
unsigned char *fatPad(unsigned char *str)
{
int count = 0, temp_count = 0;
unsigned char temp_string[11];
for(temp_count = 0; temp_count < 11; temp_count++, count++) // loop though the string
{
if(str[count] != '.') // if not a .
temp_string[temp_count] = str[count]; // paste it over from str to temp_string
else // other wise
for(; temp_count < 8; temp_count++) // while were less than 8
temp_string[temp_count] = '*'; // space the temp_string
}
return memcpy(str, temp_string, 11); // temp_string will be destroyed so return to str
}
int main ()
{
char string[11];
puts(fatPad(gets(string)));
system("pause");
return 0;
}
this output is cool**** but it should be: cool****bin
all comments welcome!
Posted: Thu Apr 12, 2007 2:09 pm
by ~
In a generic 8.3 file name for FAT, you won't find periods (except for . and ..).
If looking for short filenames, you should copy the entire 11 bytes out of the 8.3, and then figure out both the actual name and its extension by separating it in a group of 8 bytes for filename and 3 bytes for extension, and then get rid of spaces to form your final 'FILENAME.EXT' string.
By the way, aren't you iterating up to 8 bytes instead of 11?
Posted: Thu Apr 12, 2007 2:18 pm
by bsunisol
maybe you can define a string that is from beginning
filled with spaces:
and then find the dot and copy both parts with a loop like:
start with the name at the beginning and with the extension
at the end. i would not try to build such a complex loop.
i would rather code 2 simple ones.
and take care about the \0 at the end of an c-string.
Posted: Thu Apr 12, 2007 2:38 pm
by bubach
maybe something like: (untested)
Code: Select all
unsigned char *fatPad(unsigned char *str)
{
int count = 0, temp_count = 0;
unsigned char temp_string[11];
for(temp_count = 0; temp_count < 11; temp_count++, count++) // loop though the string
{
if(str[count] != '.') // if not a .
temp_string[temp_count] = str[count]; // paste it over from str to temp_string
else // other wise
{
for(; temp_count < 8; temp_count++) // while were less than 8
temp_string[temp_count] = '*'; // space the temp_string
temp_string[temp_count] = str[count+1];
temp_string[temp_count+1] = str[count+2];
temp_string[temp_count+2] = str[count+3];
}
}
return memcpy(str, temp_string, 11); // temp_string will be destroyed so return to str
}
Posted: Thu Apr 12, 2007 2:42 pm
by ~
bsunisol wrote:maybe you can define a string that is from beginning
filled with spaces:
and then find the dot and copy both parts with a loop like:
start with the name at the beginning and with the extension
at the end. i would not try to build such a complex loop.
i would rather code 2 simple ones.
and take care about the \0 at the end of an c-string.
Are you talking about the FAT short file names? They don't have such dots or '\0', as far as I know, except for the current directory entry '.' and for the parent directory '..', just ASCII characters and blank spaces (to be removed).
The delimitation of the 8.3 format could come from copying first the 11 bytes of the short filename entry, and then separate it into its first 8 bytes, remove spaces, optionally add a '.' in the final string, take the last 3 bytes and remove its blank spaces to build our final NAME.EXT type of display name.
Posted: Thu Apr 12, 2007 2:50 pm
by bsunisol
Are you talking about the FAT short file names? They don't have such dots or '\0', as far as I know, except for the current directory entry '.' and for the parent directory '..', just ASCII characters and blank spaces (to be removed).
yes, i know. i just wanted to point on it. c appends
to all strings a '\0'. but fat-tables are without them.
so he have to crap the string before writing it to the
fs.
Posted: Thu Apr 12, 2007 3:27 pm
by Kevin McGuire
Code: Select all
unsigned char *fatPad(unsigned char *str){
unsigned int x;
unsigned char e, f, g;
/// find period in file name, less than eight, or string zero termination.
for(x = 0; (str[x] != '.') && (x < 8) && (str[x] != 0); ++x);
if(str[x] != '.'){
/// filename to long (no extension found yet)
for(; (str[x] != 0) && (str[x] != '.'); ++x);
if(str[x] == 0){
/// no extension found (use last three ending letters
x -= 4;
}
}
/// extension
e = str[x+1]; f = str[x+2]; g = str[x+3];
str[8] = e; str[9] = f; str[10] = g;
/// pad remaining
for(; x < 8; ++x){
str[x] = '*'; // <---- RIGHT HERE
}
return str;
}
The space allocated for the data that str points to when passed to the function as a argument must be at least eleven bytes in length or the function will overwrite data at the end. So I think it is a slightly poor way when instead you might have.
padFat(unsigned char *in, unsigned char *out);
And, out points to the buffer where you are building the cluster to be written to disk - or cache of the cluster stored in RAM.
It should be faster to fill the 'out' string with the space value then write in the correct ones by scanning the 'in' string.
Posted: Thu Apr 12, 2007 4:31 pm
by pcmattman
THis won't allow any filename with more than one dot, but it works:
Code: Select all
void hConvertFilename( char* str )
{
// start by converting to uppercase
int i;
for( i = 0; i < strlen( str ); i++ )
{
str[i] = toupper( str[i] );
}
// find the full stop
int fullstoploc = find( str, '.', 0, strlen( str ) );
// check for validity
if( fullstoploc == -1 )
{
// make it the length of the string
fullstoploc = strlen( str );
}
// shift
for( i = fullstoploc; i < strlen( str ); i++ )
str[i] = str[i+1];
// now pad out the string if needed
// ie. test.bin --> TEST BIN
if( strlen( str ) < 11 )
{
// get the extension length
int extlen = strlen( str ) - fullstoploc;
// first offset for the extension
int firstoff = 11 - extlen;
// move ext to the end of the string
i = firstoff;
while( i < 11 )
{
// put it there
str[i] = str[i-(8-fullstoploc)];
i++;
}
str[i] = 0;
// pad out with spaces
for( i = fullstoploc; i < firstoff; i++ )
str[i] = ' ';
}
}
Posted: Thu Apr 12, 2007 4:47 pm
by B.E
try this:
Code: Select all
char *fatPad(char *str){
int i,j;
char tempstr[3], *tstr = str, *endStr;
// Find '.'
for (i=0;(i <= 8) && *str++ != '.';++i);
endStr = str;
if (*(str-1) != '.'){
// TODO: make unique name
while ( *endStr++ != '.' )
if (!*endStr){
for (i=9;(i <= 11);++i,tstr[i] = 0);
return tstr;
}
}
// copy extention to a temp location
for (j=0;j < 3;tempstr[j] = endStr[j], ++j);
// go back one so that it now point to the '.'
str--;
// fill rest of string with spaces
for (;i <= 8;++i,*str++ = ' ');
// copy extention to a temp location
for (i=0;i < 3;*str++ = tempstr[i], ++i);
*str = 0;
return tstr;
}
Posted: Thu Apr 12, 2007 6:48 pm
by GLneo
B.E. = fds.... : fds*****... so that could be a problem
Kevin McGuire = looks ok
bubach = cool.exe : cool****eex
bubach is very close so i modified his code and got:
Code: Select all
unsigned char *fatPad(unsigned char *str)
{
int count = 0, temp_count = 0;
unsigned char temp_string[11];
for(temp_count = 0; temp_count < 11; temp_count++, count++) // loop though the string
{
if(str[count] != '.') // if not a .
temp_string[temp_count] = str[count]; // paste it over from str to temp_string
else // other wise
{
for(; temp_count < 8; temp_count++) // while were less than 8
temp_string[temp_count] = '*'; // space the temp_string
temp_string[temp_count] = str[count+1];
temp_string[temp_count+1] = str[count+2];
temp_string[temp_count+2] = str[count+3];
break; //<----------- NEW-------------------
}
}
return memcpy(str, temp_string, 11); // temp_string will be destroyed so return to str
}
which works very good.