📄 cole.c
字号:
cole_closedir (COLEDIR *coledir, COLERRNO *colerrno){ free (coledir); return 0;}COLEDIRENT *cole_visiteddirentry (COLEDIR *coledir){ if (coledir->visited_entry.entry == 0xffffffffUL) return NULL; return &coledir->visited_entry;}COLEDIRENT *cole_nextdirentry (COLEDIR *coledir){ if (coledir->visited_entry.entry == 0xffffffffUL) return NULL; coledir->visited_entry.entry = coledir->fs->tree [ coledir->visited_entry.entry ].next; if (coledir->visited_entry.entry == 0xffffffffUL) return NULL; return &coledir->visited_entry;}/** * cole_direntry_isdir: * @coledirentry: directory entry to be tested. * * Tests if the directory entry @coledirentry is a directory. * * Returns: no zero if it is a directory, zero in other case. */intcole_direntry_isdir (COLEDIRENT *coledirentry){ return coledirentry->dir->fs->tree[ coledirentry->entry ].type == _COLE_TYPE_DIR;}/** * cole_direntry_isfile: * @coledirentry: directory entry to be tested. * * Tests if the directory entry @coledirentry is a file. * * Returns: no zero if it is a directory, zero in other case. */intcole_direntry_isfile (COLEDIRENT *coledirentry){ return coledirentry->dir->fs->tree[ coledirentry->entry ].type == _COLE_TYPE_FILE;}char *cole_direntry_getname (COLEDIRENT *coledirentry){ return coledirentry->dir->fs->tree[ coledirentry->entry ].name;}size_tcole_direntry_getsize (COLEDIRENT *coledirentry){ /* FIXME is it cast needed? */ return coledirentry->dir->fs->tree[ coledirentry->entry ].size;}longcole_direntry_getsec1 (COLEDIRENT *coledirentry){ /* seconds1 is U32, long is at least U32 in all plattforms, isn't it? */ return coledirentry->dir->fs->tree[ coledirentry->entry ].seconds1;}longcole_direntry_getsec2 (COLEDIRENT *coledirentry){ /* seconds2 is U32, long is at least U32 in all plattforms, isn't it? */ return coledirentry->dir->fs->tree[ coledirentry->entry ].seconds2;}longcole_direntry_getdays1 (COLEDIRENT *coledirentry){ /* days1 is U32, long is at least U32 in all plattforms, isn't it? */ return coledirentry->dir->fs->tree[ coledirentry->entry ].days1;}longcole_direntry_getdays2 (COLEDIRENT *coledirentry){ /* days2 is U32, long is at least U32 in all plattforms, isn't it? */ return coledirentry->dir->fs->tree[ coledirentry->entry ].days2;}char *cole_dir_getname (COLEDIR *coledir){ return coledir->fs->tree[ coledir->entry ].name;}size_tcole_dir_getsize (COLEDIR *coledir){ /* FIXME is it cast needed? */ return coledir->fs->tree[ coledir->entry ].size;}longcole_dir_getsec1 (COLEDIR *coledir){ /* seconds1 is U32, long is at least U32 in all plattforms, isn't it? */ return coledir->fs->tree[ coledir->entry ].seconds1;}longcole_dir_getsec2 (COLEDIR *coledir){ /* seconds2 is U32, long is at least U32 in all plattforms, isn't it? */ return coledir->fs->tree[ coledir->entry ].seconds2;}longcole_dir_getdays1 (COLEDIR *coledir){ /* days1 is U32, long is at least U32 in all plattforms, isn't it? */ return coledir->fs->tree[ coledir->entry ].days1;}longcole_dir_getdays2 (COLEDIR *coledir){ /* days2 is U32, long is at least U32 in all plattforms, isn't it? */ return coledir->fs->tree[ coledir->entry ].days2;}/** * cole_fopen: * @colefilesystem: filesystem in which @filename is in. * @filename: name of the file to open. * @colerrno: error value (COLE_EFILENOTFOUND, errors from calls * cole_opendir_rootdir(), cole_fopen_direntry() and * cole_locate_filename()). * * Opens the file with the name @filename in the filesystem @colefilesystem. * Currently, @filename must begin with a '/' character, it means @filename is * the absolute filename. * * Returns: a file in success, or NULL in other case. */struct _cole_fopen_info { COLEFILE *file; int succ; COLERRNO colerrno;};static COLE_LOCATE_ACTION_FUNC _cole_fopen_action;COLEFILE *cole_fopen (COLEFS *colefilesystem, char *filename, COLERRNO *colerrno){ struct _cole_fopen_info info; if (cole_locate_filename (colefilesystem, filename, &info, _cole_fopen_action, colerrno)) { /* couldn't locate the filename */ /* colerrno is set */ return NULL; } if (info.succ) return info.file; if (colerrno != NULL) *colerrno = info.colerrno; return NULL;}static void_cole_fopen_action (COLEDIRENT *cde, void *_info){ struct _cole_fopen_info *info; info = (struct _cole_fopen_info *)_info; if (!cole_direntry_isfile(cde)) { info->colerrno = COLE_EFILENAMEISNOTFILE; info->succ = 0; return; } info->file = cole_fopen_direntry (cde, &info->colerrno); if (info->file == NULL) { /* colerrno is set */ info->succ = 0; return; } info->succ = 1;}/** * cole_fopen_direntry: * @coledirentry: directory entry to be opened as file. * @colerrno: error value (COLE_EISNOTFILE, COLE_EMEMORY, COLE_ETMPNAM, * COLE_EOPENFILE, COLE_EINVALIDFILESYSTEM, COLE_EREAD, * COLE_EWRITE, COLE_EUNKNOWN). * * Opens a directory entry as file. * * Returns: a file in success, or NULL in other case. */COLEFILE *cole_fopen_direntry (COLEDIRENT *coledirentry, COLERRNO *colerrno){ COLEFILE *ret; if (!cole_direntry_isfile (coledirentry)) { if (colerrno != NULL) *colerrno = COLE_EISNOTFILE; return NULL; } ret = (COLEFILE *)malloc (sizeof (COLEFILE)); if (ret == NULL) { if (colerrno != NULL) *colerrno = COLE_EMEMORY; return NULL; } ret->fs = coledirentry->dir->fs; ret->entry = coledirentry->entry; switch (__cole_extract_file (&ret->file, &ret->filename, ret->fs->tree[ ret->entry ].size, ret->fs->tree[ ret->entry ].start, ret->fs->BDepot, ret->fs->SDepot, ret->fs->sbfile, ret->fs->file)) { case 0: /* success */ break; case 1: if (colerrno != NULL) *colerrno = COLE_EMEMORY; free (ret); return NULL; case 2: if (colerrno != NULL) *colerrno = COLE_ETMPNAM; free (ret); return NULL; case 3: if (colerrno != NULL) *colerrno = COLE_EOPENFILE; free (ret); return NULL; case 4: if (colerrno != NULL) *colerrno = COLE_EINVALIDFILESYSTEM; free (ret); return NULL; case 5: if (colerrno != NULL) *colerrno = COLE_EREAD; free (ret); return NULL; case 6: if (colerrno != NULL) *colerrno = COLE_EWRITE; free (ret); return NULL; default: if (colerrno != NULL) *colerrno = COLE_EUNKNOWN; free (ret); return NULL; } /* because the original fopen(3) leaves the file pointer in the beginning */ rewind (ret->file); ret->pos = 0; ret->filesize = ret->fs->tree[ ret->entry ].size; return ret;}/** * cole_fclose: * @colefile: file to be closed. * @colerrno: error value (COLE_ECLOSEFILE, CLOSE_EREMOVE). * * Closes the file @colefile. * * Returns: zero in sucess, no zero in other case. */intcole_fclose (COLEFILE *colefile, COLERRNO *colerrno){ int ret; ret = 0; if (fclose (colefile->file) && !ret) { if (colerrno != NULL) *colerrno = COLE_ECLOSEFILE; ret = 1; } if (remove (colefile->filename) && !ret) { if (colerrno != NULL) *colerrno = COLE_EREMOVE; ret = 1; } free (colefile->filename); free (colefile); return ret;}/** * cole_fread: * @colefile: file to be read. * @ptr: memory location where the bytes will be stored. * @size: how many bytes will be read. * @colerrno: error value (COLE_EOF, COLE_EREAD, COLE_ESEEK). * * Reads @size bytes from @colefile and store them in the location given * by @ptr. If not success, the file position indicator is not changed. * * Returns: in sucess the number of bytes actually readed (maximum @size) * or zero in other case. */size_tcole_fread (COLEFILE *colefile, void *ptr, size_t size, COLERRNO *colerrno){ size_t bytes_read, bytes_to_read; long tbytes; /* Check to see if going past end... */ if ((colefile->pos + size) > colefile->filesize) tbytes = colefile->filesize - colefile->pos; else tbytes = size; if (tbytes <= 0) return 0; bytes_to_read = (size_t)tbytes; bytes_read = fread (ptr, 1, bytes_to_read, colefile->file); /* assert (size && (colefile->pos + bytes_read > colefile->pos)); */ colefile->pos += bytes_read; /* assert (!feof (colefile->file) && ftell (colefile->file) == colefile->pos); */ if (bytes_read != size) { /* Linux man page says that fread returns a `short item count (or zero)' when an error of end of file ocurrs. A short count OR zero? We are hopping that fread always returns zero. */ if (feof (colefile->file)) { if (colerrno != NULL) *colerrno = COLE_EOF; return 0; } else if (ferror (colefile->file)) { if (colerrno != NULL) *colerrno = COLE_EREAD; return 0; } } /* assert (size != 0 && bytes_read != 0); */ /* assert (bytes_read <= size); */ return bytes_read;}/** * cole_ftell: * @colefile: file of which the file position indicator will be get. * * Get the current value of the file position indicator for the file * @colefile. * * Returns: The file position. */size_tcole_ftell (COLEFILE *colefile){ return colefile->pos;}/** * cole_fseek: * @colefile: file of which its file position indicator will be set. * @delta: number of bytes that the file position indicator will be moved. * @direction: from where start to count the @delta bytes. * @colerrno: error value (COLE_EFSEEKDELTA). * * Sets the value of the file position indicator for the file @colefile * @delta bytes from the beginning of the file, forward from the current * position, backward from the current position, or from the end of the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -