2013-09-01 15:05:08 +03:00
|
|
|
#ifndef _library__fileimage__hpp__included__
|
|
|
|
#define _library__fileimage__hpp__included__
|
|
|
|
|
|
|
|
#include <functional>
|
|
|
|
#include <cstdint>
|
|
|
|
#include <list>
|
|
|
|
#include <vector>
|
2014-03-23 09:45:42 +02:00
|
|
|
#include "threads.hpp"
|
2013-09-01 15:05:08 +03:00
|
|
|
|
2013-12-21 00:55:31 +02:00
|
|
|
namespace fileimage
|
|
|
|
{
|
|
|
|
class hash;
|
2013-09-01 15:05:08 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Future for SHA-256 computation.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
class hashval
|
2013-09-01 15:05:08 +03:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Construct a null future, never resolves.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
hashval();
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* Construct a future, with value that is immediately resolved.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
hashval(const std::string& value, uint64_t _prefix = 0);
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* Is the result known?
|
|
|
|
*/
|
|
|
|
bool ready() const;
|
|
|
|
/**
|
|
|
|
* Read the result (or throw error). Waits until result is ready.
|
|
|
|
*/
|
|
|
|
std::string read() const;
|
2013-09-25 13:45:34 +03:00
|
|
|
/**
|
|
|
|
* Read the prefix value. Waits until result is ready.
|
|
|
|
*/
|
|
|
|
uint64_t prefix() const;
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* Copy a future.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
hashval(const hashval& f);
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* Assign a future.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
hashval& operator=(const hashval& f);
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* Destroy a future.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
~hashval();
|
2013-09-01 15:05:08 +03:00
|
|
|
private:
|
|
|
|
/**
|
|
|
|
* Create a new future.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
hashval(hash& h, unsigned id);
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* Resolve a future.
|
|
|
|
*/
|
2013-09-25 13:45:34 +03:00
|
|
|
void resolve(unsigned id, const std::string& hash, uint64_t _prefix);
|
2013-09-01 15:05:08 +03:00
|
|
|
void resolve_error(unsigned id, const std::string& err);
|
|
|
|
|
2013-12-21 00:55:31 +02:00
|
|
|
friend class hash;
|
2014-03-23 09:45:42 +02:00
|
|
|
mutable threads::lock mlock;
|
|
|
|
mutable threads::cv condition;
|
2013-09-01 15:05:08 +03:00
|
|
|
bool is_ready;
|
|
|
|
unsigned cbid;
|
2013-09-25 13:45:34 +03:00
|
|
|
uint64_t prefixv;
|
2013-09-01 15:05:08 +03:00
|
|
|
std::string value;
|
|
|
|
std::string error;
|
2013-12-21 00:55:31 +02:00
|
|
|
hashval* prev;
|
|
|
|
hashval* next;
|
|
|
|
hash* hasher;
|
2013-09-01 15:05:08 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class performing SHA-256 hashing.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
class hash
|
2013-09-01 15:05:08 +03:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Create a new SHA-256 hasher.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
hash();
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* Destroy a SHA-256 hasher. Causes all current jobs to fail.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
~hash();
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* Set callback.
|
|
|
|
*/
|
2013-09-25 23:34:29 +03:00
|
|
|
void set_callback(std::function<void(uint64_t, uint64_t)> cb);
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* Compute SHA-256 of file.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
hashval operator()(const std::string& filename, uint64_t prefixlen = 0);
|
2013-09-25 13:45:34 +03:00
|
|
|
/**
|
|
|
|
* Compute SHA-256 of file.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
hashval operator()(const std::string& filename, std::function<uint64_t(uint64_t)> prefixlen);
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* Thread entrypoint.
|
|
|
|
*/
|
|
|
|
void entrypoint();
|
|
|
|
private:
|
2013-12-21 00:55:31 +02:00
|
|
|
void link(hashval& future);
|
|
|
|
void unlink(hashval& future);
|
2013-09-01 15:05:08 +03:00
|
|
|
void send_callback(uint64_t this_completed);
|
|
|
|
void send_idle();
|
|
|
|
|
2013-12-21 00:55:31 +02:00
|
|
|
friend class hashval;
|
2013-09-01 15:05:08 +03:00
|
|
|
struct queue_job
|
|
|
|
{
|
|
|
|
std::string filename;
|
2013-09-25 13:45:34 +03:00
|
|
|
uint64_t prefix;
|
2013-09-01 15:05:08 +03:00
|
|
|
uint64_t size;
|
|
|
|
unsigned cbid;
|
|
|
|
volatile unsigned interested;
|
|
|
|
};
|
2013-12-21 00:55:31 +02:00
|
|
|
hash(const hash&);
|
|
|
|
hash& operator=(const hash&);
|
2014-03-23 09:45:42 +02:00
|
|
|
threads::thread* hash_thread;
|
|
|
|
threads::lock mlock;
|
|
|
|
threads::cv condition;
|
2013-09-01 15:05:08 +03:00
|
|
|
std::list<queue_job> queue;
|
|
|
|
std::list<queue_job>::iterator current_job;
|
2013-12-21 00:55:31 +02:00
|
|
|
hashval* first_future;
|
|
|
|
hashval* last_future;
|
2013-09-01 15:05:08 +03:00
|
|
|
unsigned next_cbid;
|
2013-09-25 23:34:29 +03:00
|
|
|
std::function<void(uint64_t, uint64_t)> progresscb;
|
2013-09-01 15:05:08 +03:00
|
|
|
bool quitting;
|
|
|
|
uint64_t total_work;
|
2013-09-25 23:34:29 +03:00
|
|
|
uint64_t work_size;
|
2013-09-01 15:05:08 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Some loaded data or indication of no data.
|
2013-09-07 08:26:09 +03:00
|
|
|
*
|
|
|
|
* The loaded images are copied in CoW manner.
|
2013-09-01 15:05:08 +03:00
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
struct image
|
2013-09-01 15:05:08 +03:00
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Information about image to load.
|
|
|
|
*/
|
|
|
|
struct info
|
|
|
|
{
|
|
|
|
enum _type
|
|
|
|
{
|
|
|
|
IT_NONE, //Only used in type field of image.
|
|
|
|
IT_MEMORY,
|
|
|
|
IT_MARKUP,
|
|
|
|
IT_FILE
|
|
|
|
};
|
|
|
|
_type type;
|
|
|
|
unsigned headersize;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* Construct empty image.
|
|
|
|
*
|
|
|
|
* throws std::bad_alloc: Not enough memory.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
image() throw(std::bad_alloc);
|
2013-09-01 15:05:08 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This constructor construct slot by reading data from file. If filename is "", constructs an empty slot.
|
|
|
|
*
|
|
|
|
* parameter hasher: Hasher to use.
|
|
|
|
* parameter filename: The filename to read. If "", empty slot is constructed.
|
|
|
|
* parameter base: Base filename to interpret the filename against. If "", no base filename is used.
|
|
|
|
* parameter imginfo: Image information.
|
|
|
|
* throws std::bad_alloc: Not enough memory.
|
|
|
|
* throws std::runtime_error: Can't load the data.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
image(hash& hasher, const std::string& filename, const std::string& base,
|
2013-09-01 15:05:08 +03:00
|
|
|
const struct info& imginfo) throw(std::bad_alloc, std::runtime_error);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method patches this slot using specified IPS patch.
|
|
|
|
*
|
2013-09-07 08:26:09 +03:00
|
|
|
* If the object was shared, this breaks the sharing, with this object gaining dedicated copy.
|
|
|
|
*
|
2013-09-01 15:05:08 +03:00
|
|
|
* parameter patch: The patch to apply
|
|
|
|
* parameter offset: The amount to add to the offsets in the IPS file. Parts with offsets below zero are not patched.
|
|
|
|
* throws std::bad_alloc: Not enough memory.
|
|
|
|
* throws std::runtime_error: Bad IPS patch, or trying to patch file image.
|
|
|
|
*/
|
|
|
|
void patch(const std::vector<char>& patch, int32_t offset) throw(std::bad_alloc, std::runtime_error);
|
|
|
|
/**
|
|
|
|
* Type.
|
|
|
|
*/
|
|
|
|
info::_type type;
|
|
|
|
/**
|
|
|
|
* Filename this is loaded from.
|
|
|
|
*/
|
|
|
|
std::string filename;
|
2013-09-14 16:29:58 +03:00
|
|
|
/**
|
|
|
|
* ROM name hint.
|
|
|
|
*/
|
|
|
|
std::string namehint;
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* The actual data for this slot.
|
|
|
|
*/
|
2013-09-07 08:26:09 +03:00
|
|
|
std::shared_ptr<std::vector<char>> data;
|
2013-09-25 13:45:34 +03:00
|
|
|
/**
|
|
|
|
* Number of bytes stripped when loading.
|
|
|
|
*/
|
|
|
|
uint64_t stripped;
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* SHA-256 for the data in this slot if data is valid. If no valid data, this field is "".
|
|
|
|
*
|
|
|
|
* Note, for file images, this takes a bit of time to fill.
|
|
|
|
*/
|
2013-12-21 00:55:31 +02:00
|
|
|
hashval sha_256;
|
2013-09-01 15:05:08 +03:00
|
|
|
/**
|
|
|
|
* Get pointer to loaded data
|
|
|
|
*
|
|
|
|
* returns: Pointer to loaded data, or NULL if slot is blank.
|
|
|
|
*/
|
|
|
|
operator const char*() const throw()
|
|
|
|
{
|
2013-09-07 08:26:09 +03:00
|
|
|
return data ? reinterpret_cast<const char*>(&(*data)[0]) : NULL;
|
2013-09-01 15:05:08 +03:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Get pointer to loaded data
|
|
|
|
*
|
|
|
|
* returns: Pointer to loaded data, or NULL if slot is blank.
|
|
|
|
*/
|
|
|
|
operator const uint8_t*() const throw()
|
|
|
|
{
|
2013-09-07 08:26:09 +03:00
|
|
|
return data ? reinterpret_cast<const uint8_t*>(&(*data)[0]) : NULL;
|
2013-09-01 15:05:08 +03:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Get size of slot
|
|
|
|
*
|
|
|
|
* returns: The number of bytes in slot, or 0 if slot is blank.
|
|
|
|
*/
|
|
|
|
operator unsigned() const throw()
|
|
|
|
{
|
2013-09-07 08:26:09 +03:00
|
|
|
return data ? data->size() : 0;
|
2013-09-01 15:05:08 +03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-09-25 13:45:34 +03:00
|
|
|
/**
|
|
|
|
* Get headersize function.
|
|
|
|
*/
|
|
|
|
std::function<uint64_t(uint64_t)> std_headersize_fn(uint64_t hdrsize);
|
2013-12-21 00:55:31 +02:00
|
|
|
}
|
2013-09-01 15:05:08 +03:00
|
|
|
#endif
|