#ifndef PKTMAKER_H #define PKTMAKER_H #include namespace PacketMaker { class Packet { public: Packet() { memset(&hdr_s, 0, sizeof(hdr_s)); req = &hdr_s; res = (protocol_binary_response_header *)&hdr_s; } uint8_t magic() const { return req->request.magic; } void magic(uint8_t mg) { req->request.magic = mg; } uint8_t op() const { return req->request.opcode; } void op(uint8_t cc) { req->request.opcode = cc; } uint8_t extlen() const { return req->request.extlen; } void opaque(uint32_t seq) { req->request.opaque = seq; } uint32_t opaque() const { return req->request.opaque; } const char *keyptr() const { return &body[extlen()]; } std::string key() const { uint16_t len = keylen(); if (!len) { return std::string(""); } return std::string(keyptr(), len); } uint16_t keylen() const { return ntohs(req->request.keylen); } void serialize(std::vector& ret) { req->request.bodylen = htonl(body.size()); ret.insert(ret.end(), hdr_s.bytes, hdr_s.bytes + sizeof(hdr_s.bytes)); ret.insert(ret.end(), body.begin(), body.end()); } void load(std::vector& buf) { memcpy(&hdr_s.bytes, &buf[0], sizeof(hdr_s.bytes)); body.assign(&buf[24], &buf[0] + buf.size()); } void setKey(const char *kbuf, uint16_t len) { body.insert(body.end(), kbuf, kbuf + len); req->request.keylen = htons((uint16_t)len); } void setValue(const char *val, uint32_t len) { body.insert(body.end(), val, val+len); } protected: protocol_binary_request_header *req; protocol_binary_response_header *res; void addExtra(char *extbuf, uint8_t nbuf) { body.insert(body.begin(), extbuf, extbuf+nbuf); req->request.extlen += nbuf; } private: protocol_binary_request_header hdr_s; std::vector body; Packet(Packet&); }; class StorageRequest : public Packet { public: StorageRequest(const std::string& key, const std::string& val) : Packet() { setKey(key.c_str(), (uint16_t)key.size()); setValue(val.c_str(), (uint32_t)val.size()); } }; class GetRequest : public Packet { public: GetRequest(std::string& key) : Packet() { setKey(key.c_str(), (uint16_t)key.size()); } }; class Response : public Packet { public: Response(const Packet& request, uint16_t status = 0) : Packet() { res->response.status = htons(status); opaque(request.opaque()); } }; } #endif