//-----------------------------------.h---------------------------------------
#ifndef MYSERIALIZATION_H
#define MYSERIALIZATION_H
#include <memory>
#include <vector>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <nghttp2/nghttp2.h>
#define MAKE_NV(K, V)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
{? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
? (uint8_t *)K, (uint8_t *)V, sizeof(K) - 1, sizeof(V) - 1,? ? ? ? ? ? ? ? ? \
? ? ? NGHTTP2_NV_FLAG_NONE? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
}
class Deflate
{
public:
? ? Deflate() : def(nullptr), errorCode(0) {}
? ? ~Deflate()
? ? {
? ? ? ? free();
? ? }
? ? nghttp2_hd_deflater* getDef()
? ? {
? ? ? ? if(!def)
? ? ? ? {
? ? ? ? ? ? errorCode = nghttp2_hd_deflate_new(&def, 4096);
? ? ? ? ? ? if(0 != errorCode)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? def = nullptr;
? ? ? ? ? ? }
? ? ? ? ? ? printf("nghttp2_hd_deflate_new? %d\n", errorCode);
? ? ? ? }
? ? ? ? return def;
? ? }
? ? void free()
? ? {
? ? ? ? //必須跟inflater配套使用,否則每次都要?jiǎng)?chuàng)建新的deflate
? ? ? ? if(def)
? ? ? ? {
? ? ? ? ? ? nghttp2_hd_deflate_del(def);
? ? ? ? ? ? def = nullptr;
? ? ? ? ? ? printf("nghttp2_hd_deflate_del\n");
? ? ? ? }
? ? }
? ? int getErrorcode()
? ? {
? ? ? ? return errorCode;
? ? }
private:
? ? nghttp2_hd_deflater* def;
? ? int errorCode;
};
class mySerialization
{
public:
? ? mySerialization();
? ? template <typename T, size_t N>
? ? int httpSerialization(T nva[N]);
? ? void test();
private:
? ? std::vector<uint8_t> output;
? ? static Deflate def;
};
#endif
//-----------------------------------.cpp---------------------------------------
#include "mySerialization.h"
Deflate mySerialization::def;
void mySerialization::test()
{
? ? nghttp2_nv nva[5] = {
? ? ? MAKE_NV(":scheme", "https"), MAKE_NV(":authority", "example.org"),
? ? ? MAKE_NV(":path", "/"), MAKE_NV("user-agent", "libnghttp2"),
? ? ? MAKE_NV("accept-encoding", "gzip, deflate")};
? ? httpSerialization<nghttp2_nv, sizeof(nva)/sizeof(nva[0])>(nva);
? ? uint8_t comp[] = {0x87, 0x41, 0x88, 0x2F, 0x91, 0xD3, 0x5D, 0x05, 0x5C, 0xF6, 0x4D, 0x84, 0x7A, 0x87, 0xA0, 0xD1, 0xD5, 0x34, 0xE9, 0x4D, 0x62, 0x90};
? ? for(int i = 0; i < output.size(); i++)
? ? {
? ? ? ? if(output[i] != comp[i])
? ? ? ? {
? ? ? ? ? ? printf("Failed: %d [%x] [%x]\n", i, output[i], comp[i]);
? ? ? ? ? ? return;
? ? ? ? }
? ? }
? ? def.free();
? ? std::cout << "Success" << std::endl;
}
mySerialization::mySerialization() : output()
{
? ? output.reserve(1024);
}
template <typename T, size_t N>
int mySerialization::httpSerialization(T nva[N])
{
? ? int result = 0;
? ? int buflen = 0;
? ? do
? ? {
? ? ? ? if(N <= 0){ result = 1; }
? ? ? ? nghttp2_hd_deflater* deflater = def.getDef();
? ? ? ? if(def.getErrorcode() > 0)
? ? ? ? {
? ? ? ? ? ? result = def.getErrorcode();
? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? buflen = nghttp2_hd_deflate_bound(deflater, nva, N);
? ? ? ? std::unique_ptr<uint8_t> buf(new uint8_t(buflen));
? ? ? ? result = nghttp2_hd_deflate_hd(deflater, buf.get(), buflen, nva, N);
? ? ? ? if(result < 0) { break; }
? ? ? ? for(int i = 0; i < result; i++)
? ? ? ? {
? ? ? ? ? ? output.emplace_back(buf.get()[i]);
? ? ? ? }
? ? } while (false);
? ? return result;
}