+}
+
+typedef std::map<uint32_t, std::string> Blobs;
+
+static void insert(Blobs &blobs, uint32_t slot, const std::stringbuf &buffer) {
+ auto value(buffer.str());
+ std::swap(blobs[slot], value);
+}
+
+static void insert(Blobs &blobs, uint32_t slot, uint32_t magic, const std::stringbuf &buffer) {
+ auto value(buffer.str());
+ Blob blob;
+ blob.magic = Swap(magic);
+ blob.length = Swap(uint32_t(sizeof(blob) + value.size()));
+ value.insert(0, reinterpret_cast<char *>(&blob), sizeof(blob));
+ std::swap(blobs[slot], value);
+}
+
+static size_t put(std::streambuf &output, uint32_t magic, const Blobs &blobs) {
+ size_t total(0);
+ _foreach (blob, blobs)
+ total += blob.second.size();
+
+ struct SuperBlob super;
+ super.blob.magic = Swap(magic);
+ super.blob.length = Swap(uint32_t(sizeof(SuperBlob) + blobs.size() * sizeof(BlobIndex) + total));
+ super.count = Swap(uint32_t(blobs.size()));
+ put(output, &super, sizeof(super));
+
+ size_t offset(sizeof(SuperBlob) + sizeof(BlobIndex) * blobs.size());
+
+ _foreach (blob, blobs) {
+ BlobIndex index;
+ index.type = Swap(blob.first);
+ index.offset = Swap(uint32_t(offset));
+ put(output, &index, sizeof(index));
+ offset += blob.second.size();
+ }
+
+ _foreach (blob, blobs)
+ put(output, blob.second.data(), blob.second.size());
+
+ return offset;
+}
+
+class Buffer {
+ private:
+ BIO *bio_;
+
+ public:
+ Buffer(BIO *bio) :
+ bio_(bio)
+ {
+ _assert(bio_ != NULL);
+ }
+
+ Buffer() :
+ bio_(BIO_new(BIO_s_mem()))
+ {
+ }
+
+ Buffer(const char *data, size_t size) :
+ Buffer(BIO_new_mem_buf(const_cast<char *>(data), size))
+ {
+ }
+
+ Buffer(const std::string &data) :
+ Buffer(data.data(), data.size())
+ {
+ }
+
+ Buffer(PKCS7 *pkcs) :
+ Buffer()
+ {
+ _assert(i2d_PKCS7_bio(bio_, pkcs) != 0);
+ }
+
+ ~Buffer() {
+ BIO_free_all(bio_);
+ }
+
+ operator BIO *() const {
+ return bio_;
+ }
+
+ explicit operator std::string() const {
+ char *data;
+ auto size(BIO_get_mem_data(bio_, &data));
+ return std::string(data, size);
+ }
+};