📄 mem-ffs.c
字号:
//****************************************************************************************
//****************************************************************************************
// Project Name: FAT FILING SYSTEM FAT16 & FAT 32 DRIVER
// FAT FILING SYSTEM DRIVER C CODE FILE
// Copyright: EMBEDDED-CODE.COM
//
// Licenced To: NONE
// Licence Number: NONE
//
// IMPORTANT: These files are copyright of embedded-code.com and are subject to a licence
// agreement. All rights reserved. Unauthorised use, reproduction or distribution of
// these files may lead to prosecution.
// Any use in violation of the licence restrictions may subject the user to criminal
// sanctions under applicable laws, as well as to civil liability for the breach of the
// terms and conditions of the license.
// This software is provided in an "as is" condition. No warranties, whether express,
// implied or statutory, including, but not limited to, implied warranties of
// merchantability and fitness for a particular purpose apply to this software.
// Embedded-code.com shall not be liable in any circumstances for special, incidental
// or consequential damages, for any reason whatsoever.
// Please see 'www.embedded-code.com\licence' or email 'licence@embedded-code.com' for
// full details.
// This file contains hidden markers to identify it uniquely to the licence number it was
// purchased under.
// DO NOT REMOVE THIS NOTICE - IT IS A REQUIREMENT OF THE LICENCE AGREEMENT.
//****************************************************************************************
//****************************************************************************************
######## "####.#"
####### #####
######## "#######.#"
######## "#########.#"
//*******************************
//*******************************
//********** OPEN FILE **********
//*******************************
//*******************************
//For ease of use this driver does not differentiate between text and binary mode. You may open a file in either mode (or
//neither) and all file operations will be exactly the same (basically is if the file was opened in binary mode. LF characters
//will not be converted to a pair CRLF characters and vice versa. This makes using functions like fseek much simpler and avoids
//operating system difference issues. (If you are not aware there is no difference between a binary file and a text file - the
//difference is in how the operating system chooses to handle text files)
//
//filename
// Only 8 character DOS compatible root directory filenames are allowed. Format is F.E where F may be between 1 and 8 characters
// and E may be between 1 and 3 characters, null terminated, non-case sensitive. The '*' and '?' wildcard characters may be used.
//
//access_mode
// "r" Open a file for reading. The file must exist.
// "r+" Open a file for reading and writing. The file must exist.
// "w" Create an empty file for writing. If a file with the same name already exists its content is erased.
// "w+" Create an empty file for writing and reading. If a file with the same name already exists its content is erased before it is opened.
// "a" Append to a file. Writing operations append data at the end of the file. The file is created if it doesn't exist.
// "a+" Open a file for reading and appending. All writing operations are done at the end of the file protecting the previous
// content from being overwritten. You can reposition (fseek) the pointer to anywhere in the file for reading, but
// writing operations will move back to the end of file. The file is created if it doesn't exist.
//
//Return value.
// If the file has been successfully opened the function will return a pointer to the file. Otherwise a null pointer is returned (0x00).
FFS_FILE* ffs_fopen (const char *filename, const char *access_mode)
{
#### ###########;
#### ##############;
#### #####;
#### ##############[#];
#### ###################[#];
//----------------------------------------------
//----- LOOK FOR AN AVAILABLE FILE HANDLER -----
//----------------------------------------------
### (########### = #; ########### < #############; ###########++)
{
## (########[###########].#####.####.############ == #)
{
//THIS HANDLER IS AVAILABLE
#####;
}
## (########### == (############# # #))
{
//LAST HANDLER TRIED - THE MAXIMUM NUMBER OF FILES ARE ALREADY OPEN
######(#);
}
}
//----- AVAILABLE FILE HANDLER FOUND BUT NOT YET ASSIGNED -----
//(file_number = the available handler)
//----------------------------------------------
//----- LOOK TO SEE IF FILE ALREADY EXISTS -----
//----------------------------------------------
########[###########].############### = ############# (########, &########[###########].#########, &##############, &########[###########].######################, &########[###########].#############################, ##############, ###################);
//--------------------------------------------------------
//----- IF FILE EXISTS ENSURE IT IS NOT ALREADY OPEN -----
//--------------------------------------------------------
## (########[###########].############### != ##########) //0xffffffff = file not found
{
### (##### = #; ##### < #############; #####++)
{
## (########[#####].#####.####.############)
{
## (
(##### != ###########) &&
(########[#####].###################### == ########[###########].######################) &&
(########[#####].############################# == ########[###########].#############################)
)
{
######(#);
}
}
}
}
//-------------------------------------------------------------
//----- IF OPENING A FILE FOR READ THEN CHECK FILE EXISTS -----
//-------------------------------------------------------------
## (########[###########].############### == ##########) //0xffffffff = file not found
{
## (*########### == '#')
{
//ERROR - CAN'T OPEN FILE FOR READ AS IT DOESN'T EXIST
######(#);
}
}
//-----------------------------------------------------------------
//----- IF WRITING A FILE AND IT ALREADY EXISTS THEN ERASE IT -----
//-----------------------------------------------------------------
## (########[###########].############### != ##########) //0xffffffff = file not found
{
## (*########### == '#')
{
//ERASE FILE
##########(########);
########[###########].############### = ##########;
}
}
//----------------------------------------------------------------------
//----- IF WRITING OR APPENDING A FILE THEN CREATE IT IF NECESSARY -----
//----------------------------------------------------------------------
## (########[###########].############### == ##########)
{
## (###################(########, &########[###########].###############, &########[###########].######################,
&########[###########].#############################) == #) //This function checks for any wildcard characters in the filename and aborts if there are any
{
//ERROR - CAN'T CREATE A NEW FILE
######(#);
}
########[###########].######### = #;
}
//------------------------------------------------------------
//----- FLAG THAT FILE IS OPEN AND SETUP FOR FILE ACCESS -----
//------------------------------------------------------------
########[###########].#####.####.############ = #;
########[###########].#####.####.############ = #;
########[###########].#####.####.########### = #;
########[###########].#####.####.##################### = #;
//--------------------------------------------------
//----- SET THE ACCESS MODE FLAGS FOR THE FILE -----
//--------------------------------------------------
## (*########### == '#')
{
## (
(*(########### + #) == '+') ||
((*(########### + #) != ####) && (*(########### + #) == '+'))
)
{
//----- ACCESS MODE IS 'R+' -----
########[###########].#####.####.############## = #;
########[###########].#####.####.############### = #;
########[###########].#####.####.################# = #;
}
####
{
//----- ACCESS MODE IS 'R' -----
########[###########].#####.####.############## = #;
########[###########].#####.####.############### = #;
########[###########].#####.####.################# = #;
}
//Set the current location to the beginning of the file
########[###########].############## = #;
########[###########].############ = #;
########[###########].######################## = #;
########[###########].#####.####.####################### = #; //No increment before next read or write as we're already pointing to the next byte to access
}
#### ## (*########### == '#')
{
## (
(*(########### + #) == '+') ||
((*(########### + #) != ####) && (*(########### + #) == '+'))
)
{
//----- ACCESS MODE IS 'W+' -----
########[###########].#####.####.############## = #;
########[###########].#####.####.############### = #;
########[###########].#####.####.################# = #;
}
####
{
//----- ACCESS MODE IS 'W' -----
########[###########].#####.####.############## = #;
########[###########].#####.####.############### = #;
########[###########].#####.####.################# = #;
}
//Set the current location to the beginning of the file
########[###########].############## = #;
########[###########].############ = #;
########[###########].######################## = #;
########[###########].#####.####.####################### = #; //No increment before next read or write as we're already pointing to the next byte to access
}
#### ## (*########### == '#')
{
## (
(*(########### + #) == '+') ||
((*(########### + #) != ####) && (*(########### + #) == '+'))
)
{
//----- ACCESS MODE IS 'A+' -----
########[###########].#####.####.############## = #;
########[###########].#####.####.############### = #;
########[###########].#####.####.################# = #;
}
####
{
//----- ACCESS MODE IS 'A' -----
########[###########].#####.####.############## = #;
########[###########].#####.####.############### = #;
########[###########].#####.####.################# = #;
}
//Set the current location to the last byte of the file
########[###########].############## = #; //These need setting to file start before calling ffs_fseek
########[###########].############ = #;
########[###########].######################## = #;
########[###########].#####.####.####################### = #;
#########(&########[###########], #, ############); //Use the fseek function to do this
## (########[###########].#########)
{
########[###########].#####.####.####################### = #; //Increment before doing the next read or write as we're pointing to the last byte of the file and the next byte will be a new byte
}
}
######(&########[###########]);
}
//************************************************
//************************************************
//********** MOVE THE FILE BYTE POINTER **********
//************************************************
//************************************************
//This function is quite complex as it looks to see if the new location is in the same cluster as the current location to avoid having
//to read all of the FAT table entries for the file from the file start where possible. This results in a large speed improvement.
//
//origin
// The initial position from where the offset is applied
// FFS_SEEK_SET (0) Beginning of file
// FFS_SEEK_CUR (1) Current position of the file pointer
// FFS_SEEK_END (2) End of file
//offset
// Signed offset from the position set by origin
//returns
// 0 if successful, 1 otherwise
int ffs_fseek (FFS_FILE *file_pointer, long offset, int origin)
{
##### #######;
##### #################;
##### #################;
#### ##################;
################# = ################### * ####################;
//-----------------------------------
//----- ENSURE THE FILE IS OPEN -----
//-----------------------------------
## (#############>#####.####.############ == #)
######(#);
## (###### == ############)
{
//---------------------------------------
//----- ORIGIN IS BEGINNING OF FILE -----
//---------------------------------------
## (###### < #)
{
//----- NEGATIVE VALUE - ILLEGAL -----
######(#);
}
#### ## (###### == #)
{
//----- ZERO VALUE - SET TO START OF FILE -----
################# = #;
}
####
{
//----- POSITIVE VALUE -----
################# = (#####)######; //Set bytes from start value ready to move to requried location
}
}
#### ## (###### == ############)
{
//----------------------------------------------
//----- ORIGIN IS CURRENT POSITION IN FILE -----
//----------------------------------------------
################# = #############>########################;
## (#############>#####.####.#######################)
#################++;
## (###### < #)
{
//OFFSET IS NEGATIVE
################# #= (#####)# # ######;
}
####
{
//OFFSET IS POSITIVE
################# += (#####)######;
}
}
#### ## (###### == ############)
{
//---------------------------------
//----- ORIGIN IS END OF FILE -----
//---------------------------------
## (###### > #)
{
//----- POSITIVE VALUE > 1 ILLEGAL -----
######(#);
}
#### ## (###### == #)
{
################# = #############>#########;
}
####
{
################# = (#############>#########) # (#####)(# # ######) # #; //Set bytes from start value ready to move to requried location
}
}
####
{
//----- INVALID ORIGIN VALUE -----
######(#);
}
//------------------------------------------------
//----- ORIGIN IS NOW FROM BEGINNING OF FILE -----
//------------------------------------------------
//----- CHECK OFFSET IS VALID -----
## (################# > (#############>#########))
{
//NEW POSITION IS > FILE SIZE + 1 = ERROR
######(#);
}
#### ## (################# == (#############>#########))
{
//NEW POSITION = FILE SIZE SO IS THE POSITION READY FOR WRITING A NEW BYTE (DOESN'T ACTUALLY EXIST IN FILE YET)
## (#################)
{
###################;
#############>#####.####.####################### = #;
}
####
{
#############>#####.####.####################### = #;
}
}
####
{
//NEW POSITION IS WITHIN FILE
#############>#####.####.####################### = #;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -