Oops from previous commit
[lsnes.git] / include / library / fileimage.hpp
blob19696f5611e45e18f9c08c7ae635e942a3761c7b
1 #ifndef _library__fileimage__hpp__included__
2 #define _library__fileimage__hpp__included__
4 #include <functional>
5 #include <cstdint>
6 #include <list>
7 #include <vector>
8 #include "threads.hpp"
10 namespace fileimage
12 class hash;
14 /**
15 * Future for SHA-256 computation.
17 class hashval
19 public:
20 /**
21 * Construct a null future, never resolves.
23 hashval();
24 /**
25 * Construct a future, with value that is immediately resolved.
27 hashval(const std::string& value, uint64_t _prefix = 0);
28 /**
29 * Is the result known?
31 bool ready() const;
32 /**
33 * Read the result (or throw error). Waits until result is ready.
35 std::string read() const;
36 /**
37 * Read the prefix value. Waits until result is ready.
39 uint64_t prefix() const;
40 /**
41 * Copy a future.
43 hashval(const hashval& f);
44 /**
45 * Assign a future.
47 hashval& operator=(const hashval& f);
48 /**
49 * Destroy a future.
51 ~hashval();
52 private:
53 /**
54 * Create a new future.
56 hashval(hash& h, unsigned id);
57 /**
58 * Resolve a future.
60 void resolve(unsigned id, const std::string& hash, uint64_t _prefix);
61 void resolve_error(unsigned id, const std::string& err);
63 friend class hash;
64 mutable threads::lock mlock;
65 mutable threads::cv condition;
66 bool is_ready;
67 unsigned cbid;
68 uint64_t prefixv;
69 std::string value;
70 std::string error;
71 hashval* prev;
72 hashval* next;
73 hash* hasher;
76 /**
77 * Class performing SHA-256 hashing.
79 class hash
81 public:
82 /**
83 * Create a new SHA-256 hasher.
85 hash();
86 /**
87 * Destroy a SHA-256 hasher. Causes all current jobs to fail.
89 ~hash();
90 /**
91 * Set callback.
93 void set_callback(std::function<void(uint64_t, uint64_t)> cb);
94 /**
95 * Compute SHA-256 of file.
97 hashval operator()(const std::string& filename, uint64_t prefixlen = 0);
98 /**
99 * Compute SHA-256 of file.
101 hashval operator()(const std::string& filename, std::function<uint64_t(uint64_t)> prefixlen);
103 * Thread entrypoint.
105 void entrypoint();
106 private:
107 void link(hashval& future);
108 void unlink(hashval& future);
109 void send_callback(uint64_t this_completed);
110 void send_idle();
112 friend class hashval;
113 struct queue_job
115 std::string filename;
116 uint64_t prefix;
117 uint64_t size;
118 unsigned cbid;
119 volatile unsigned interested;
121 hash(const hash&);
122 hash& operator=(const hash&);
123 threads::thread* hash_thread;
124 threads::lock mlock;
125 threads::cv condition;
126 std::list<queue_job> queue;
127 std::list<queue_job>::iterator current_job;
128 hashval* first_future;
129 hashval* last_future;
130 unsigned next_cbid;
131 std::function<void(uint64_t, uint64_t)> progresscb;
132 bool quitting;
133 uint64_t total_work;
134 uint64_t work_size;
138 * Some loaded data or indication of no data.
140 * The loaded images are copied in CoW manner.
142 struct image
145 * Information about image to load.
147 struct info
149 enum _type
151 IT_NONE, //Only used in type field of image.
152 IT_MEMORY,
153 IT_MARKUP,
154 IT_FILE
156 _type type;
157 unsigned headersize;
160 * Construct empty image.
162 * throws std::bad_alloc: Not enough memory.
164 image() throw(std::bad_alloc);
167 * This constructor construct slot by reading data from file. If filename is "", constructs an empty slot.
169 * parameter hasher: Hasher to use.
170 * parameter filename: The filename to read. If "", empty slot is constructed.
171 * parameter base: Base filename to interpret the filename against. If "", no base filename is used.
172 * parameter imginfo: Image information.
173 * throws std::bad_alloc: Not enough memory.
174 * throws std::runtime_error: Can't load the data.
176 image(hash& hasher, const std::string& filename, const std::string& base,
177 const struct info& imginfo) throw(std::bad_alloc, std::runtime_error);
180 * This method patches this slot using specified IPS patch.
182 * If the object was shared, this breaks the sharing, with this object gaining dedicated copy.
184 * parameter patch: The patch to apply
185 * parameter offset: The amount to add to the offsets in the IPS file. Parts with offsets below zero are not patched.
186 * throws std::bad_alloc: Not enough memory.
187 * throws std::runtime_error: Bad IPS patch, or trying to patch file image.
189 void patch(const std::vector<char>& patch, int32_t offset) throw(std::bad_alloc, std::runtime_error);
191 * Type.
193 info::_type type;
195 * Filename this is loaded from.
197 std::string filename;
199 * ROM name hint.
201 std::string namehint;
203 * The actual data for this slot.
205 std::shared_ptr<std::vector<char>> data;
207 * Number of bytes stripped when loading.
209 uint64_t stripped;
211 * SHA-256 for the data in this slot if data is valid. If no valid data, this field is "".
213 * Note, for file images, this takes a bit of time to fill.
215 hashval sha_256;
217 * Get pointer to loaded data
219 * returns: Pointer to loaded data, or NULL if slot is blank.
221 operator const char*() const throw()
223 return data ? reinterpret_cast<const char*>(&(*data)[0]) : NULL;
226 * Get pointer to loaded data
228 * returns: Pointer to loaded data, or NULL if slot is blank.
230 operator const uint8_t*() const throw()
232 return data ? reinterpret_cast<const uint8_t*>(&(*data)[0]) : NULL;
235 * Get size of slot
237 * returns: The number of bytes in slot, or 0 if slot is blank.
239 operator unsigned() const throw()
241 return data ? data->size() : 0;
246 * Get headersize function.
248 std::function<uint64_t(uint64_t)> std_headersize_fn(uint64_t hdrsize);
250 #endif