1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
/*
Classes to simplify the handling and caching of temporary files.
Copyright (c) 2008 by Alastair M. Robinson
TempFileTracker is a header class which maintains a list of TempFiles
and deletes them when it's destroyed, typically when the application
quits.
TempFile is a base class which will be subclassed by classes needing
to generate a specific type of temporary file.
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "tempfile.h"
#include "debug.h"
using namespace std;
TempFile::TempFile(TempFileTracker *header,const char *pfix,const char *skey)
: filename(NULL), prefix(NULL), searchkey(NULL), header(header), nexttempfile(NULL), prevtempfile(NULL)
{
header->mutex.ObtainMutex();
if((prevtempfile=header->firsttempfile))
{
while(prevtempfile->nexttempfile)
prevtempfile=prevtempfile->nexttempfile;
prevtempfile->nexttempfile=this;
}
else
header->firsttempfile=this;
// if((nexttempfile=header->firsttempfile))
// nexttempfile->prevtempfile=this;
// header->firsttempfile=this;
if(skey)
searchkey=strdup(skey);
if(pfix)
prefix=strdup(pfix);
header->mutex.ReleaseMutex();
}
TempFile::~TempFile()
{
// Debug[TRACE] << "In TempFile destructor" << endl;
header->mutex.ObtainMutex();
if(filename)
{
// Debug[TRACE] << "Removing " << filename << endl;
remove(filename);
free(filename);
}
if(searchkey)
free(searchkey);
if(prefix)
free(prefix);
if(nexttempfile)
nexttempfile->prevtempfile=prevtempfile;
if(prevtempfile)
prevtempfile->nexttempfile=nexttempfile;
else
header->firsttempfile=nexttempfile;
header->mutex.ReleaseMutex();
}
const char *TempFile::Filename()
{
// If no subclass has provided a filename, generate one here.
if(!filename)
filename=tempnam(NULL,prefix);
return(filename);
}
TempFile *TempFile::NextTempFile()
{
return(nexttempfile);
}
bool TempFile::MatchTempFile(const char *skey)
{
return(strcmp(skey,searchkey)==0);
}
// TempFileTracker
TempFileTracker::TempFileTracker() : mutex(), firsttempfile(NULL)
{
}
TempFileTracker::~TempFileTracker()
{
mutex.ObtainMutex();
while(firsttempfile)
delete firsttempfile;
mutex.ReleaseMutex();
}
TempFile *TempFileTracker::GetTempFile(const char *prefix,const char *searchkey)
{
mutex.ObtainMutexShared();
TempFile *result=NULL;
if(searchkey)
result=FindTempFile(searchkey);
if(!result)
result=new TempFile(this,prefix,searchkey);
mutex.ReleaseMutexShared();
return(result);
}
TempFile *TempFileTracker::FindTempFile(const char *searchkey)
{
mutex.ObtainMutexShared();
TempFile *result=NULL;
TempFile *t=FirstTempFile();
while(t)
{
t=t->NextTempFile();
if(t->MatchTempFile(searchkey))
{
result=t;
t=NULL;
}
}
mutex.ReleaseMutexShared();
return(result);
}
TempFile *TempFileTracker::FirstTempFile()
{
mutex.ObtainMutexShared();
TempFile *result=firsttempfile;
mutex.ReleaseMutexShared();
return(result);
}
|