You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
663 lines
22 KiB
663 lines
22 KiB
2 years ago
|
/**
|
||
|
* @file file_list.c
|
||
|
* @author Chen Jihang (embedded@eseaoptics.com)
|
||
|
* @brief 文件列表
|
||
|
* @version 1.0
|
||
|
* @date 2022-08-25
|
||
|
*
|
||
|
* @copyright ESEA (c) 2020
|
||
|
*
|
||
|
*/
|
||
|
#include "file_list.h"
|
||
|
/**
|
||
|
* @brief 从文件中读取链表头
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_head 链表头
|
||
|
* @return int 0:成功 非0:失败
|
||
|
*/
|
||
|
int file_list_get_head(struct file_list *p_list,struct file_list_head *p_head)
|
||
|
{
|
||
|
FRESULT ret;
|
||
|
UINT btr;
|
||
|
UINT br;
|
||
|
ret=f_lseek(&p_list->fp,0);
|
||
|
if(ret!=FR_OK){
|
||
|
return -1;
|
||
|
}
|
||
|
btr=sizeof(struct file_list_head);
|
||
|
ret=f_read(&p_list->fp,p_head,btr,&br);
|
||
|
if(ret!=FR_OK || btr!=br){
|
||
|
return -2;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 将链表头写入文件
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_head 链表头
|
||
|
* @return int 0:成功 非0:失败
|
||
|
*/
|
||
|
int file_list_put_head(struct file_list *p_list,struct file_list_head *p_head)
|
||
|
{
|
||
|
FRESULT ret;
|
||
|
UINT btw;
|
||
|
UINT bw;
|
||
|
ret=f_lseek(&p_list->fp,0);
|
||
|
if(ret!=FR_OK){
|
||
|
return -1;
|
||
|
}
|
||
|
btw=sizeof(struct file_list_head);
|
||
|
ret=f_write(&p_list->fp,p_head,btw,&bw);
|
||
|
if(ret!=FR_OK || btw!=bw){
|
||
|
return -2;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 从文件中获取链表节点
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_node 链表节点
|
||
|
* @param file_pointer 文件指针
|
||
|
* @return int 0:成功 非0:失败
|
||
|
*/
|
||
|
int file_list_get_node(struct file_list *p_list,struct file_list_node *p_node,uint64_t file_pointer)
|
||
|
{
|
||
|
FRESULT ret;
|
||
|
UINT btr;
|
||
|
UINT br;
|
||
|
ret=f_lseek(&p_list->fp,file_pointer);
|
||
|
if(ret!=FR_OK){
|
||
|
return -1;
|
||
|
}
|
||
|
btr=sizeof(struct file_list_node);
|
||
|
ret=f_read(&p_list->fp,p_node,btr,&br);
|
||
|
if(ret!=FR_OK || btr!=br){
|
||
|
return -2;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 将链表节点写入文件
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_node 链表节点
|
||
|
* @return int 0:成功 非0:失败
|
||
|
*/
|
||
|
int file_list_put_node(struct file_list *p_list,struct file_list_node *p_node)
|
||
|
{
|
||
|
FRESULT ret;
|
||
|
UINT btw;
|
||
|
UINT bw;
|
||
|
ret=f_lseek(&p_list->fp,p_node->file_pointer_this);
|
||
|
if(ret!=FR_OK){
|
||
|
return -1;
|
||
|
}
|
||
|
btw=sizeof(struct file_list_node);
|
||
|
ret=f_write(&p_list->fp,p_node,btw,&bw);
|
||
|
if(ret!=FR_OK || btw!=bw){
|
||
|
return -2;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 从指定链表节点中获取数据
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_node 链表节点
|
||
|
* @param p_data 数据缓冲区
|
||
|
* @param base_addr 数据在链表节点中的基地址
|
||
|
* @param size 要获取的数据长度
|
||
|
* @return int 0:成功 非0:失败
|
||
|
*/
|
||
|
int file_list_get_data(struct file_list *p_list,struct file_list_node *p_node,uint8_t *p_data,uint64_t base_addr,uint64_t size)
|
||
|
{
|
||
|
FRESULT ret;
|
||
|
UINT btr;
|
||
|
UINT br;
|
||
|
ret=f_lseek(&p_list->fp,p_node->file_pointer_this+sizeof(struct file_list_node)+base_addr);
|
||
|
if(ret!=FR_OK){
|
||
|
return -1;
|
||
|
}
|
||
|
btr=size;
|
||
|
ret=f_read(&p_list->fp,p_data,btr,&br);
|
||
|
if(ret!=FR_OK || btr!=br){
|
||
|
return -2;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 将数据写入指定链表节点中
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_node 链表节点
|
||
|
* @param p_data 要写入的数据
|
||
|
* @param base_addr 数据在链表节点中的基地址
|
||
|
* @param size 要写入的数据长度
|
||
|
* @return int 0:成功 非0:失败
|
||
|
*/
|
||
|
int file_list_put_data(struct file_list *p_list,struct file_list_node *p_node,uint8_t *p_data,uint64_t base_addr,uint64_t size)
|
||
|
{
|
||
|
FRESULT ret;
|
||
|
UINT btw;
|
||
|
UINT bw;
|
||
|
ret=f_lseek(&p_list->fp,p_node->file_pointer_this+sizeof(struct file_list_node)+base_addr);
|
||
|
if(ret!=FR_OK){
|
||
|
return -1;
|
||
|
}
|
||
|
btw=size;
|
||
|
ret=f_write(&p_list->fp,p_data,btw,&bw);
|
||
|
if(ret!=FR_OK || btw!=bw){
|
||
|
return -2;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 使用指定字符填充链表节点数据
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_node 链表节点
|
||
|
* @param data_to_fill 要填充的字符
|
||
|
* @return int 0:成功 非0:失败
|
||
|
*/
|
||
|
int file_list_fill_data(struct file_list *p_list,struct file_list_node *p_node,uint8_t data_to_fill)
|
||
|
{
|
||
|
FRESULT ret;
|
||
|
UINT btw;
|
||
|
UINT bw;
|
||
|
uint64_t i;
|
||
|
ret=f_lseek(&p_list->fp,p_node->file_pointer_this+sizeof(struct file_list_node));
|
||
|
if(ret!=FR_OK){
|
||
|
return -1;
|
||
|
}
|
||
|
for(i=0;i<p_node->size;i++){
|
||
|
btw=1;
|
||
|
ret=f_write(&p_list->fp,&data_to_fill,btw,&bw);
|
||
|
if(ret!=FR_OK || btw!=bw){
|
||
|
return -2;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 使用指定文件路径创建链表
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param path 文件路径
|
||
|
* @return struct file_list* 成功:p_list 失败:NULL
|
||
|
*/
|
||
|
struct file_list *file_list_create(struct file_list *p_list,char *path)
|
||
|
{
|
||
|
FRESULT ret;
|
||
|
ret=f_open(&p_list->fp,path,FA_CREATE_ALWAYS|FA_READ|FA_WRITE);
|
||
|
if(ret!=FR_OK){
|
||
|
return NULL;
|
||
|
}
|
||
|
p_list->list_head.file_pointer_used_first=0;
|
||
|
p_list->list_head.file_pointer_used_last=0;
|
||
|
p_list->list_head.file_pointer_free_first=sizeof(struct file_list_head);
|
||
|
p_list->list_head.file_pointer_free_last=p_list->list_head.file_pointer_free_first;
|
||
|
p_list->free_node_now.file_pointer_last=0;
|
||
|
p_list->free_node_now.file_pointer_next=0;
|
||
|
p_list->free_node_now.file_pointer_this=p_list->list_head.file_pointer_free_last;
|
||
|
p_list->free_node_now.size=0xffffffffffffffff;
|
||
|
p_list->used_node_now.size_used=0;
|
||
|
p_list->used_node_now.file_pointer_last=0;
|
||
|
p_list->used_node_now.file_pointer_next=0;
|
||
|
p_list->used_node_now.file_pointer_this=0;
|
||
|
p_list->used_node_now.size=0;
|
||
|
p_list->used_node_now.size_used=0;
|
||
|
if(file_list_put_head(p_list,&p_list->list_head)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
if(file_list_put_node(p_list,&p_list->free_node_now)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
f_sync(&p_list->fp);
|
||
|
return p_list;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 使用指定文件路径打开链表,若文件不存在则创建新的链表
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param path 文件路径
|
||
|
* @return struct file_list* 成功:p_list 失败:NULL
|
||
|
*/
|
||
|
struct file_list *file_list_open(struct file_list *p_list,char *path)
|
||
|
{
|
||
|
FRESULT ret;
|
||
|
ret=f_open(&p_list->fp,path,FA_READ|FA_WRITE);
|
||
|
if(ret!=FR_OK){
|
||
|
return file_list_create(p_list,path);
|
||
|
}
|
||
|
if(file_list_get_head(p_list,&p_list->list_head)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
if(p_list->list_head.file_pointer_used_first!=0){
|
||
|
if(file_list_get_node(p_list,&p_list->used_node_now,p_list->list_head.file_pointer_used_first)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
p_list->used_node_now.file_pointer_last=0;
|
||
|
p_list->used_node_now.file_pointer_next=0;
|
||
|
p_list->used_node_now.file_pointer_this=0;
|
||
|
p_list->used_node_now.size=0;
|
||
|
}
|
||
|
if(file_list_get_node(p_list,&p_list->free_node_now,p_list->list_head.file_pointer_free_first)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
f_sync(&p_list->fp);
|
||
|
return p_list;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 关闭链表
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @return int 0:成功 非0:失败
|
||
|
*/
|
||
|
int file_list_close(struct file_list *p_list)
|
||
|
{
|
||
|
FRESULT ret;
|
||
|
ret=f_sync(&p_list->fp);
|
||
|
if(ret!=FR_OK){
|
||
|
return -1;
|
||
|
}
|
||
|
ret=f_close(&p_list->fp);
|
||
|
if(ret!=FR_OK){
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 合并未使用的链表节点
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_free_node 未使用的链表节点
|
||
|
* @return int 0:成功 非0:失败
|
||
|
*/
|
||
|
int file_list_merge_free_node(struct file_list *p_list,struct file_list_node *p_free_node)
|
||
|
{
|
||
|
struct file_list_node last_free_node;
|
||
|
struct file_list_node next_free_node;
|
||
|
struct file_list_node this_free_node;
|
||
|
this_free_node.size=p_free_node->size;
|
||
|
this_free_node.file_pointer_last=p_free_node->file_pointer_last;
|
||
|
this_free_node.file_pointer_next=p_free_node->file_pointer_next;
|
||
|
this_free_node.file_pointer_this=p_free_node->file_pointer_this;
|
||
|
if(p_free_node->file_pointer_last!=0){
|
||
|
if(file_list_get_node(p_list,&last_free_node,p_free_node->file_pointer_last)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
if(last_free_node.file_pointer_this+last_free_node.size+sizeof(struct file_list_node)==last_free_node.file_pointer_next){
|
||
|
// printf("<Merge [%llX,%llX]-->%llX,Size [%llX,%llX]-->%llX\n",last_free_node.file_pointer_this,this_free_node.file_pointer_this,last_free_node.file_pointer_this,last_free_node.size,this_free_node.size,this_free_node.size+last_free_node.size+sizeof(struct file_list_node));
|
||
|
this_free_node.file_pointer_last=last_free_node.file_pointer_last;
|
||
|
this_free_node.file_pointer_this=last_free_node.file_pointer_this;
|
||
|
this_free_node.size+=last_free_node.size+sizeof(struct file_list_node);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
if(p_free_node->file_pointer_next!=0){
|
||
|
if(file_list_get_node(p_list,&next_free_node,p_free_node->file_pointer_next)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
if(this_free_node.file_pointer_this+this_free_node.size+sizeof(struct file_list_node)==this_free_node.file_pointer_next){
|
||
|
// printf(">Merge [%llX,%llX]-->%llX,Size [%llX,%llX]-->%llX\n",this_free_node.file_pointer_this,next_free_node.file_pointer_this,this_free_node.file_pointer_this,this_free_node.size,next_free_node.size,this_free_node.size+next_free_node.size+sizeof(struct file_list_node));
|
||
|
this_free_node.file_pointer_next=next_free_node.file_pointer_next;
|
||
|
this_free_node.size+=next_free_node.size+sizeof(struct file_list_node);
|
||
|
if(this_free_node.file_pointer_next!=0){
|
||
|
if(file_list_get_node(p_list,&next_free_node,this_free_node.file_pointer_next)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
next_free_node.file_pointer_last=this_free_node.file_pointer_this;
|
||
|
if(file_list_put_node(p_list,&next_free_node)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
p_list->list_head.file_pointer_free_last=this_free_node.file_pointer_this;
|
||
|
if(file_list_put_head(p_list,&p_list->list_head)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
next_free_node.file_pointer_last=this_free_node.file_pointer_this;
|
||
|
}
|
||
|
}
|
||
|
if(file_list_put_node(p_list,&this_free_node)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
if(this_free_node.file_pointer_next!=0){
|
||
|
if(file_list_put_node(p_list,&next_free_node)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
p_list->free_node_now.file_pointer_last=this_free_node.file_pointer_last;
|
||
|
p_list->free_node_now.file_pointer_next=this_free_node.file_pointer_next;
|
||
|
p_list->free_node_now.file_pointer_this=this_free_node.file_pointer_this;
|
||
|
p_list->free_node_now.size=this_free_node.size;
|
||
|
return 0;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 分配一个新的链表节点
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param size 要存储的数据大小
|
||
|
* @return struct file_list_node* 成功:新的链表节点 失败:NULL
|
||
|
*/
|
||
|
struct file_list_node *file_list_alloc(struct file_list *p_list,uint64_t size)
|
||
|
{
|
||
|
struct file_list_node last_free_node;
|
||
|
struct file_list_node this_free_node;
|
||
|
struct file_list_node next_free_node;
|
||
|
uint64_t file_pointer;
|
||
|
this_free_node.file_pointer_last=0;
|
||
|
this_free_node.file_pointer_next=0;
|
||
|
this_free_node.file_pointer_this=0;
|
||
|
this_free_node.size=0;
|
||
|
file_pointer=p_list->list_head.file_pointer_free_first;
|
||
|
do{
|
||
|
last_free_node.file_pointer_last=this_free_node.file_pointer_last;
|
||
|
last_free_node.file_pointer_next=this_free_node.file_pointer_next;
|
||
|
last_free_node.file_pointer_this=this_free_node.file_pointer_this;
|
||
|
last_free_node.size=this_free_node.size;
|
||
|
if(file_list_get_node(p_list,&this_free_node,file_pointer)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
file_pointer=this_free_node.file_pointer_next;
|
||
|
}while(this_free_node.size<size);
|
||
|
p_list->used_node_now.size=this_free_node.size;
|
||
|
p_list->free_node_now.file_pointer_last=this_free_node.file_pointer_last;
|
||
|
p_list->free_node_now.file_pointer_next=this_free_node.file_pointer_next;
|
||
|
p_list->free_node_now.file_pointer_this=this_free_node.file_pointer_this;
|
||
|
p_list->free_node_now.size=this_free_node.size;
|
||
|
p_list->used_node_now.file_pointer_this=this_free_node.file_pointer_this;
|
||
|
p_list->used_node_now.file_pointer_next=0;
|
||
|
p_list->used_node_now.size_used=size;
|
||
|
if(this_free_node.file_pointer_last!=0){
|
||
|
if(file_list_get_node(p_list,&last_free_node,this_free_node.file_pointer_last)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
if(this_free_node.size>=size+sizeof(struct file_list_node)){
|
||
|
p_list->free_node_now.file_pointer_last=last_free_node.file_pointer_this;
|
||
|
p_list->free_node_now.file_pointer_this=p_list->used_node_now.file_pointer_this+size+sizeof(struct file_list_node);
|
||
|
last_free_node.file_pointer_next=p_list->free_node_now.file_pointer_this;
|
||
|
}
|
||
|
else{
|
||
|
last_free_node.file_pointer_next=this_free_node.file_pointer_next;
|
||
|
|
||
|
}
|
||
|
if(file_list_put_node(p_list,&last_free_node)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
if(this_free_node.size>=size+sizeof(struct file_list_node)){
|
||
|
p_list->free_node_now.file_pointer_this=p_list->used_node_now.file_pointer_this+size+sizeof(struct file_list_node);
|
||
|
p_list->list_head.file_pointer_free_first=p_list->free_node_now.file_pointer_this;
|
||
|
}
|
||
|
else{
|
||
|
p_list->list_head.file_pointer_free_first=this_free_node.file_pointer_next;
|
||
|
}
|
||
|
}
|
||
|
if(this_free_node.file_pointer_next!=0){
|
||
|
if(file_list_get_node(p_list,&next_free_node,this_free_node.file_pointer_next)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
if(this_free_node.size>=size+sizeof(struct file_list_node)){
|
||
|
p_list->free_node_now.file_pointer_this=p_list->used_node_now.file_pointer_this+size+sizeof(struct file_list_node);
|
||
|
p_list->free_node_now.file_pointer_next=next_free_node.file_pointer_this;
|
||
|
next_free_node.file_pointer_last=p_list->free_node_now.file_pointer_this;
|
||
|
}
|
||
|
else{
|
||
|
next_free_node.file_pointer_last=this_free_node.file_pointer_last;
|
||
|
}
|
||
|
if(file_list_put_node(p_list,&next_free_node)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
if(this_free_node.size>=size+sizeof(struct file_list_node)){
|
||
|
p_list->free_node_now.file_pointer_this=p_list->used_node_now.file_pointer_this+size+sizeof(struct file_list_node);
|
||
|
p_list->list_head.file_pointer_free_last=p_list->free_node_now.file_pointer_this;
|
||
|
}
|
||
|
else{
|
||
|
p_list->list_head.file_pointer_free_last=this_free_node.file_pointer_last;
|
||
|
}
|
||
|
}
|
||
|
if(this_free_node.size>=size+sizeof(struct file_list_node)){
|
||
|
p_list->used_node_now.size=size;
|
||
|
p_list->free_node_now.size-=size+sizeof(struct file_list_node);
|
||
|
if(file_list_put_node(p_list,&p_list->free_node_now)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
if(file_list_put_head(p_list,&p_list->list_head)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
return &p_list->used_node_now;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 释放链表节点
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_node_to_free 要释放的链表节点
|
||
|
* @return int 0:成功 非0:失败
|
||
|
*/
|
||
|
int file_list_free_node(struct file_list *p_list,struct file_list_node *p_node_to_free)
|
||
|
{
|
||
|
struct file_list_node last_free_node;
|
||
|
struct file_list_node next_free_node;
|
||
|
uint64_t file_pointer;
|
||
|
next_free_node.file_pointer_this=0;
|
||
|
next_free_node.file_pointer_last=0;
|
||
|
next_free_node.size=0;
|
||
|
file_pointer=p_list->list_head.file_pointer_free_first;
|
||
|
do{
|
||
|
last_free_node.file_pointer_last=next_free_node.file_pointer_last;
|
||
|
last_free_node.file_pointer_this=next_free_node.file_pointer_this;
|
||
|
last_free_node.size=next_free_node.size;
|
||
|
if(file_list_get_node(p_list,&next_free_node,file_pointer)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
file_pointer=next_free_node.file_pointer_next;
|
||
|
}while(next_free_node.file_pointer_this<p_node_to_free->file_pointer_this);
|
||
|
if(last_free_node.file_pointer_this!=0){
|
||
|
last_free_node.file_pointer_next=p_node_to_free->file_pointer_this;
|
||
|
if(file_list_put_node(p_list,&last_free_node)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
p_list->list_head.file_pointer_free_first=p_node_to_free->file_pointer_this;
|
||
|
}
|
||
|
next_free_node.file_pointer_last=p_node_to_free->file_pointer_this;
|
||
|
p_node_to_free->file_pointer_last=last_free_node.file_pointer_this;
|
||
|
p_node_to_free->file_pointer_next=next_free_node.file_pointer_this;
|
||
|
if(file_list_put_node(p_list,&next_free_node)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
if(file_list_put_node(p_list,p_node_to_free)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
return file_list_merge_free_node(p_list,p_node_to_free);
|
||
|
}
|
||
|
/**
|
||
|
* @brief 从链表中删除指定节点
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_used_node 要删除的节点
|
||
|
* @return int 0:成功 非0:失败
|
||
|
*/
|
||
|
int file_list_del_node(struct file_list *p_list,struct file_list_node *p_used_node)
|
||
|
{
|
||
|
struct file_list_node last_used_node;
|
||
|
struct file_list_node next_used_node;
|
||
|
if(p_used_node->file_pointer_last!=0){
|
||
|
if(file_list_get_node(p_list,&last_used_node,p_used_node->file_pointer_last)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
last_used_node.file_pointer_next=p_used_node->file_pointer_next;
|
||
|
if(file_list_put_node(p_list,&last_used_node)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
p_list->list_head.file_pointer_used_first=p_used_node->file_pointer_next;
|
||
|
}
|
||
|
if(p_used_node->file_pointer_next!=0){
|
||
|
if(file_list_get_node(p_list,&next_used_node,p_used_node->file_pointer_next)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
next_used_node.file_pointer_last=p_used_node->file_pointer_last;
|
||
|
if(file_list_put_node(p_list,&next_used_node)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
p_list->list_head.file_pointer_used_last=p_used_node->file_pointer_last;
|
||
|
}
|
||
|
if(file_list_put_head(p_list,&p_list->list_head)!=0){
|
||
|
return -1;
|
||
|
}
|
||
|
return file_list_free_node(p_list,p_used_node);
|
||
|
}
|
||
|
/**
|
||
|
* @brief 向链表最后插入新的节点
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param size 要存储的数据大小
|
||
|
* @return struct file_list_node* 成功:新的节点 失败:NULL
|
||
|
*/
|
||
|
struct file_list_node *file_list_add_node(struct file_list *p_list,uint64_t size)
|
||
|
{
|
||
|
struct file_list_node last_used_node;
|
||
|
struct file_list_node *pnode;
|
||
|
pnode=file_list_alloc(p_list,size);
|
||
|
if(pnode==NULL){
|
||
|
return NULL;
|
||
|
}
|
||
|
pnode->file_pointer_last=0;
|
||
|
pnode->file_pointer_next=0;
|
||
|
if(p_list->list_head.file_pointer_used_last!=0){
|
||
|
pnode->file_pointer_last=p_list->list_head.file_pointer_used_last;
|
||
|
if(file_list_get_node(p_list,&last_used_node,pnode->file_pointer_last)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
last_used_node.file_pointer_next=pnode->file_pointer_this;
|
||
|
if(file_list_put_node(p_list,&last_used_node)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
p_list->list_head.file_pointer_used_last=pnode->file_pointer_this;
|
||
|
if(p_list->list_head.file_pointer_used_first==0){
|
||
|
p_list->list_head.file_pointer_used_first=pnode->file_pointer_this;
|
||
|
}
|
||
|
if(file_list_put_head(p_list,&p_list->list_head)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
if(file_list_put_node(p_list,pnode)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
f_sync(&p_list->fp);
|
||
|
return pnode;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 获取链表中第一个节点
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @return struct file_list_node* 成功:第一个节点 失败:NULL
|
||
|
*/
|
||
|
struct file_list_node *file_list_get_first_node(struct file_list *p_list)
|
||
|
{
|
||
|
if(p_list->list_head.file_pointer_used_first==0){
|
||
|
return NULL;
|
||
|
}
|
||
|
if(file_list_get_node(p_list,&p_list->used_node_now,p_list->list_head.file_pointer_used_first)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
return &p_list->used_node_now;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 获取链表中下一个节点
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @return struct file_list_node* 成功:下一个节点 失败:NULL
|
||
|
*/
|
||
|
struct file_list_node *file_list_get_next_node(struct file_list *p_list)
|
||
|
{
|
||
|
if(p_list->used_node_now.file_pointer_next==0){
|
||
|
return NULL;
|
||
|
}
|
||
|
if(file_list_get_node(p_list,&p_list->used_node_now,p_list->used_node_now.file_pointer_next)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
return &p_list->used_node_now;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 获取链表中最后一个节点
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @return struct file_list_node* 成功:最后一个节点 失败:NULL
|
||
|
*/
|
||
|
struct file_list_node *file_list_get_last_node(struct file_list *p_list)
|
||
|
{
|
||
|
if(p_list->used_node_now.file_pointer_last==0){
|
||
|
return NULL;
|
||
|
}
|
||
|
if(file_list_get_node(p_list,&p_list->used_node_now,p_list->used_node_now.file_pointer_last)!=0){
|
||
|
return NULL;
|
||
|
}
|
||
|
return &p_list->used_node_now;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 获取链表中数据大小
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_node 链表节点
|
||
|
* @return uint64_t 改节点中的数据大小
|
||
|
*/
|
||
|
uint64_t file_list_get_node_size(struct file_list *p_list,struct file_list_node *p_node)
|
||
|
{
|
||
|
return p_node->size_used;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 获取指定节点中的数据
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_node 链表节点
|
||
|
* @param buf 数据缓冲区
|
||
|
* @param base_addr 要获取的数据在链表节点中的基地址
|
||
|
* @param size 要获取的数据大小
|
||
|
* @return uint64_t 实际获取的数据大小
|
||
|
*/
|
||
|
uint64_t file_list_get_node_data(struct file_list *p_list,struct file_list_node *p_node,void *buf,uint64_t base_addr,uint64_t size)
|
||
|
{
|
||
|
size=(base_addr+size>p_node->size_used)?p_node->size_used-base_addr:size;
|
||
|
if(file_list_get_data(p_list,p_node,buf,base_addr,size)!=0){
|
||
|
return 0;
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
/**
|
||
|
* @brief 向指定节点中写入数据
|
||
|
*
|
||
|
* @param p_list file_list描述符
|
||
|
* @param p_node 链表节点
|
||
|
* @param buf 要写入的数据
|
||
|
* @param base_addr 要写入的数据的基地址
|
||
|
* @param size 要写入的数据大小
|
||
|
* @return uint64_t 实际写入的数据大小
|
||
|
*/
|
||
|
uint64_t file_list_put_node_data(struct file_list *p_list,struct file_list_node *p_node,void *buf,uint64_t base_addr,uint64_t size)
|
||
|
{
|
||
|
size=(base_addr+size>p_node->size_used)?p_node->size_used-base_addr:size;
|
||
|
if(file_list_put_data(p_list,p_node,buf,base_addr,size)!=0){
|
||
|
return 0;
|
||
|
}
|
||
|
f_sync(&p_list->fp);
|
||
|
return size;
|
||
|
}
|