⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.c

📁 新一代基于事件的嵌入式操作系统dyos在三星的s3c44b0的arm芯片上的完整移植代码
💻 C
📖 第 1 页 / 共 5 页
字号:
{
    uint32_t buffing_len;   //读缓冲区内的数据长度
    struct rw_para *pl_read_para = (struct rw_para *)read_para;
    uint32_t read_len;  //需要读取的数据长度
    sint64_t stock_size;
    uint32_t result;
    struct file_rsc *fp = (struct file_rsc *)file;
    struct st_DBX_device_tag *DBX_device_tag;
    DBX_device_tag = (struct st_DBX_device_tag*)
                            DBX_lhdl->dev_interfase->private_tag;
    read_len = pl_read_para->nmemb * pl_read_para->size;
    //查询物理设备有多少数据可读,文件尺寸并不可靠,不能用
    stock_size = DBX_device_tag->query_file_stocks(fp);
    if(stock_size >= read_len)
    {//物理设备上有足够的数据
        //读取物理设备
        result = DBX_device_tag->read(fp,(uint8_t*)buf,read_len);
        result = result / pl_read_para->nmemb;
    }else
    {//物理设备上没有足够的数据,需要调整读取数量,以确保读到整数个单元
        read_len = (stock_size / pl_read_para->nmemb) * pl_read_para->nmemb;
        //需要从物理设备读取的数据字节数
        read_len = read_len * pl_read_para->size;
        //读取物理设备
        result = DBX_device_tag->read(fp,(uint8_t*)(buf+buffing_len),read_len);
        result = result / pl_read_para->nmemb;
    }

    return result;
}
//----测试字符串是否包含文件柜名-----------------------------------------------
//功能: 测试给定的字符串是否包含文件柜名
//参数: fullname,待检查的字符串
//返回: 含文件柜名,则返回文件柜名的长度,否则返回0
//备注: 内部函数,调用前先确保fullname是合法的字符串。
//----------------------------------------------------------------------------
uint16_t __djyfs_if_contain_DBX_name(char *fullname)
{
    uint16_t offset;
    for(offset = 0; offset < cn_DBX_name_limit+1; offset++)
    {
        if(fullname[offset] == ':')
            return offset;
    }
        return 0;
}

//----测试目录串是否绝对路径--------------------------------------------------
//功能: 测试目录串是否绝对路径
//参数: fullname,待检查的字符串
//返回: true = fullname是绝对路径,false = 不是绝对路径
//备注: 内部函数,调用前先确保fullname是合法的字符串。
//----------------------------------------------------------------------------
bool_t __djyfs_if_abs_path(char *fullname)
{
    if(fullname[0] == '\\')
    {
        return true;
    }else
    {
        if(__djyfs_if_contain_DBX_name(fullname) != 0)
            return true;
        else
            return false;
    }
}

//----测试目录串是否包含文件名--------------------------------------------------
//功能: 测试目录串是否包含文件名
//参数: fullname,待检查的字符串
//返回: true = fullname包含文件名,false = 不包含文件名
//备注: 内部函数,调用前先确保fullname是合法的字符串。
//----------------------------------------------------------------------------
bool_t __djyfs_if_contain_filename(char *fullname)
{
    //fullname是已经经过字符串长度合法性检查的指针
    if(fullname[strlen(fullname)-1] != '\\')
        return true;
    else
        return false;
}

