1 #ifndef _library__filesys__hpp__included
2 #define _library__filesys__hpp__included
8 #include "workthread.hpp"
10 #define CLUSTER_SIZE 8192
11 #define CLUSTERS_PER_SUPER (CLUSTER_SIZE / 4)
12 #define SUPERCLUSTER_SIZE (static_cast<uint64_t>(CLUSTER_SIZE) * CLUSTERS_PER_SUPER)
13 #define FILESYSTEM_SUPERBLOCK 1
14 #define FILESYSTEM_ROOTDIR 2
19 //Create a new or open existing filesystem backed by specified file.
20 filesystem(const std::string
& backingfile
);
21 //Allocate a new file.
22 uint32_t allocate_cluster();
23 //Delete specified file.
24 void free_cluster_chain(uint32_t cluster
);
25 //Skip specfied amount of data. If skip goes to end of file, ptr will be left at CLUSTER_SIZE.
26 size_t skip_data(uint32_t& cluster
, uint32_t& ptr
, uint32_t length
);
27 //Read specified amount of data. If read goes to end of file, ptr will be left at CLUSTER_SIZE.
28 //Returns the number of bytes read.
29 size_t read_data(uint32_t& cluster
, uint32_t& ptr
, void* data
, uint32_t length
);
30 //Write specified amount of data. real_cluster and real_ptr point to location data was written to.
31 //If write exactly fills the last cluster, ptr will be left at CLUSTER_SIZE.
32 void write_data(uint32_t& cluster
, uint32_t& ptr
, const void* data
, uint32_t length
,
33 uint32_t& real_cluster
, uint32_t& real_ptr
);
35 filesystem(const filesystem
&);
36 filesystem
& operator=(const filesystem
&);
37 void link_cluster(uint32_t cluster
, uint32_t linkto
);
40 unsigned free_clusters
;
41 uint32_t clusters
[CLUSTERS_PER_SUPER
];
42 void load(std::fstream
& s
, uint32_t index
);
43 void save(std::fstream
& s
, uint32_t index
);
45 uint32_t supercluster_count
;
46 std::map
<uint32_t, supercluster
> superclusters
;
59 filesystem_ref(const std::string
& backingfile
)
64 refcnt
= new unsigned;
65 mutex
= new mutex_class
;
66 fs
= new filesystem(backingfile
);
76 mutex_class
* mtodelete
= NULL
;
80 umutex_class
m(*mutex
);
91 filesystem_ref(const filesystem_ref
& r
)
93 umutex_class
m(*r
.mutex
);
99 filesystem_ref
& operator=(const filesystem_ref
& r
)
103 //This is tricky, due to having to lock two objects.
104 size_t A
= (size_t)this;
105 size_t B
= (size_t)&r
;
106 mutex_class
* mtodelete
= NULL
;
108 //We just have to grab a ref and copy.
109 umutex_class
m(*r
.mutex
);
116 umutex_class
m1(*mutex
);
117 umutex_class
m2(*r
.mutex
);
130 umutex_class
m1(*r
.mutex
);
131 umutex_class
m2(*mutex
);
147 uint32_t allocate_cluster()
149 umutex_class
m(*mutex
);
150 return fs
->allocate_cluster();
152 void free_cluster_chain(uint32_t cluster
)
154 umutex_class
m(*mutex
);
155 fs
->free_cluster_chain(cluster
);
157 size_t skip_data(uint32_t& cluster
, uint32_t& ptr
, uint32_t length
)
159 umutex_class
m(*mutex
);
160 return fs
->skip_data(cluster
, ptr
, length
);
162 size_t read_data(uint32_t& cluster
, uint32_t& ptr
, void* data
, uint32_t length
)
164 umutex_class
m(*mutex
);
165 return fs
->read_data(cluster
, ptr
, data
, length
);
167 void write_data(uint32_t& cluster
, uint32_t& ptr
, const void* data
, uint32_t length
,
168 uint32_t& real_cluster
, uint32_t& real_ptr
)
170 umutex_class
m(*mutex
);
171 fs
->write_data(cluster
, ptr
, data
, length
, real_cluster
, real_ptr
);