vFile文件的精读
typedef struct
{uint8_t *curptr;uint32_t offset;uint32_t size;
}vFile;
作用:
定义了一个虚拟文件结构体 vFile
,用于在内存中模拟文件操作。
curptr
:指向数据的起始地址(内存中的“文件内容”)。offset
:当前读写位置(偏移量)。size
:文件总大小(字节数)。
void *vmalloc(size_t size)
{if (bs_user_func.bs_malloc == NULL){return NULL;}return bs_user_func.bs_malloc((size_t)size);
}
作用:
- 封装了内存分配操作。
- 如果用户没有提供分配函数(
bs_malloc
),返回NULL
。 - 否则调用用户自定义的分配函数分配指定大小的内存。
这里就会和函数指针类型定义联系起来
void vfree(void *ptr)
{if (bs_user_func.bs_free == NULL){return;}bs_user_func.bs_free(ptr);
}
作用:
- 封装了内存释放操作。
- 如果用户没有提供释放函数(
bs_free
),什么也不做。 - 否则调用用户自定义的释放函数释放内存。
vFile *vfopen(const uint8_t *dp, uint32_t size)
{vFile *fp = NULL;fp = vmalloc(sizeof(vFile));if (fp != NULL){fp->curptr = (uint8_t *)dp;fp->offset = 0;fp->size = size;}return (fp);
}
作用:
- 这是“打开虚拟文件”的函数。
- 分配一个
vFile
结构体,并初始化:curptr
指向数据的起始地址(把内存当作文件内容)。offset
置为0,表示文件指针在开头。size
记录数据总长度。
- 返回新建的虚拟文件指针。
int vfread(vFile *fp, uint8_t *buff, int len)
{if (fp != NULL){if ((fp->offset + len) > fp->size){len = fp->size - fp->offset;}memcpy(buff, fp->curptr + fp->offset, len);fp->offset += len;return (len);}return (0);
}
作用:
- 从虚拟文件当前偏移处读取
len
字节到buff
。 - 如果请求读取超出文件末尾,只读取剩余部分。
- 读取后自动更新文件偏移。
- 返回实际读取的字节数,若文件指针无效则返回0。
假设当前文件总大小为 fp->size
,当前偏移为 fp->offset
,你请求读取 len
字节。
如果直接 len = fp->size
,那么你会从当前位置把整个文件内容都读一遍,这显然不对,因为你可能已经读到文件中间了。
正确做法是:
- 只允许读取当前位置到文件末尾的剩余部分,也就是
fp->size - fp->offset
字节。 - 如果请求的
len
比剩余的还多,就把len
改成剩余的长度。
举例说明:
- 文件总长 100 字节,当前偏移 80,你请求读 30 字节。
- 剩余可读 = 100 - 80 = 20 字节。
- 只能读 20 字节,不能读 100 字节(否则会越界)。
所以,
if ((fp->offset + len) > fp->size){len = fp->size - fp->offset;}
这样写是为了防止越界,只读取剩余部分,保证安全。
uint8_t *vfgetpos(vFile *fp, uint32_t *position)
{if (fp != NULL){*position = fp->offset;return (fp->curptr + fp->offset);}return (NULL);
}
作用:
- 获取当前文件偏移(
offset
),并返回当前位置的数据指针。 - 如果文件指针无效,返回NULL。
int vfsetpos(vFile *fp, uint32_t position)
{if (fp != NULL){fp->offset = position;return (fp->offset);}return -1;
}
作用:
- 设置文件偏移(类似于fseek),让下次读写从新位置开始。
- 返回设置后的偏移值,若文件指针无效返回-1。
int vfclose(vFile *fp)
{if (fp != NULL){vfree(fp);}return (0);
}
作用:
- 关闭虚拟文件,释放结构体内存。
- 总是返回0。
uint32_t vfgetlen(vFile *fp)
{return (fp->size);
}
作用:
- 返回虚拟文件的总长度(字节数)。