📄 rmfile.c
字号:
/***************************************** Copyright 2001-2003 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//** @file rmfile.h @ingroup types @brief standard libc IO API. @author Mathieu Lacage @date 2001-09-07*/#define _LARGEFILE64_SOURCE 1#ifndef ALLOW_OS_CODE#define ALLOW_OS_CODE#endif#include "../include/rmlibcw.h"#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <stdarg.h>#include <string.h>#include <stdio.h>#include <sys/types.h>#include <dirent.h>#ifndef _LARGEFILE64_SOURCE#warning LIBC doesnt support LARGEFILE64#define O_LARGEFILE 0#define off64_t off_t#define lseek64 lseek#define stat64 stat#endif#if 0#define FILEDBG ENABLE#else#define FILEDBG DISABLE#endifstruct _RMfile { RMint32 fd;#ifdef _DEBUG RMuint32 seekcount; RMuint32 readcount;#endif // _DEBUG void *cookie; RMFileOps *ops;};struct _RMfile _RMstdin = { .fd = STDIN_FILENO};struct _RMfile _RMstdout = { .fd = STDOUT_FILENO};struct _RMfile _RMstderr = { .fd = STDERR_FILENO};RMfile RMOpenFile(const RMnonAscii *name, RMfileOpenMode mode){ RMfile file; int flags=0; file = (RMfile) RMMalloc(sizeof(struct _RMfile)); switch (mode) { case RM_FILE_OPEN_READ: flags = O_RDONLY; break; case RM_FILE_OPEN_WRITE: flags = O_RDWR|O_CREAT|O_TRUNC; break; case RM_FILE_OPEN_READ_WRITE: flags = O_RDWR; break; case RM_FILE_OPEN_READ_WRITE_CREATE: flags = O_RDWR|O_CREAT; break; default: RMPanic(RM_ERROROPENFILE); break; } file->fd = open((char *)name, flags|O_LARGEFILE, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); file->cookie = NULL; if (file->fd < 0) { RMDBGLOG((FILEDBG,"could not open file \"%s\", error \"%s\"\n", name, strerror(errno))); RMFree(file); return (RMfile) NULL; }#ifdef _DEBUG file->readcount = 0; file->seekcount = 0;#endif // _DEBUG return file;}RMfile RMOpenFileCookie(void *cookie, RMfileOpenMode mode, RMFileOps *ops){ RMfile file; if (cookie == NULL || ops == NULL) return NULL; file = (RMfile) RMMalloc(sizeof(struct _RMfile)); file->cookie = cookie; file->ops = ops;#ifdef _DEBUG file->readcount = 0; file->seekcount = 0;#endif // _DEBUG return file;}RMfile RMCreateTmpFile(void){ RMfile file; file = (RMfile) RMMalloc(sizeof(struct _RMfile)); file->fd = fileno(tmpfile()); if (file->fd < 0) { RMDBGLOG((FILEDBG,"could not create temporary file\n")); RMFree(file); return (RMfile) NULL; }#ifdef _DEBUG file->readcount = 0; file->seekcount = 0;#endif // _DEBUG return file;} RMstatus RMCloseFile(RMfile f) { int res; if (f->cookie){ if (f->ops->close) res = f->ops->close(f->cookie); else res = 0; //Nothing to do }else { res = close((int) f->fd); } if (res < 0) { RMDBGLOG((FILEDBG,"could not close file, error \"%s\"\n", strerror(errno))); return RM_ERRORCLOSEFILE; } RMDBGLOG((FILEDBG, "Seek count = %lu\n", f->seekcount)); RMDBGLOG((FILEDBG, "read count = %lu\n", f->readcount)); RMFree(f); return RM_OK;}RMstatus RMReadFile (const RMfile f, RMuint8 *pbuffer, RMuint32 size, RMuint32 *preadSize){ int res; RMstatus status; status = RM_OK; if (f->cookie){ if (f->ops->read){ res = f->ops->read(f->cookie, pbuffer, size); } else { /* Read not supported */ res = -1; } } else { res = read((int) f->fd, (void *)pbuffer, (size_t)size); } if (res < 0) { *preadSize = 0; RMDBGLOG((FILEDBG,"could not read in file, error \"%s\"", strerror(errno))); status = RM_ERRORREADFILE; } else if ((res == 0) && (size > 0)) { *preadSize = 0; status = RM_ERRORENDOFFILE; } else { // It is legal to cast here because res is positive. *preadSize = (RMuint32)res; }#ifdef _DEBUG f->readcount ++;#endif // _DEBUG return status;}RMstatus RMWriteFile (const RMfile f, const RMuint8 *pbuffer, RMuint32 size, RMuint32 *const pwrittenSize){ int res; RMstatus status; status = RM_OK; if (f->cookie){ if (f->ops->write){ res = f->ops->write(f->cookie, pbuffer, size); } else { /* Write not supported */ res = -1; } } else { res = write((int) f->fd, (void *)pbuffer, (size_t)size); } if (res < 0) { *pwrittenSize = 0; RMDBGLOG((FILEDBG,"could not write in file, error \"%s\"", strerror(errno))); status = RM_ERRORWRITEFILE; } else { // It is legal to cast here because res is positive. *pwrittenSize = (RMuint32)res; } return status;}RMstatus RMCopyFile(const RMfile dest, const RMfile src){#define BUFSIZE 4096 RMuint8 buf[BUFSIZE]; RMuint32 bytes = 1; RMuint32 res; RMstatus status = RM_OK; while (bytes > 0) { status = RMReadFile(src, buf, BUFSIZE, &bytes); if (status == RM_ERRORREADFILE) { RMDBGLOG((FILEDBG,"could not read in file, error \"%s\"", strerror(errno))); break; } if (bytes > 0) { status = RMWriteFile(dest, buf, bytes, &res); if (status == RM_ERRORWRITEFILE) { RMDBGLOG((FILEDBG,"could not write in file, error \"%s\"", strerror(errno))); break; } } } return status;}RMstatus RMPrintFile(RMfile f, const RMascii *fmt, ...){#define RM_MAX_LINE 2048 va_list ap; RMstatus status; RMascii str[RM_MAX_LINE]; RMuint32 size,writtenSize; status = RM_OK; va_start(ap, fmt); size=vsnprintf((char *)str, RM_MAX_LINE, fmt, ap); if(RMFAILED(RMWriteFile (f, (RMuint8 *)str,size, &writtenSize))){ RMDBGLOG((FILEDBG, "could not print into file, error \"%d\"", strerror(errno))); status = RM_ERRORWRITEFILE; } va_end(ap); return status;}RMstatus RMGetCurrentPositionOfFile (const RMfile f, RMint64 *position){ off64_t retval=0; RMstatus status; status = RM_OK; if (f->cookie){ if (f->ops->seek){ *position = 0; retval = f->ops->seek(f->cookie, position, RM_FILE_SEEK_CURRENT); }else{ retval = -1; } if (retval == -1) { RMDBGLOG((FILEDBG,"could not seek in file, error \"%s\"", strerror(errno))); status = RM_ERRORSEEKFILE; *position = 0; } } else { retval = lseek64 ((int)f->fd, 0, SEEK_CUR); if (retval == -1) { RMDBGLOG((FILEDBG,"could not seek in file, error \"%s\"", strerror(errno))); status = RM_ERRORSEEKFILE; *position = 0; } else *position = (RMint64)retval; } return status;}RMstatus RMSeekFile (const RMfile f, RMint64 offset, RMfileSeekPos position){ off64_t retval=0; RMstatus status; status = RM_OK; if (f->cookie){ if (f->ops->seek){ RMint64 pos = offset; retval = f->ops->seek(f->cookie, &pos, position); } else { retval = -1; } } else { switch (position) { case RM_FILE_SEEK_START: retval = lseek64 ((int)f->fd, (off64_t) offset, SEEK_SET); break; case RM_FILE_SEEK_CURRENT: retval = lseek64 ((int)f->fd, (off64_t) offset, SEEK_CUR); break; case RM_FILE_SEEK_END: retval = lseek64 ((int)f->fd, (off64_t) offset, SEEK_END); break; } } if (retval == -1) { RMDBGLOG((FILEDBG,"could not seek in file, error \"%s\"", strerror(errno))); status = RM_ERRORSEEKFILE; }#ifdef _DEBUG f->seekcount ++;#endif // _DEBUG return status;}RMbool RMEndOfFile (const RMfile f){ RMbool answer = FALSE; RMuint32 res; RMuint8 buffer[1]; RMstatus status; status = RMReadFile(f, buffer, 1, &res); if (status == RM_ERRORENDOFFILE){ answer = TRUE; }else{ RMSeekFile(f, (RMint64)(-1), RM_FILE_SEEK_CURRENT); } return answer;}RMstatus RMFlushFile (RMfile f){ RMstatus status; status = RM_OK; // I think the correct implementation is: nothing (sync() would be overkill). return status;}RMstatus RMSizeOfFile(const RMnonAscii *filename,RMint64 *pSize){ int rc; struct stat64 buf; /* on the linux platform, we KNOW that RMnonAscii and RMascii * are compatible (except for signedness) */ rc = stat64((RMascii *)filename,&buf); if (rc!=0) return RM_ERROR; *pSize=buf.st_size; return RM_OK;}RMstatus RMSizeOfOpenFile(RMfile f, RMint64 *pSize){ RMint64 curPos; // Initialize with a default just in case procedure is unsuccessful *pSize = 0; if ((RMGetCurrentPositionOfFile(f, &curPos) != RM_OK) || (RMSeekFile(f, 0, RM_FILE_SEEK_END) != RM_OK) || (RMGetCurrentPositionOfFile(f, pSize) != RM_OK) || (RMSeekFile(f, curPos, RM_FILE_SEEK_START) != RM_OK)) return RM_ERROR; return RM_OK;}RMstatus RMReadLineFile(RMfile f, RMascii *line, RMuint32 maxsize){ RMuint32 nc, i; RMReadFile(f, (RMuint8 *)line, maxsize, &nc); for (i=0 ; i<nc ; i++) { if (line[i] == '\n') { line[i] = '\0'; i++; break; } } if (i < nc) RMSeekFile(f, (RMint32) (i - nc), RM_FILE_SEEK_CURRENT); return RM_OK;}RMstatus RMLockFile(RMfile f){ return RM_OK;} RMstatus RMUnLockFile(RMfile f){ return RM_OK;}RMstatus RMChangeCurrentDirectory(const RMnonAscii *const directory){ /* on the linux platform, we KNOW that RMnonAscii and RMascii * are compatible (except for signedness) */ int status = chdir((RMascii*)directory); if (status < 0) { return RM_ERROROPENFILE; } else { return RM_OK; }}struct _RMdirectory { DIR* dir; void* cookie; RMDirectoryOps* ops;};RMstatus RMOpenCurrentDirectory (RMdirectory *const dir){ RMstatus status = RMOpenDirectory (RMNONASCII("."), dir); return status;}RMstatus RMOpenDirectory (const RMnonAscii *const directory, RMdirectory *const dir){ struct _RMdirectory * pdir = (struct _RMdirectory *)RMMalloc (sizeof (struct _RMdirectory)); /* on the linux platform, we KNOW that RMnonAscii and RMascii * are compatible (except for signedness) */ pdir->dir = opendir ((RMascii *)directory); pdir->cookie = NULL; if (pdir->dir == NULL) { RMFree( pdir ); return RM_ERROROPENFILE; } else { *dir = pdir; return RM_OK; }}RMstatus RMOpenDirectoryCookie (RMdirectory *const dir, void* cookie, RMDirectoryOps *ops) { struct _RMdirectory * pdir = (struct _RMdirectory *)RMMalloc (sizeof (struct _RMdirectory)); pdir->ops = ops; pdir->cookie = cookie; *dir = pdir; return RM_OK;}RMstatus RMReadDirectory (RMdirectory directory, RMdirectoryEntry *const entry){ if( directory->cookie ){ return directory->ops->read( directory->cookie, entry ); } else { struct dirent *dir_entry; dir_entry = readdir (directory->dir); if (dir_entry == NULL) { if (errno == EBADF) { return RM_ERROR; } else { return RM_ERRORNODIRECTORYENTRY; } } entry->name = RMNONASCII(dir_entry->d_name); return RM_OK; }}RMstatus RMCloseDirectory (RMdirectory directory){ RMstatus status; if( directory->cookie ){ status = directory->ops->close( directory->cookie ); } else if (closedir (directory->dir) < 0) { status = RM_ERRORCLOSEFILE; } else { status = RM_OK; } if( status == RM_OK ) { RMFree( directory ); } return status;}RMstatus RMFileRename(RMnonAscii *oldpath,RMnonAscii *newpath){ /* on the linux platform, we KNOW that RMnonAscii and RMascii * are compatible (except for signedness) */ return (rename((RMascii *)oldpath, (RMascii *)newpath) == 0) ? RM_OK : RM_ERROR;}RMstatus RMFileMkdir(RMnonAscii *pathname){ /* on the linux platform, we KNOW that RMnonAscii and RMascii * are compatible (except for signedness) */ return (mkdir((RMascii *)pathname,S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH|S_IXUSR)==0)?RM_OK:RM_ERROR;}RMstatus RMFileUnlink(RMnonAscii *pathname){ /* on the linux platform, we KNOW that RMnonAscii and RMascii * are compatible (except for signedness) */ return (unlink((RMascii *)pathname)==0)?RM_OK:RM_ERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -