summaryrefslogtreecommitdiff
path: root/src/cachestorefiles.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/cachestorefiles.h')
-rw-r--r--src/cachestorefiles.h192
1 files changed, 192 insertions, 0 deletions
diff --git a/src/cachestorefiles.h b/src/cachestorefiles.h
new file mode 100644
index 0000000..6b37d0a
--- /dev/null
+++ b/src/cachestorefiles.h
@@ -0,0 +1,192 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_CACHE_STORE_FILES_H
9#define BU_CACHE_STORE_FILES_H
10
11#include "bu/fstring.h"
12#include "bu/file.h"
13#include "bu/cachestore.h"
14#include "bu/archive.h"
15#include "bu/membuf.h"
16#include "bu/formatter.h"
17#include "bu/sio.h"
18
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <dirent.h>
22#include <unistd.h>
23
24namespace Bu
25{
26 template<class keytype, class obtype>
27 keytype __cacheGetKey( const obtype *pObj );
28
29 template<class keytype, class obtype>
30 obtype *__cacheStoreFilesAlloc( const keytype &key )
31 {
32 return new obtype();
33 }
34
35 template<class keytype, class obtype>
36 void __cacheStoreFilesStore( Bu::Stream &s, obtype &rObj,
37 const keytype & )
38 {
39 Bu::Archive ar( s, Bu::Archive::save );
40 ar << rObj;
41 }
42
43 template<class keytype, class obtype>
44 obtype *__cacheStoreFilesLoad( Bu::Stream &s, const keytype &key )
45 {
46 obtype *pObj = __cacheStoreFilesAlloc<keytype, obtype>( key );
47 Bu::Archive ar( s, Bu::Archive::load );
48 ar >> (*pObj);
49 return pObj;
50 }
51
52 template<class keytype, class obtype>
53 class CacheStoreFiles : public CacheStore<keytype, obtype>
54 {
55 public:
56 CacheStoreFiles( const Bu::FString &sPrefix ) :
57 sPrefix( sPrefix )
58 {
59 if( access( sPrefix.getStr(), W_OK|R_OK|X_OK ) )
60 {
61 mkdir( sPrefix.getStr(), 0755 );
62 }
63 }
64
65 virtual ~CacheStoreFiles()
66 {
67 }
68
69 virtual obtype *load( const keytype &key )
70 {
71 Bu::MemBuf mb;
72 Bu::Formatter f( mb );
73 f << sPrefix << "/" << key;
74 Bu::File fIn( mb.getString(), Bu::File::Read );
75 obtype *pOb = __cacheStoreFilesLoad<keytype, obtype>( fIn, key );
76 return pOb;
77 }
78
79 virtual void unload( obtype *pObj, const keytype &key )
80 {
81 delete pObj;
82 }
83
84 virtual keytype create( obtype *pSrc )
85 {
86 keytype key = __cacheGetKey<keytype, obtype>( pSrc );
87 Bu::MemBuf mb;
88 Bu::Formatter f( mb );
89 f << sPrefix << "/" << key;
90
91 Bu::File fTouch( mb.getString(), Bu::File::WriteNew );
92
93 return key;
94 }
95
96 virtual void sync()
97 {
98 }
99
100 virtual void sync( obtype *pSrc, const keytype &key )
101 {
102 Bu::MemBuf mb;
103 Bu::Formatter f( mb );
104 f << sPrefix << "/" << key;
105
106 Bu::File fOut( mb.getString(), Bu::File::WriteNew );
107 __cacheStoreFilesStore<keytype, obtype>( fOut, *pSrc, key );
108 }
109
110 virtual void destroy( obtype *pObj, const keytype &key )
111 {
112 Bu::MemBuf mb;
113 Bu::Formatter f( mb );
114 f << sPrefix << "/" << key;
115
116 unlink( mb.getString().getStr() );
117 delete pObj;
118 }
119
120 virtual void destroy( const keytype &key )
121 {
122 Bu::MemBuf mb;
123 Bu::Formatter f( mb );
124 f << sPrefix << "/" << key;
125
126 unlink( mb.getString().getStr() );
127 }
128
129 virtual bool has( const keytype &key )
130 {
131 Bu::MemBuf mb;
132 Bu::Formatter f( mb );
133 f << sPrefix << "/" << key;
134
135 return access( mb.getString().getStr(), F_OK ) == 0;
136 }
137
138 virtual Bu::List<keytype> getKeys()
139 {
140 DIR *dir = opendir( sPrefix.getStr() );
141 struct dirent *de;
142 Bu::List<keytype> lKeys;
143
144 while( (de = readdir( dir ) ) )
145 {
146 if( de->d_type != DT_REG )
147 continue;
148
149 keytype tmp;
150 Bu::MemBuf mb( de->d_name );
151 Bu::Formatter f( mb );
152 try
153 {
154 f >> tmp;
155 }
156 catch( Bu::ExceptionBase &e )
157 {
158 Bu::sio << "Parse error in dir-scan: " << e.what()
159 << Bu::sio.nl;
160 }
161 lKeys.append( tmp );
162 }
163 closedir( dir );
164
165 return lKeys;
166 }
167
168 virtual int getSize()
169 {
170 DIR *dir = opendir( sPrefix.getStr() );
171 struct dirent *de;
172 int iCount = 0;
173
174 while( (de = readdir( dir ) ) )
175 {
176 if( de->d_type != DT_REG )
177 continue;
178
179 iCount++;
180 }
181 closedir( dir );
182
183 return iCount;
184 }
185
186 private:
187 Bu::FString sPrefix;
188 };
189
190};
191
192#endif