/* ioapi.c -- IO base function header for compress/uncompress .zip files using zlib + zip or unzip API Version 1.01e, February 12th, 2005 Copyright (C) 1998-2005 Gilles Vollant */ #include #include #include #include #include "zlib.h" #include "ioapi.h" #include #include #include typedef struct { loff_t offset; // 当前文件偏移 loff_t size; // 文件大小 const char *fname; // 文件名 int error; // 错误标志 } uboot_file; #ifdef __UBOOT__ #include #include //typedef loff_t off_t; #define FILE struct fs_dir_stream #endif /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ #ifndef SEEK_CUR #define SEEK_CUR 1 #endif #ifndef SEEK_END #define SEEK_END 2 #endif #ifndef SEEK_SET #define SEEK_SET 0 #endif voidpf ZCALLBACK fopen_file_func OF(( voidpf opaque, const char* filename, int mode)); uLong ZCALLBACK fread_file_func OF(( voidpf opaque, voidpf stream, void* buf, uLong size)); uLong ZCALLBACK fwrite_file_func OF(( voidpf opaque, voidpf stream, const void* buf, uLong size)); long ZCALLBACK ftell_file_func OF(( voidpf opaque, voidpf stream)); long ZCALLBACK fseek_file_func OF(( voidpf opaque, voidpf stream, uLong offset, int origin)); int ZCALLBACK fclose_file_func OF(( voidpf opaque, voidpf stream)); int ZCALLBACK ferror_file_func OF(( voidpf opaque, voidpf stream)); #ifdef __UBOOT__ voidpf ZCALLBACK fopen_file_func(voidpf opaque, const char* filename, int mode) { loff_t file_size = 0; if ((mode & ZLIB_FILEFUNC_MODE_READ) == 0) return NULL; if (fs_set_blk_dev("usb", "0", FS_TYPE_FAT)) { printf("Can't set block device\n"); return NULL; } if (fs_size(filename, &file_size) < 0) { printf("ZIP file not found: %s\n", filename); return NULL; } uboot_file *file = malloc(sizeof(uboot_file)); if (!file) return NULL; file->offset = 0; file->fname = filename; file->size = file_size; file->error = 0; return (voidpf)file; } #else voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) voidpf opaque; const char* filename; int mode; { FILE* file = NULL; const char* mode_fopen = NULL; if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) mode_fopen = "rb"; else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) mode_fopen = "r+b"; else if (mode & ZLIB_FILEFUNC_MODE_CREATE) mode_fopen = "wb"; if ((filename!=NULL) && (mode_fopen != NULL)) file = fopen(filename, mode_fopen); return file; } #endif uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) voidpf opaque; voidpf stream; void* buf; uLong size; { uboot_file *file = (uboot_file*)stream; loff_t actread; if (fs_set_blk_dev("usb", "0", FS_TYPE_FAT)) { printf("Can't set block device\n"); return 1; } // 计算可读字节数 uLong max_size = file->size - file->offset; if (size > max_size) size = max_size; // 调用 U-Boot FS API 读取 if (fs_read(file->fname, (ulong)buf, file->offset, size, &actread)) { file->error = -1; printf(">>>>>>>>>>>>>>>>>>>>>>>>read error!!!\n"); return 0; } file->offset += actread; return (uLong)actread; } uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) voidpf opaque; voidpf stream; const void* buf; uLong size; { return 0; } long ZCALLBACK ftell_file_func (opaque, stream) voidpf opaque; voidpf stream; { return (unsigned int)((uboot_file*)stream)->offset; } long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) voidpf opaque; voidpf stream; uLong offset; int origin; { uboot_file *file = (uboot_file*)stream; loff_t new_offset; switch (origin) { case ZLIB_FILEFUNC_SEEK_SET: new_offset = offset; break; case ZLIB_FILEFUNC_SEEK_CUR: new_offset = file->offset + offset; break; case ZLIB_FILEFUNC_SEEK_END: new_offset = file->size + offset; break; default: return -1; } if (new_offset < 0 || new_offset > file->size) return -1; file->offset = new_offset; return 0; } int ZCALLBACK fclose_file_func (opaque, stream) voidpf opaque; voidpf stream; { if (stream) { free(stream); return 0; } return -1; } int ZCALLBACK ferror_file_func (opaque, stream) voidpf opaque; voidpf stream; { return ((uboot_file*)stream)->error; } void fill_fopen_filefunc (pzlib_filefunc_def) zlib_filefunc_def* pzlib_filefunc_def; { pzlib_filefunc_def->zopen_file = fopen_file_func; pzlib_filefunc_def->zread_file = fread_file_func; pzlib_filefunc_def->zwrite_file = NULL;//fwrite_file_func; pzlib_filefunc_def->ztell_file = ftell_file_func; pzlib_filefunc_def->zseek_file = fseek_file_func; pzlib_filefunc_def->zclose_file = fclose_file_func; pzlib_filefunc_def->zerror_file = ferror_file_func; pzlib_filefunc_def->opaque = NULL; }