removing non-existing file from the build
[folly.git] / folly / wangle / codec / LengthFieldBasedFrameDecoder.cpp
1 /*
2  * Copyright 2015 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 #include <folly/wangle/codec/LengthFieldBasedFrameDecoder.h>
17
18 namespace folly { namespace wangle {
19
20 LengthFieldBasedFrameDecoder::LengthFieldBasedFrameDecoder(
21   uint32_t lengthFieldLength,
22   uint32_t maxFrameLength,
23   uint32_t lengthFieldOffset,
24   uint32_t lengthAdjustment,
25   uint32_t initialBytesToStrip,
26   bool networkByteOrder)
27     : lengthFieldLength_(lengthFieldLength)
28     , maxFrameLength_(maxFrameLength)
29     , lengthFieldOffset_(lengthFieldOffset)
30     , lengthAdjustment_(lengthAdjustment)
31     , initialBytesToStrip_(initialBytesToStrip)
32     , networkByteOrder_(networkByteOrder)
33     , lengthFieldEndOffset_(lengthFieldOffset + lengthFieldLength) {
34   CHECK(maxFrameLength > 0);
35   CHECK(lengthFieldOffset <= maxFrameLength - lengthFieldLength);
36 }
37
38 std::unique_ptr<IOBuf> LengthFieldBasedFrameDecoder::decode(
39   Context* ctx, IOBufQueue& buf, size_t&) {
40   // discarding too long frame
41   if (buf.chainLength() < lengthFieldEndOffset_) {
42     return nullptr;
43   }
44
45   uint64_t frameLength = getUnadjustedFrameLength(
46     buf, lengthFieldOffset_, lengthFieldLength_, networkByteOrder_);
47
48   frameLength += lengthAdjustment_ + lengthFieldEndOffset_;
49
50   if (frameLength < lengthFieldEndOffset_) {
51     buf.trimStart(lengthFieldEndOffset_);
52     ctx->fireReadException(folly::make_exception_wrapper<std::runtime_error>(
53                              "Frame too small"));
54     return nullptr;
55   }
56
57   if (frameLength > maxFrameLength_) {
58     buf.trimStart(frameLength);
59     ctx->fireReadException(folly::make_exception_wrapper<std::runtime_error>(
60                              "Frame larger than " +
61                              folly::to<std::string>(maxFrameLength_)));
62     return nullptr;
63   }
64
65   if (buf.chainLength() < frameLength) {
66     return nullptr;
67   }
68
69   if (initialBytesToStrip_ > frameLength) {
70     buf.trimStart(frameLength);
71     ctx->fireReadException(folly::make_exception_wrapper<std::runtime_error>(
72                              "InitialBytesToSkip larger than frame"));
73     return nullptr;
74   }
75
76   buf.trimStart(initialBytesToStrip_);
77   int actualFrameLength = frameLength - initialBytesToStrip_;
78   return buf.split(actualFrameLength);
79 }
80
81 uint64_t LengthFieldBasedFrameDecoder::getUnadjustedFrameLength(
82   IOBufQueue& buf, int offset, int length, bool networkByteOrder) {
83   folly::io::Cursor c(buf.front());
84   uint64_t frameLength;
85
86   c.skip(offset);
87
88   switch(length) {
89     case 1:{
90       if (networkByteOrder) {
91         frameLength = c.readBE<uint8_t>();
92       } else {
93         frameLength = c.readLE<uint8_t>();
94       }
95       break;
96     }
97     case 2:{
98       if (networkByteOrder) {
99         frameLength = c.readBE<uint16_t>();
100       } else {
101         frameLength = c.readLE<uint16_t>();
102       }
103       break;
104     }
105     case 4:{
106       if (networkByteOrder) {
107         frameLength = c.readBE<uint32_t>();
108       } else {
109         frameLength = c.readLE<uint32_t>();
110       }
111       break;
112     }
113     case 8:{
114       if (networkByteOrder) {
115         frameLength = c.readBE<uint64_t>();
116       } else {
117         frameLength = c.readLE<uint64_t>();
118       }
119       break;
120     }
121   }
122
123   return frameLength;
124 }
125
126
127 }} // namespace