/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * file.cc * * Thu Jun 9 15:31:38 CEST 2005 * Copyright 2005 Bent Bisballe * deva@aasimon.org ****************************************************************************/ /* * This file is part of MIaV. * * MIaV is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * MIaV 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MIaV; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ /* * $Id$ */ /* * $Log$ * Revision 1.3 2005/06/14 12:29:40 deva * Incorporated the use of the Info object everywhere... also using the log functionality. * * Revision 1.2 2005/06/13 20:38:19 deva * Added some logfile code. * Enhanced the file object... now ready to hook into mov_encoder * * Revision 1.1 2005/06/09 17:54:00 deva * New file object, that takes care of uniqueness and counts up number in * filename, when grown too big. * */ #include #include "file.h" #include #include #include #include #include #include #include File::File(char *fn, char* ext, Info *i) { char path[256]; info = i; filename = (char*)malloc(strlen(fn) + 1); extension = (char*)malloc(strlen(ext) + 1); strcpy(filename, fn); strcpy(extension, ext); num = 0; seqnum = 0; fd = -1; int pos = (int)strrchr(filename, '/'); memset(path, 0, sizeof(path)); if(pos) { // pos is NULL, a file will be created in the current dir (Which is bad) pos -= (int)filename; // Make pos relative to the beginning of the string strncpy(path, filename, pos); createPath(path); } Open(); } File::~File() { close(fd); free(filename); free(extension); } int File::Open() { char fname[256]; if(fd) close(fd); fd = -1; while(fd == -1) { if(seqnum) { // A sequence number > 0 sprintf(fname, "%s%.3d-%d.%s", filename, num, seqnum, extension); } else { // A sequence number of 0 sprintf(fname, "%s%.3d.%s", filename, num, extension); } fd = open(fname, O_CREAT | O_WRONLY | O_SYNC | O_EXCL, //| O_LARGEFILE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); num ++; // If more than 1000 files are created in one day, something is terribly wrong! if(num > 1000) { info->error("Something is wrong with the path [%s]!\n", fname); exit(1); } } seqnum ++; info->log("Opened the file %s for output.", fname); return 0; } int File::Write(void* data, int size) { int w; w = write(fd, data, size); if(w != size) { info->log("Wrapping file.\n"); Open(); w = write(fd, data, size); if(w != size) { info->error("Out of diskspace!\n"); return -1; } } return w; } int File::createPath(char* path) { // struct stat stats; char *subpath; subpath = (char*)calloc(strlen(path) + 1, 1); strcpy(subpath, path); subpath[strrchr(subpath, '/') - subpath] = '\0'; info->info("Checking and/or generating directory: %s", path); if(strlen(subpath) > 0) createPath(subpath); // stat(path, &stats); //if(!S_ISDIR(stats.st_mode) && S_ISREG(stats.st_mode)) mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH); // TODO: Check for creation errors! free(subpath); return 0; } #ifdef FILE_TEST // Test #define BLOCK_SIZE 1024*1024 #define TIMES 4000 int main() { void *buf = malloc(BLOCK_SIZE); double b = BLOCK_SIZE; double t = TIMES; double gb = b / (1024 * 1024 * 1024); gb *= t; printf("Writing %f GB.\n", gb); File file("/tmp/filetest/folder1/folder2/file", "ext"); for(int cnt = 0; cnt < TIMES; cnt++) { file.Write(buf, BLOCK_SIZE); } printf("Done.\n"); } #endif // Test