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
22 FrameInfo::~FrameInfo() = default;
23 BarrierFrameInfo::~BarrierFrameInfo() = default;
24 DurabilityFrameInfo::~DurabilityFrameInfo() = default;
25 DcpStreamIdFrameInfo::~DcpStreamIdFrameInfo() = default;
26 OpenTracingContextFrameInfo::~OpenTracingContextFrameInfo() = default;
27
28 using cb::mcbp::request::FrameInfoId;
29
encode() const30 std::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
encode() const36 std::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
encode() const62 std::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
encode() const73 std::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