📄 imf.c
字号:
/***************************************************************************
* Copyright (c) 1993 - 2001 Accelerated Technology, Inc.
*
* PROPRIETARY RIGHTS of Accelerated Technology are involved in the subject
* matter of this material. All manufacturing, reproduction, use and sales
* rights pertaining to this subject matter are governed by the license
* agreement. The recipient of this software implicity accepts the terms
* of the license.
*
****************************************************************************/
/****************************************************************************
*
* FILENAME VERSION
*
* IMF 1.0
*
* COMPONENT
*
* File Abstraction Layer
*
* DESCRIPTION
*
* This file contains the In-Memory File System functions.
* The In-Memory File System does not support directories. The user can
* increase the number of files by modifying the MAX_FILES macro in imf.h.
* The user can increase the maximum size of a file by modifying the
* MAX_FILE_SIZE macro in imf.h.
*
* DATA STRUCTURES
*
* None
*
* FUNCTIONS
*
* IMF_Open
* IMF_Find_File
* IMF_Close
* IMF_Write
* IMF_Read
* IMF_Delete
* IMF_Seek
* IMF_Store_Name
* IMF_Fgets
* IMF_Rename
*
* DEPENDENCIES
*
* imf.h
*
***************************************************************************/
#include "fal/inc/imf.h"
#include "net/inc/externs.h"
MEM_FILE file_desc_ary[MAX_FILES];
INT p_errno;
/****************************************************************************
*
* FUNCTION
*
* IMF_Open
*
* DESCRIPTION
*
* This function will search for a file with the name specified in the
* path parameter. If a file of the same name is found the file
* descriptor is returned, otherwise the file will be created if the
* IMF_CREAT flag is set. Newly created files have a length of 0 and
* their read and write pointers set to the beginning of the file.
* File names can be no longer than 12 characters; otherwise, they are
* truncated at the 12th character.
*
* INPUTS
*
* path Name of the file to open / create
* flag Flags that are set on the open
*
* OUTPUTS
*
* Upon successful completion, the function returns the file descriptor
* of the open file. Otherwise, the function returns -1, and p_errno
* is set to an error code. Possible error codes follow:
*
* IMF_NO_FILE The file was not found, and the IMF_CREAT flag
* was not set.
* IMF_NO_BUFFERS There are no unused buffers to create the file.
* The number of buffers used for file storage can
* be increased in imf.h - MAX_FILES.
* IMF_FILE_EXISTS The file already exists, and the IMF_EXCL and
* IMF_CREAT flags were both set.
* IMF_FILE_OPEN The file is already open and either the
* IMF_NOSHAREANY flag was set or the IMF_WRONLY
* flag was previously set and the IMF_NOSHAREWRITE
* flag was set on this open call.
*
***************************************************************************/
INT IMF_Open(CHAR *path, INT16 flag)
{
INT i, size;
INT file_desc;
/* check if there is such an existing file, or not. If the file does not
* exist, and the user did not specify PO_CREAT in the flag field, return
* that the file does not exist - otherwise, create the file
*/
if ((file_desc = IMF_Find_File(path, flag)) != IMF_NO_FILE)
return (file_desc);
/* If the flag is not set to create if the file is not found, return
* otherwise, continue and create the file
*/
else if (!(flag & IMF_CREAT))
{
p_errno = IMF_NO_FILE;
return (-1);
}
/* If the flag is set for read only, but the file does not exist, return
* an error
*/
if (flag & IMF_RDONLY)
{
p_errno = IMF_NO_FILE;
return (-1);
}
/* Search the unused file descriptors. */
for (i = 0; i < MAX_FILES; i++)
if (file_desc_ary[i].used == 0)
break;
/* If an unused file was not found, return an error. */
if (i >= MAX_FILES)
{
p_errno = IMF_NO_BUFFERS;
return (-1);
}
else
{
file_desc = i;
/* If the length of the name is longer than 12, truncate */
if((size = strlen((CHAR*)path)) > NAME_LENGTH)
size = NAME_LENGTH;
/* Copy the name and null terminate it */
memmove(file_desc_ary[i].name, path, (unsigned int)size);
file_desc_ary[i].name[size] = NU_NULL;
/* Set the file to open and used */
file_desc_ary[i].used = 1;
file_desc_ary[i].open = 1;
/* Set the flag field */
file_desc_ary[i].flag = flag;
/* This is a new file - its length is 0 */
file_desc_ary[i].length = 0;
/* The read and write pointers start at the beginning of the file */
file_desc_ary[i].eof_ptr = file_desc_ary[i].start;
file_desc_ary[i].file_ptr = file_desc_ary[i].start;
return (file_desc);
}
}
/****************************************************************************
*
* FUNCTION
*
* IMF_Find_File
*
* DESCRIPTION
*
* This function will search for a file with the name specified in the
* path parameter. If the PO_APPEND flag is set, the write pointer is
* set to the end of the existing data of the file; otherwise, the
* write pointer is set to the beginning of the file and the length is
* set to 0.
*
* INPUTS
*
* path Name of the file to open
* flag Flags that are set on the open
*
* OUTPUTS
*
* Upon successful completion, the function returns the file descriptor.
* Otherwise, the function returns -1 and sets p_errno to one of the
* following error codes:
*
* IMF_NO_FILE The file was not found.
* IMF_FILE_EXISTS The file already exists, and the IMF_EXCL and
* IMF_CREAT flags were both set.
* IMF_FILE_OPEN The file is already open and either the
* IMF_NOSHAREANY flag was set or the IMF_WRONLY
* flag was previously set and the IMF_NOSHAREWRITE
* flag was set on this open call.
*
***************************************************************************/
INT IMF_Find_File(CHAR *path, INT16 flag)
{
INT i, size;
INT file_desc;
/* If the name of the file is longer than 12, truncate */
if((size = strlen((CHAR*)path)) > NAME_LENGTH)
size = NAME_LENGTH;
/* Look for the file descriptor */
for (i = 0; i < MAX_FILES; i++)
{
if (strncmp(file_desc_ary[i].name, (CHAR*)path, (unsigned int)size) == 0)
break;
}
/* If we did not find the file */
if (i >= MAX_FILES)
return (IMF_NO_FILE);
/* If flag set to fail if creating and already exists, return error */
if ((flag & IMF_EXCL) && (flag & IMF_CREAT))
return (IMF_FILE_EXISTS);
/* If file is already open and flag is set to fail if open, return error.
* If file is already open and previous flag is set to write only and flag
* is set to fail if already open for write, return error.
*/
if (((file_desc_ary[i].open) && (flag & IMF_NOSHAREANY)) ||
((file_desc_ary[i].open) && (file_desc_ary[i].flag & IMF_WRONLY) &&
(flag & IMF_NOSHAREWRITE)))
return (IMF_FILE_OPEN);
else
{
file_desc = i;
file_desc_ary[i].open = 1;
/* If the truncate flag is set, the contents of the file are
* destroyed and the length is set to 0
*/
if (flag & IMF_TRUNC)
file_desc_ary[i].length = 0;
/* If the flag is set to append, set the file pointer to the end of
* the data in the file
*/
else if (flag & IMF_APPEND)
{
file_desc_ary[i].file_ptr = file_desc_ary[i].start +
file_desc_ary[i].length;
}
else
file_desc_ary[i].file_ptr = file_desc_ary[i].start;
/* The EOF file pointer is always set to the end of the data */
file_desc_ary[i].eof_ptr = file_desc_ary[i].start +
file_desc_ary[i].length;
/* Set the flag */
file_desc_ary[i].flag = flag;
return (file_desc);
}
}
/****************************************************************************
*
* FUNCTION
*
* IMF_Close
*
* DESCRIPTION
*
* This function closes a file.
*
* INPUTS
*
* file The file descriptor of the file to close
*
* OUTPUTS
*
* Upon successful completion, the function returns NU_SUCCESS.
* Otherwise, the function returns -1 and sets p_errno to one of the
* following error codes:
*
* IMF_NO_FILE The file does not exist.
* IMF_INVAL_DESC The file descriptor is invalid - it either exceeds
* MAX_FILES or is less than 0.
*
***************************************************************************/
INT IMF_Close(INT file)
{
/* Validate the file descriptor. */
if( (file >= MAX_FILES) || (file < 0))
{
p_errno = IMF_INVAL_DESC;
return (-1);
}
if (file_desc_ary[file].used == 0)
{
p_errno = IMF_NO_FILE;
return (-1);
}
else
{
file_desc_ary[file].open = 0;
/* Set the file pointer back to the beginning of the file */
file_desc_ary[file].file_ptr = file_desc_ary[file].start;
/* Set the EOF pointer to the end of the data */
file_desc_ary[file].eof_ptr = file_desc_ary[file].start +
file_desc_ary[file].length;
return (0);
}
}
/****************************************************************************
*
* FUNCTION
*
* IMF_Write
*
* DESCRIPTION
*
* This function writes size bytes of data from buf into the file.
*
* INPUTS
*
* buf Pointer to the buffer of data to write.
* size Number of bytes to write.
* file File descriptor of the file to write the data to.
*
* OUTPUTS
*
* Upon successful completion, the function returns the amount of data
* written to the file; otherwise, it returns 0 and sets p_errno to one
* of the following error codes:
*
* IMF_INVAL_DESC The file descriptor is invalid - it either exceeds
* MAX_FILES or is less than 0.
* IMF_INVAL_BUFFER Either the size is 0 or buf is NULL.
* IMF_NO_FILE The file does not exist.
* IMF_FILE_CLOSED The file is closed.
* IMF_FILE_READONLY The file is read only.
* IMF_BUFFER_FULL The file is full.
*
***************************************************************************/
INT32 IMF_Write(CHAR *buf, INT size, INT file)
{
MEM_FILE *fptr;
INT bytes_to_write, bytes_left, init_bytes;
/* Validate the file descriptor. */
if ((file >= MAX_FILES) || (file < 0))
{
p_errno = IMF_INVAL_DESC;
return (0);
}
/* Verify that the buffersize and buffer ptr are valid. */
if ((size == 0) || (buf == NU_NULL))
{
p_errno = IMF_INVAL_BUFFER;
return(0);
}
/* Setup a pointer to a file descriptor. */
fptr = &file_desc_ary[file];
/* Make sure that this file exists, is open and is not read only */
if(fptr -> used == 0)
{
p_errno = IMF_NO_FILE;
return (0);
}
else if(fptr -> open == 0)
{
p_errno = IMF_FILE_CLOSED;
return(0);
}
else if(fptr -> flag & IMF_RDONLY)
{
p_errno = IMF_FILE_READONLY;
return(0);
}
/* If the IMF_APPEND flag is set, all writes are done at the end of the
* file, regardless of where you seek the pointer to
*/
if (fptr -> flag & IMF_APPEND)
fptr -> file_ptr = fptr -> eof_ptr;
/* Make sure there is room in the buffer. Only do a write if there is
* enough room to write the entire buffer.
*/
if((fptr -> max_length - fptr -> length) < (UINT32)size)
{
p_errno = IMF_BUFFER_FULL;
return (0);
}
/* Initialize bytes_to_write. */
bytes_to_write = size;
/* At this point we know how much data can be copied into this file. Check
* to see if a wrap is required to copy all the data.
*/
if ((fptr -> end - fptr -> file_ptr) >= bytes_to_write)
{
/* Copy the data to the file. */
memcpy(fptr -> file_ptr, buf, (unsigned int)bytes_to_write);
/* Update the file_ptr. */
fptr -> file_ptr += bytes_to_write;
/* If the file pointer has passed the eof pointer, we must increment
* the eof pointer and update the length - this will always be true
* if IMF_APPEND flag is set
*/
if (fptr -> file_ptr > fptr -> eof_ptr)
{
fptr -> length += (UINT32)(fptr -> file_ptr - fptr -> eof_ptr);
fptr -> eof_ptr = fptr -> file_ptr;
}
}
/* Otherwise, a wrap is required to fit all data into the file */
else
{
/* Find out how much room is left before the end is reached */
init_bytes = (INT)(fptr -> end - fptr -> eof_ptr);
/* Write to the end of the file */
memcpy(fptr -> eof_ptr, buf, (unsigned int)init_bytes);
/* Increment the length of the file */
fptr -> length += bytes_to_write;
/* Wrap back around to the start of the file */
fptr -> file_ptr = fptr -> start;
/* Update the buffer ptr */
buf += init_bytes;
/* Calculate the amount of data that is left to write */
bytes_left = bytes_to_write - init_bytes;
/* Copy the rest of the data */
memcpy(fptr -> file_ptr, buf, (unsigned int)bytes_left);
/* Update the file_ptr */
fptr -> file_ptr += bytes_left;
}
/* Return the number of bytes written to the file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -