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.8 KiB
C

/******************************************************************************
* 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>&copy; 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[512];
int32_t size = 0;
if (config->index_max - config->index_min >= config->files_max)
{
return E_FULL;
}
/* 确认文件名 */
snprintf(filename, sizeof(filename), "%s/%ld", 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[512];
int32_t size = 0;
if (config->index_max == config->index_min)
{
return E_EMPTY;
}
/* 确认文件名 */
snprintf(filename, sizeof(filename), "%s/%ld", 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[512];
snprintf(filename, sizeof(filename), "%s/%ld", 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 ****************/