//----查看文件(目录)是否已经打开----------------------------------------------
//功能: 查看一个文件(目录)是否已经打开,即看它是否在被打开的文件资源中
//参数: synname,待查的文件(目录)名
//返回: true = 已经打开,false = 未打开(或其他错误)
//备注: 调用前保证fullname是合法的字符串
//----------------------------------------------------------------------------
bool_t __djyfs_item_if_opened(struct st_DBX_device_tag *DBX_device_tag,
                              char *synname)
{
    struct file_rsc *parent,*son;
    uint16_t offset,name_len,index=0;
    char    name[256];

    if(__djyfs_if_abs_path(synname))
    {
        parent = DBX_device_tag->opened_root;  //从根目录开始操作
        offset = 1;
    }else
    {
        parent = pg_work_path;  //从当前路径开始操作
        offset = 0;
    }
    //synname是已经经过字符串长度合法性检查的指针
    name_len = strlen(synname);
    for( ; offset< name_len; offset++)
    {//沿路径逐级查看目录是否已经打开
        if(synname[offset] == '\\')    //遇到字符'\'
        {
            name[index] = '\0';
            index = 0;
            if((son=(struct file_rsc*)rsc_search_son(&parent->file_node,name))
                                            != NULL)
            {//目标已经打开
                parent = son;   //以当前打开的目录为下次使用的父目录
            }else
            {
                return false;
            }
        }else   //未遇到字符'\'。
        {
            name[index] = synname[offset];     //复制当前字符到文件名串
            index++;
        }
        if(index >= cn_file_name_limit)    //目录名长度超限。
            return false;
    }
    //至此,如果filename传入的是文件名(末字符不是'\'),name保存的是文件名,
    //index是串长度,串结束符'\0'未赋值,整个路径都已经打开。
    //如果filename出入是目录名,则name保存最后一个目录,且已经打开,index=0。
    if(index != 0)
    {
        name[index] = '\0';
        if(rsc_search_son(&parent->file_node,name) != NULL)
        {
            return true;        //文件已经打开
        }else
        {
            return false;       //文件尚未打开
        }
    }else
        return true;
}

//----删除文件(目录)----------------------------------------------------------
//功能:删除一个文件(目录),本函数不能删除非空目录,以及只读文件(目录)。要
//      删除只读文件,只有先把它改为非只读文件才能进行。本函数由文件柜的左手
//      控制函数调用,调用顺序:
//      用户调用remove
//      -->dev_ctrl
//      -->DBX_device->left_hand.io_ctrl
//      -->DBX_left_ctrl (用enum_DBX_remove命令)
//      -->__djyfs_DBX_remove_item
//参数: DBX_lhdl,被操作的文件柜
//      synname,文件名或者目录名字符串,文件和目录统称item
//返回:参考文件系统错误代码列表
//----------------------------------------------------------------------------
uint32_t __djyfs_DBX_remove_item(struct dev_handle *DBX_lhdl,char *synname)
{
    struct file_rsc item;
    struct st_DBX_device_tag *DBX_device_tag;
    DBX_device_tag = (struct st_DBX_device_tag *)
                                        (DBX_lhdl->dev_interfase->private_tag);
    if(__djyfs_item_if_opened(DBX_device_tag,synname) == true)
        return (uint32_t)enum_fs_object_opened;       //不能删除已经打开的对象
    if(__djyfs_if_abs_path(synname) == true)
    {//synname是当前文件柜的绝对路径
        if(!DBX_device_tag->lookfor_item(synname+1,
                                         DBX_device_tag->opened_root,&item))
            return (uint32_t)enum_fs_object_nonentity;   //被删除的对象不存在
    }else
    {//synname是相对与 pg_work_path 的相对路径
        if(!DBX_device_tag->lookfor_item(synname,pg_work_path,&item))
            return (uint32_t)enum_fs_object_nonentity;   //被删除的对象不存在
    }
    item.open_counter = 0;     //打开次数清零
    item.home_DBX = (struct pan_device*)DBX_lhdl->dev_interfase;
    if(item.attr.bits.read_only == true)
        return (uint32_t)enum_fs_object_readonly;       //不能删除只读对象
    if(item.attr.bits.folder)
    {//是个目录,需要判断是否空
        if(DBX_device_tag->check_folder(&item) != 0)
            return (uint32_t)enum_fs_folder_unblank;
    }
    if(DBX_device_tag->remove_item(&item))
        return enum_fs_no_error;
    else
        return enum_fs_remove_error;
}

