You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
244 lines
6.9 KiB
C
244 lines
6.9 KiB
C
![]()
2 days ago
|
/******************************************************************************
|
||
|
* file lib/management/file_fifo.c
|
||
|
* author YuLiang
|
||
|
* version 1.0.0
|
||
|
* date 10-Jun-2025
|
||
|
* brief This file provides all the file fifo operation functions.
|
||
|
*
|
||
|
******************************************************************************
|
||
|
* Attention
|
||
|
*
|
||
|
* <h2><center>© COPYRIGHT(c) 2025 LandPower</center></h2>
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||
|
* are permitted provided that the following conditions are met:
|
||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||
|
* this list of conditions and the following disclaimer.
|
||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||
|
* this list of conditions and the following disclaimer in the documentation
|
||
|
* and/or other materials provided with the distribution.
|
||
|
* 3. Neither the name of LandPower nor the names of its contributors may be used to
|
||
|
* endorse or promote products derived from this software without specific
|
||
|
* prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
|
||
|
/* Includes ------------------------------------------------------------------*/
|
||
|
#ifdef HAVE_CONFIG_H
|
||
|
#include "config.h"
|
||
|
#endif
|
||
|
|
||
|
/* 标准C库头文件. */
|
||
|
#include <sys/stat.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <dirent.h>
|
||
|
#include <ctype.h>
|
||
|
|
||
|
/* 用户代码头文件. */
|
||
|
#include <file_fifo.h>
|
||
|
|
||
|
/* Private define ------------------------------------------------------------*/
|
||
|
|
||
|
/* Private macro -------------------------------------------------------------*/
|
||
|
|
||
|
/* Private typedef -----------------------------------------------------------*/
|
||
|
|
||
|
/* Private variables ---------------------------------------------------------*/
|
||
|
|
||
|
/* Private function prototypes -----------------------------------------------*/
|
||
|
|
||
|
/* Internal functions --------------------------------------------------------*/
|
||
|
/* 创建目录 */
|
||
|
int32_t _file_fifo_dir_create(char *dir)
|
||
|
{
|
||
|
uint32_t i = 0;
|
||
|
uint32_t len = 0;
|
||
|
|
||
|
len = strlen(dir);
|
||
|
|
||
|
/* 循环创建前级目录 */
|
||
|
for(i = 0; i < len; i++)
|
||
|
{
|
||
|
if(dir[i] == '/')
|
||
|
{
|
||
|
dir[i] = '\0';
|
||
|
if(access(dir, 0) != 0)
|
||
|
{
|
||
|
mkdir(dir, 744);
|
||
|
}
|
||
|
dir[i] ='/';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* 创建最后级目录 */
|
||
|
if(len > 0 && access(dir, 0) != 0)
|
||
|
{
|
||
|
mkdir(dir, 744);
|
||
|
}
|
||
|
|
||
|
return E_NONE;
|
||
|
}
|
||
|
|
||
|
/* Interface functions -------------------------------------------------------*/
|
||
|
/* 写函数 */
|
||
|
int32_t file_fifo_write(file_fifo_t *config, const char *content, int32_t len)
|
||
|
{
|
||
|
FILE *fp = NULL;
|
||
|
char filename[FILE_FIFO_PATH_LEN];
|
||
|
int32_t size = 0;
|
||
|
|
||
|
if (config->index_max - config->index_min >= config->files_max)
|
||
|
{
|
||
|
return E_FULL;
|
||
|
}
|
||
|
|
||
|
/* 确认文件名 */
|
||
|
snprintf(filename, FILE_FIFO_PATH_LEN, "%s/%lld", config->dir, config->index_max);
|
||
|
|
||
|
/* 写入文件 */
|
||
|
fp = fopen(filename, "w+");
|
||
|
if (!fp)
|
||
|
{
|
||
|
DBG(DBG_M_FILE_FIFO_ERR, "Open %s ERROR\r\n", filename);
|
||
|
return E_SYS_CALL;
|
||
|
}
|
||
|
|
||
|
size = fwrite(content, 1, len, fp);
|
||
|
if (size != len)
|
||
|
{
|
||
|
fclose(fp);
|
||
|
DBG(DBG_M_FILE_FIFO_ERR, "Write %s ERROR\r\n", filename);
|
||
|
return E_SYS_CALL;
|
||
|
}
|
||
|
fclose(fp);
|
||
|
|
||
|
config->index_max++;
|
||
|
return E_NONE;
|
||
|
}
|
||
|
|
||
|
/* 读函数 */
|
||
|
int32_t file_fifo_read(file_fifo_t *config, char *content, int32_t *len)
|
||
|
{
|
||
|
FILE *fp = NULL;
|
||
|
char filename[FILE_FIFO_PATH_LEN];
|
||
|
int32_t size = 0;
|
||
|
|
||
|
if (config->index_max == config->index_min)
|
||
|
{
|
||
|
return E_EMPTY;
|
||
|
}
|
||
|
|
||
|
/* 确认文件名 */
|
||
|
snprintf(filename, FILE_FIFO_PATH_LEN, "%s/%lld", config->dir, config->index_min);
|
||
|
|
||
|
/* 打开文件 */
|
||
|
fp = fopen(filename, "r");
|
||
|
if (!fp)
|
||
|
{
|
||
|
file_fifo_delete_by_min_index(config);
|
||
|
DBG(DBG_M_FILE_FIFO_ERR, "Open %s ERROR\r\n", filename);
|
||
|
return E_SYS_CALL;
|
||
|
}
|
||
|
|
||
|
size = fread(content, 1, *len, fp);
|
||
|
if (size <= 0)
|
||
|
{
|
||
|
fclose(fp);
|
||
|
file_fifo_delete_by_min_index(config);
|
||
|
DBG(DBG_M_FILE_FIFO_ERR, "Read %s ERROR\r\n", filename);
|
||
|
return E_SYS_CALL;
|
||
|
}
|
||
|
*len = size;
|
||
|
fclose(fp);
|
||
|
|
||
|
return E_NONE;
|
||
|
}
|
||
|
|
||
|
/* 删除最小索引文件 */
|
||
|
void file_fifo_delete_by_min_index(file_fifo_t *config)
|
||
|
{
|
||
|
char filename[FILE_FIFO_PATH_LEN];
|
||
|
|
||
|
snprintf(filename, FILE_FIFO_PATH_LEN, "%s/%lld", config->dir, config->index_min);
|
||
|
remove(filename);
|
||
|
|
||
|
/* 更新最小索引 */
|
||
|
config->index_min++;
|
||
|
}
|
||
|
|
||
|
/* 初始化最大最小索引, 这套接口不能在不同线程同时调用, 例如 write 接口只能在单一线程调用, read可以在另一个线程调用,
|
||
|
但是 write 接口不能同时在两个线程调用 */
|
||
|
int32_t file_fifo_init(file_fifo_t *config)
|
||
|
{
|
||
|
DIR *dir = opendir(config->dir);
|
||
|
struct dirent *entry;
|
||
|
uint8_t first = 1;
|
||
|
int64_t index = 0;
|
||
|
|
||
|
config->index_max = 0;
|
||
|
config->index_min = 0;
|
||
|
|
||
|
if (!dir)
|
||
|
{
|
||
|
/* 创建目录 */
|
||
|
_file_fifo_dir_create(config->dir);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* 初始化最大最小 index */
|
||
|
while ((entry = readdir(dir)) != NULL)
|
||
|
{
|
||
|
if (entry->d_type != DT_REG)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (!isdigit(entry->d_name[0]))
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
index = strtoll(entry->d_name, NULL, 10);
|
||
|
if (first)
|
||
|
{
|
||
|
config->index_max = config->index_min = index;
|
||
|
first = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (index > config->index_max)
|
||
|
{
|
||
|
config->index_max = index;
|
||
|
}
|
||
|
|
||
|
if (index < config->index_min)
|
||
|
{
|
||
|
config->index_min = index;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* 非空目录最大索引要加一 */
|
||
|
if (!first)
|
||
|
{
|
||
|
config->index_max++;
|
||
|
}
|
||
|
|
||
|
closedir(dir);
|
||
|
}
|
||
|
|
||
|
return E_NONE;
|
||
|
}
|
||
|
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/
|