#ifndef _H_REQMAKER
#define _H_REQMAKER
#include "requirement.h"
namespace Security {
namespace CodeSigning {
class Requirement::Maker {
public:
Maker(Kind k = exprForm);
~Maker() { free(mBuffer); }
template <class T>
T *alloc(size_t size) { return reinterpret_cast<T *>(alloc(size)); }
template <class T>
void put(const T &value) { *alloc<Endian<T> >(sizeof(T)) = value; }
void put(ExprOp op) { put(uint32_t(op)); }
void put(MatchOperation op) { put(uint32_t(op)); }
void put(const std::string &s) { putData(s.data(), s.size()); }
void put(const char *s) { putData(s, strlen(s)); }
void putData(const void *data, size_t length);
void putData(CFStringRef s) { put(cfString(s)); }
void anchor(int slot, SHA1::Digest digest); void anchor(int slot, const void *cert, size_t length); void anchor(); void anchorGeneric();
void trustedAnchor();
void trustedAnchor(int slot);
void infoKey(const std::string &key, const std::string &value);
void ident(const std::string &identHash);
void cdhash(SHA1::Digest digest);
void cdhash(CFDataRef digest);
void platform(int platformIdentifier);
void copy(const void *data, size_t length)
{ memcpy(this->alloc(length), data, length); }
void copy(const Requirement *req);
struct Label {
const Offset pos;
Label(const Maker &maker) : pos((const Offset)maker.length()) { }
};
void *insert(const Label &label, size_t length = sizeof(uint32_t));
template <class T>
Endian<T> &insert(const Label &label, size_t length = sizeof(T))
{ return *reinterpret_cast<Endian<T>*>(insert(label, length)); }
class Chain : public Label {
public:
Chain(Maker &myMaker, ExprOp op)
: Label(myMaker), maker(myMaker), mJoiner(op), mCount(0) { }
void add() const
{ if (mCount++) maker.insert<ExprOp>(*this) = mJoiner; }
Maker &maker;
bool empty() const { return mCount == 0; }
private:
ExprOp mJoiner;
mutable unsigned mCount;
};
void kind(Kind k) { mBuffer->kind(k); }
size_t length() const { return mPC; }
Requirement *make();
Requirement *operator () () { return make(); }
protected:
void require(size_t size);
void *alloc(size_t size);
private:
Requirement *mBuffer;
Offset mSize;
Offset mPC;
};
} }
#endif //_H_REQMAKER