1/* 2 * Copyright 2019 Couchbase, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "frameinfo.h" 18 19#include <gsl.h> 20#include <mcbp/protocol/request.h> 21 22FrameInfo::~FrameInfo() = default; 23BarrierFrameInfo::~BarrierFrameInfo() = default; 24DurabilityFrameInfo::~DurabilityFrameInfo() = default; 25DcpStreamIdFrameInfo::~DcpStreamIdFrameInfo() = default; 26OpenTracingContextFrameInfo::~OpenTracingContextFrameInfo() = default; 27 28using cb::mcbp::request::FrameInfoId; 29 30std::vector<uint8_t> BarrierFrameInfo::encode() const { 31 std::vector<uint8_t> ret; 32 ret.push_back(uint8_t(FrameInfoId::Barrier) << 0x04U); 33 return ret; 34} 35 36std::vector<uint8_t> DurabilityFrameInfo::encode() const { 37 using cb::durability::Level; 38 using cb::durability::Timeout; 39 40 if (level == Level::None) { 41 return {}; 42 } 43 44 std::vector<uint8_t> ret(2); 45 ret[0] = uint8_t(FrameInfoId::DurabilityRequirement) << 0x04U; 46 ret[1] = (uint8_t(0x0f) & uint8_t(level)); 47 48 if (timeout.isDefault()) { 49 // Level is the only byte 50 ret[0] |= uint8_t(0x01); 51 } else { 52 // Level and timeout is present 53 ret[0] |= uint8_t(0x03); 54 auto value = htons(timeout.get()); 55 const auto* ptr = reinterpret_cast<const char*>(&value); 56 ret.insert(ret.end(), ptr, ptr + sizeof(value)); 57 } 58 59 return ret; 60} 61 62std::vector<uint8_t> DcpStreamIdFrameInfo::encode() const { 63 std::vector<uint8_t> ret(1); 64 ret[0] = uint8_t(FrameInfoId::DcpStreamId) << 0x04U; 65 ret[0] |= sizeof(id); 66 auto value = htons(id); 67 const auto* ptr = reinterpret_cast<const char*>(&value); 68 ret.insert(ret.end(), ptr, ptr + sizeof(value)); 69 70 return ret; 71} 72 73std::vector<uint8_t> OpenTracingContextFrameInfo::encode() const { 74 std::vector<uint8_t> ret(1); 75 ret[0] = uint8_t(FrameInfoId::OpenTracingContext) << 0x04U; 76 if (ctx.size() < 0x0fU) { 77 // We may fit in a single byte 78 ret[0] |= uint8_t(ctx.size()); 79 } else { 80 // we need an extra length byte to set the length 81 ret[0] |= 0x0fU; 82 ret.push_back(gsl::narrow<uint8_t>(ctx.size())); 83 } 84 ret.insert(ret.end(), ctx.cbegin(), ctx.cend()); 85 86 return ret; 87} 88