📄 file.c
字号:
/* * * QccPack: Quantization, compression, and coding libraries * Copyright (C) 1997-2009 James E. Fowler * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * */#include "libQccPack.h"#define QCCFILE_READ 1#define QCCFILE_WRITE 2#define QCCFILE_PIPETRUE 1#define QCCFILE_PIPEFALSE 2typedef struct{ FILE *fileptr; int access_mode; int pipe_type;} QccFileEntry;static int QccFileTableLen = 0;static QccFileEntry *QccFileTable;#ifdef QCC_USE_PTHREADSstatic pthread_mutex_t QccFileTableMutex = PTHREAD_MUTEX_INITIALIZER;#endifvoid QccFileInit(void){#ifdef QCC_USE_PTHREADS if (pthread_mutex_lock(&QccFileTableMutex)) { QccErrorAddMessage("(QccFileInit): Error locking mutex"); QccExit; }#endif QccFileTableLen = 0; QccFileTable = NULL;#ifdef QCC_USE_PTHREADS if (pthread_mutex_unlock(&QccFileTableMutex)) { QccErrorAddMessage("(QccFileInit): Error unlocking mutex"); QccExit; }#endif}int QccFileExists(const QccString filename){ struct stat statbuf; return(!stat(filename, &statbuf));}int QccFileGetExtension(const QccString filename, QccString extension){ char *ptr; QccString filename2; QccStringCopy(filename2, filename); if ((ptr = strrchr(filename2, '.')) == NULL) { QccStringMakeNull(extension); return(1); } if (!strcmp(ptr + 1, "gz")) { *ptr = '\0'; if ((ptr = strrchr(filename2, '.')) == NULL) { QccStringMakeNull(extension); return(1); } } QccStringCopy(extension, ptr + 1); return(0);}static int QccFileTableAddEntry(FILE *fileptr, const int access_mode, const int pipe_flag){ int return_value = 0;#ifdef QCC_USE_PTHREADS if (pthread_mutex_lock(&QccFileTableMutex)) { QccErrorAddMessage("(QccFileTableAddEntry): Error locking mutex"); QccExit; }#endif if (QccFileTable == NULL) { if ((QccFileTable = (QccFileEntry *)malloc(sizeof(QccFileEntry))) == NULL) { QccErrorAddMessage("(QccFileTableAddEntry): Error allocating memory"); goto Error; } QccFileTableLen = 1; } else { QccFileTableLen++; if ((QccFileTable = (QccFileEntry *)realloc((void *)QccFileTable, sizeof(QccFileEntry)*QccFileTableLen)) == NULL) { QccErrorAddMessage("(QccFileTableAddEntry): Error reallocating memory"); goto Error; } } QccFileTable[QccFileTableLen - 1].fileptr = fileptr; QccFileTable[QccFileTableLen - 1].access_mode = access_mode; QccFileTable[QccFileTableLen - 1].pipe_type = pipe_flag; return_value = 0; goto Return; Error: return_value = 1; Return:#ifdef QCC_USE_PTHREADS if (pthread_mutex_unlock(&QccFileTableMutex)) { QccErrorAddMessage("(QccFileTableAddEntry): Error unlocking mutex"); QccExit; }#endif return(return_value);}static int QccFileGetPipeType(FILE *fileptr){ int file_cnt; int return_value = 0;#ifdef QCC_USE_PTHREADS if (pthread_mutex_lock(&QccFileTableMutex)) { QccErrorAddMessage("(QccFileGetPipeType): Error locking mutex"); QccExit; }#endif for (file_cnt = 0; file_cnt < QccFileTableLen; file_cnt++) if (QccFileTable[file_cnt].fileptr == fileptr) { return_value = QccFileTable[file_cnt].pipe_type; break; }#ifdef QCC_USE_PTHREADS if (pthread_mutex_unlock(&QccFileTableMutex)) { QccErrorAddMessage("(QccFileGetPipeType): Error unlocking mutex"); QccExit; }#endif return(return_value);}static int QccFileTableRemoveEntry(FILE *fileptr){ int file_cnt, file_cnt2, file_cnt3; QccFileEntry *tmp_table; int return_value = 0;#ifdef QCC_USE_PTHREADS if (pthread_mutex_lock(&QccFileTableMutex)) { QccErrorAddMessage("(QccFileTableRemoveEntry): Error locking mutex"); QccExit; }#endif for (file_cnt = 0; file_cnt < QccFileTableLen; file_cnt++) if (QccFileTable[file_cnt].fileptr == fileptr) break; if (file_cnt >= QccFileTableLen) { QccErrorAddMessage("(QccFileTableRemoveEntry): fileptr is not in table"); goto Error; } if (QccFileTableLen == 1) { QccFree(QccFileTable); QccFileTableLen = 0; QccFileTable = NULL; goto Return; } if ((tmp_table = (QccFileEntry *)malloc(sizeof(QccFileEntry)*(QccFileTableLen - 1))) == NULL) { QccErrorAddMessage("(QccFileTableRemoveEntry): Error allocating memory"); goto Error; } for (file_cnt2 = 0, file_cnt3 = 0; file_cnt2 < QccFileTableLen; file_cnt2++) if (file_cnt2 != file_cnt) tmp_table[file_cnt3++] = QccFileTable[file_cnt2]; QccFree(QccFileTable); QccFileTable = tmp_table; QccFileTableLen--; return_value = 0; goto Return; Error: return_value = 1; Return:#ifdef QCC_USE_PTHREADS if (pthread_mutex_unlock(&QccFileTableMutex)) { QccErrorAddMessage("(QccFileTableRemoveEntry): Error unlocking mutex"); QccExit; }#endif return(return_value);}static FILE *QccFileOpenRead(const QccString filename, int *pipe_flag){ int len; QccString cmd; FILE *infile = NULL; *pipe_flag = QCCFILE_PIPEFALSE; if (!QccFileExists(filename)) { QccErrorAddMessage("(QccFileOpenRead): file %s not found", filename); return(NULL); } if ((infile = fopen(filename, "rb")) == NULL) { QccErrorAddMessage("(QccFileOpenRead): Unable to open %s for reading", filename); return(NULL); } len = strlen(filename); if ((!strcmp(&filename[len-2], ".Z")) || (!strcmp(&filename[len-3], ".gz"))) { fclose(infile); QccStringSprintf(cmd, "%s -q -c %s", QCCMAKESTRING(QCCUNCOMPRESS), filename); if ((infile = popen(cmd, "r")) == NULL) QccErrorAddMessage("(QccFileOpenRead): unable to open pipe for decompression"); *pipe_flag = QCCFILE_PIPETRUE; } return(infile);}static FILE *QccFileOpenWrite(const QccString filename, int *pipe_flag){ int len; QccString cmd; FILE *outfile = NULL; len = strlen(filename); *pipe_flag = QCCFILE_PIPEFALSE; if ((!strcmp(&filename[len-2], ".Z")) || (!strcmp(&filename[len-3], ".gz"))) { QccStringSprintf(cmd, "%s > %s", QCCMAKESTRING(QCCCOMPRESS), filename); if ((outfile = popen(cmd, "w")) == NULL) { QccErrorAddMessage("(QccFileOpenWrite): unable to open pipe for compression"); } *pipe_flag = QCCFILE_PIPETRUE; } else { if ((outfile = fopen(filename, "wb")) == NULL) QccErrorAddMessage("(QccFileOpenWrite): unable to open %s for writing", filename); } return(outfile);}FILE *QccFileOpen(const QccString filename, const QccString mode){ FILE *fileptr = NULL; int pipe_flag; int access_mode; if (mode == NULL) { QccErrorAddMessage("(QccFileOpen): Error invalid open mode"); return(NULL); } if (mode[0] == 'r') { if ((fileptr = QccFileOpenRead(filename, &pipe_flag)) == NULL) { QccErrorAddMessage("(QccFileOpen): Error calling QccFileOpenRead()"); return(NULL); } access_mode = QCCFILE_READ; } else if (mode[0] == 'w') { if ((fileptr = QccFileOpenWrite(filename, &pipe_flag)) == NULL) { QccErrorAddMessage("(QccFileOpen): Error calling QccFileOpenWrite()"); return(NULL); } access_mode = QCCFILE_WRITE; } else { QccErrorAddMessage("(QccFileOpen): Open mode %s is invalid", mode); return(NULL); } if (QccFileTableAddEntry(fileptr, access_mode, pipe_flag)) { QccErrorAddMessage("(QccFileOpen): Error calling QccFileTableAddEntry()"); return(NULL); } return(fileptr);}FILE *QccFileDescriptorOpen(int file_descriptor, const QccString mode){ FILE *fileptr = NULL; int pipe_flag; int access_mode; pipe_flag = QCCFILE_PIPEFALSE; if (mode == NULL) { QccErrorAddMessage("(QccFileDescriptorOpen): Error invalid open mode"); return(NULL); } if (mode[0] == 'r') { if ((fileptr = fdopen(file_descriptor, "r")) == NULL) { QccErrorAddMessage("(QccFileDescriptorOpen): Error opening file descriptor for reading()"); return(NULL); } access_mode = QCCFILE_READ; } else if (mode[0] == 'w') { if ((fileptr = fdopen(file_descriptor, "w")) == NULL) { QccErrorAddMessage("(QccFileDescriptorOpen): Error opening file descriptor for writing()"); return(NULL); } access_mode = QCCFILE_WRITE; } else { QccErrorAddMessage("(QccFileDescriptorOpen): Open mode %s is invalid", mode); return(NULL); } if (QccFileTableAddEntry(fileptr, access_mode, pipe_flag)) { QccErrorAddMessage("(QccFileDescriptorOpen): Error calling QccFileTableAddEntry()"); return(NULL); } return(fileptr);}int QccFileClose(FILE *fileptr){ int pipe_flag; if (fileptr == NULL) return(0); if (!(pipe_flag = QccFileGetPipeType(fileptr))) { QccErrorAddMessage("(QccFileClose): fileptr is not in QccFileTable"); return(1); } if (pipe_flag == QCCFILE_PIPETRUE) pclose(fileptr); else fclose(fileptr); if (QccFileTableRemoveEntry(fileptr)) { QccErrorAddMessage("(QccFileClose): Error calling QccFileTableRemoveEntry()"); return(1); } return(0);}int QccFileSeekable(FILE *fileptr){ if (ftell(fileptr) == -1) return(0); return(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -