1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2018 Couchbase, Inc
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include <mcbp/protocol/request.h>
21 #include <platform/sized_buffer.h>
22 #include <platform/socket.h>
23 
24 #include <stdint.h>
25 #include <iosfwd>
26 
27 namespace cb {
28 namespace mcbp {
29 
30 /**
31  * DcpStreamId - allows a client to chose a value to associate with a stream
32  * or if no value is chosen (normal DCP) 0 is reserved for meaning off.
33  */
34 class DcpStreamId {
35 public:
36     DcpStreamId() = default;
37 
DcpStreamId(uint16_t value)38     explicit DcpStreamId(uint16_t value) : id(value){};
39 
to_network() const40     uint16_t to_network() const {
41         return htons(id);
42     }
43 
to_string() const44     std::string to_string() const {
45         if (id != 0) {
46             return "sid:" + std::to_string(id);
47         }
48         return "sid:none";
49     }
50 
operator bool() const51     operator bool() const {
52         return id != 0;
53     }
54 
operator <(const DcpStreamId& other) const55     bool operator<(const DcpStreamId& other) const {
56         return (id < other.id);
57     }
58 
operator <=(const DcpStreamId& other) const59     bool operator<=(const DcpStreamId& other) const {
60         return (id <= other.id);
61     }
62 
operator >(const DcpStreamId& other) const63     bool operator>(const DcpStreamId& other) const {
64         return (id > other.id);
65     }
66 
operator >=(const DcpStreamId& other) const67     bool operator>=(const DcpStreamId& other) const {
68         return (id >= other.id);
69     }
70 
operator ==(const DcpStreamId& other) const71     bool operator==(const DcpStreamId& other) const {
72         return (id == other.id);
73     }
74 
operator !=(const DcpStreamId& other) const75     bool operator!=(const DcpStreamId& other) const {
76         return !(*this == other);
77     }
78 
79 protected:
80     uint16_t id{0};
81 };
82 
83 struct DcpStreamIdFrameInfo {
DcpStreamIdFrameInfocb::mcbp::DcpStreamIdFrameInfo84     DcpStreamIdFrameInfo(DcpStreamId sid) {
85         *reinterpret_cast<uint16_t*>(this->sid) = sid.to_network();
86     }
87 
getBufcb::mcbp::DcpStreamIdFrameInfo88     cb::const_byte_buffer getBuf() const {
89         return cb::const_byte_buffer{reinterpret_cast<const uint8_t*>(this),
90                                      sizeof(tag) + sizeof(sid)};
91     }
92 
93 private:
94     // FrameID:2, len:2
95     static const uint8_t frameId = uint8_t(request::FrameInfoId::DcpStreamId);
96     uint8_t tag{(frameId << 4) | 2};
97     uint8_t sid[2]{};
98 };
99 
100 static_assert(sizeof(DcpStreamIdFrameInfo) == 3,
101               "DcpStreamIdFrameInfo should be 3 bytes");
102 
103 } // namespace mcbp
104 } // namespace cb
105 
106 std::ostream& operator<<(std::ostream&, const cb::mcbp::DcpStreamId);
107