proxygen
LengthFieldPrepender.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, 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 
18 
19 using folly::Future;
20 using folly::Unit;
21 using folly::IOBuf;
22 
23 namespace wangle {
24 
26  int lengthFieldLength,
27  int lengthAdjustment,
28  bool lengthIncludesLengthField,
29  bool networkByteOrder)
30  : lengthFieldLength_(lengthFieldLength)
31  , lengthAdjustment_(lengthAdjustment)
32  , lengthIncludesLengthField_(lengthIncludesLengthField)
33  , networkByteOrder_(networkByteOrder) {
34  CHECK(lengthFieldLength == 1 ||
35  lengthFieldLength == 2 ||
36  lengthFieldLength == 4 ||
37  lengthFieldLength == 8 );
38  }
39 
41  Context* ctx, std::unique_ptr<IOBuf> buf) {
42  int length = lengthAdjustment_ + buf->computeChainDataLength();
44  length += lengthFieldLength_;
45  }
46 
47  if (length < 0) {
48  throw std::runtime_error("Length field < 0");
49  }
50 
52  len->append(lengthFieldLength_);
53  folly::io::RWPrivateCursor c(len.get());
54 
55  switch (lengthFieldLength_) {
56  case 1: {
57  if (length >= 256) {
58  throw std::runtime_error("length does not fit byte");
59  }
60  if (networkByteOrder_) {
61  c.writeBE((uint8_t)length);
62  } else {
63  c.writeLE((uint8_t)length);
64  }
65  break;
66  }
67  case 2: {
68  if (length >= 65536) {
69  throw std::runtime_error("length does not fit byte");
70  }
71  if (networkByteOrder_) {
72  c.writeBE((uint16_t)length);
73  } else {
74  c.writeLE((uint16_t)length);
75  }
76  break;
77  }
78  case 4: {
79  if (networkByteOrder_) {
80  c.writeBE((uint32_t)length);
81  } else {
82  c.writeLE((uint32_t)length);
83  }
84  break;
85  }
86  case 8: {
87  if (networkByteOrder_) {
88  c.writeBE((uint64_t)length);
89  } else {
90  c.writeLE((uint64_t)length);
91  }
92  break;
93  }
94  default: {
95  throw std::runtime_error("Invalid lengthFieldLength");
96  }
97  }
98 
99  len->prependChain(std::move(buf));
100  return ctx->fireWrite(std::move(len));
101 }
102 
103 
104 } // namespace wangle
virtual folly::Future< folly::Unit > fireWrite(Out msg)=0
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
folly::Future< folly::Unit > write(Context *ctx, std::unique_ptr< folly::IOBuf > buf) override
std::size_t computeChainDataLength() const
Definition: IOBuf.cpp:501
char c
LengthFieldPrepender(int lengthFieldLength=4, int lengthAdjustment=0, bool lengthIncludesLengthField=false, bool networkByteOrder=true)