//----目录(文件)改名-----------------------------------------------------------
//功能:把一个目录(文件)改名,不允许修改只读目录(文件)的名字,要修改只读文
//      件,必须先修改只读文件的属性,本函数由文件柜的左手控制函数调用,
//      调用顺序:
//      用户调用rename
//      -->dev_ctrl
//      -->DBX_device->left_hand.io_ctrl
//      -->DBX_left_ctrl (用enum_DBX_rename命令)
//      -->__DBX_rename_item
//参数: DBX_lhdl,被操作的文件柜
//      old_synname,文件或目录原名字符串,
//      newname,文件或目录的新名字字符串
//返回:参考文件系统错误代码列表
//----------------------------------------------------------------------------
uint32_t __DBX_rename_item(struct dev_handle *DBX_lhdl,
                            char *old_synname,char *newname)
{
    struct st_DBX_device_tag *DBX_device_tag;
    struct file_rsc item;
    DBX_device_tag = (struct st_DBX_device_tag *)
                                        (DBX_lhdl->dev_interfase->private_tag);
    if(__djyfs_item_if_opened(DBX_device_tag,old_synname) == true)
        return enum_fs_object_opened;       //不能改名已经打开的对象
    if(__djyfs_if_abs_path(old_synname)== true)
    {//old_synname是当前文件柜的绝对
        if(!DBX_device_tag->lookfor_item(old_synname+1,
                                         DBX_device_tag->opened_root,&item))
            return enum_fs_object_nonentity; //被改名的对象不存在
    }else
    {//old_synname是相对与 pg_work_path 的相对路径
        if(!DBX_device_tag->lookfor_item(old_synname,pg_work_path,&item))
            return enum_fs_object_nonentity; //被改名的对象不存在
    }
    if(item.attr.bits.read_only == true)
        return enum_fs_object_readonly;   //只读文件不允许改名
    //newname是已经经过字符串长度合法性检查的指针
    if(strlen(newname) <= cn_file_name_limit)//读取文件柜名字
        strcpy(item.name,newname);
    else
    {
        memcpy(item.name,newname,cn_file_name_limit);
        item.name[cn_file_name_limit] = '\0';
    }
    if( DBX_device_tag->rename_item(&item))
        return enum_fs_no_error;
    else
        return enum_fs_rename_error;
}
//----关闭文件(目录)----------------------------------------------------------
//功能:关闭一个文件(目录),本函数由文件柜的左手控制函数调用,调用顺序:
//      用户调用fclose
//      -->dev_ctrl
//      -->DBX_device->left_hand.io_ctrl
//      -->DBX_left_ctrl (用enum_DBX_close命令)
//      -->__DBX_close_item
//参数:DBX_lhdl,被关闭文件(目录)所属的文件柜
//      file,被关闭的文件(目录)指针
//返回:true=成功关闭则,false=失败
//----------------------------------------------------------------------------
bool_t __DBX_close_item(struct dev_handle *DBX_lhdl,struct file_rsc *fp)
{
    struct st_DBX_device_tag *DBX_device_tag;
    struct file_rsc *parent,*son;
    DBX_device_tag =(struct st_DBX_device_tag *)
                            (DBX_lhdl->dev_interfase->private_tag);
    if(fp->attr.bits.folder)
    {
        if(rsc_get_son(&fp->file_node) != NULL)
            return false;       //被关闭的目录仍有已经被打开的子项,不能关闭
    }
    //下面把文件从资源链表中删除,包括已经空的目录
    son = fp;
    parent = (struct file_rsc *)rsc_get_parent(&son->file_node);
    do
    {//从被删除结点开始,逐级向上删除空目录。空目录是指资源链表上的空目录结点,
     //而物理存储器上该目录可能不是空的
        if(son == pg_work_path)  //当前工作路径不能被删除
            break;
        DBX_device_tag->close_item(son);
        rsc_del_node(&son->file_node);   //从打开文件资源链表中删除结点
        mb_free(pg_content_pool,son);               //释放结点内存
        son = parent;               //下一循环释放父结点
        parent=(struct file_rsc*)rsc_get_parent(&parent->file_node);//父结点上移
        if(DBX_device_tag->opened_sum != 0)
            DBX_device_tag->opened_sum --;
    }while(son != DBX_device_tag->opened_root);    //直到根目录
    return true;
}

//----把文件写入到存储器------------------------------------------------------
//功能: 把文件写缓冲区的数据和buf中的数据一起写入到存储器中,并清空写缓冲区。
//      调用顺序:
//      用户调用fflush
//      -->dev_ctrl

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -