1 | /******************************************************************** |
2 | * Copyright (c) 2013 - 2014, Pivotal Inc. |
3 | * All rights reserved. |
4 | * |
5 | * Author: Zhanwei Wang |
6 | ********************************************************************/ |
7 | /******************************************************************** |
8 | * 2014 - |
9 | * open source under Apache License Version 2.0 |
10 | ********************************************************************/ |
11 | /** |
12 | * Licensed to the Apache Software Foundation (ASF) under one |
13 | * or more contributor license agreements. See the NOTICE file |
14 | * distributed with this work for additional information |
15 | * regarding copyright ownership. The ASF licenses this file |
16 | * to you under the Apache License, Version 2.0 (the |
17 | * "License"); you may not use this file except in compliance |
18 | * with the License. You may obtain a copy of the License at |
19 | * |
20 | * http://www.apache.org/licenses/LICENSE-2.0 |
21 | * |
22 | * Unless required by applicable law or agreed to in writing, software |
23 | * distributed under the License is distributed on an "AS IS" BASIS, |
24 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
25 | * See the License for the specific language governing permissions and |
26 | * limitations under the License. |
27 | */ |
28 | #include "BigEndian.h" |
29 | #include "Exception.h" |
30 | #include "ExceptionInternal.h" |
31 | #include "PacketHeader.h" |
32 | |
33 | namespace Hdfs { |
34 | namespace Internal { |
35 | |
36 | int PacketHeader:: = PacketHeader::CalcPkgHeaderSize(); |
37 | |
38 | int PacketHeader::() { |
39 | PacketHeaderProto ; |
40 | header.set_offsetinblock(0); |
41 | header.set_datalen(0); |
42 | header.set_lastpacketinblock(false); |
43 | header.set_seqno(0); |
44 | return header.ByteSize() + sizeof(int32_t) /*packet length*/ + sizeof(int16_t)/* proto length */; |
45 | } |
46 | |
47 | int PacketHeader::() { |
48 | return PkgHeaderSize; |
49 | } |
50 | |
51 | PacketHeader::() : |
52 | packetLen(0) { |
53 | } |
54 | |
55 | PacketHeader::(int packetLen, int64_t offsetInBlock, int64_t seqno, |
56 | bool lastPacketInBlock, int dataLen) : |
57 | packetLen(packetLen) { |
58 | proto.set_offsetinblock(offsetInBlock); |
59 | proto.set_seqno(seqno); |
60 | proto.set_lastpacketinblock(lastPacketInBlock); |
61 | proto.set_datalen(dataLen); |
62 | } |
63 | |
64 | int PacketHeader::() { |
65 | return proto.datalen(); |
66 | } |
67 | |
68 | bool PacketHeader::() { |
69 | return proto.lastpacketinblock(); |
70 | } |
71 | |
72 | bool PacketHeader::(int64_t lastSeqNo) { |
73 | // We should only have a non-positive data length for the last packet |
74 | if (proto.datalen() <= 0 && !proto.lastpacketinblock()) |
75 | return false; |
76 | |
77 | // The last packet should not contain data |
78 | if (proto.lastpacketinblock() && proto.datalen() != 0) |
79 | return false; |
80 | |
81 | // Seqnos should always increase by 1 with each packet received |
82 | if (proto.seqno() != lastSeqNo + 1) |
83 | return false; |
84 | |
85 | return true; |
86 | } |
87 | |
88 | int64_t PacketHeader::() { |
89 | return proto.seqno(); |
90 | } |
91 | |
92 | int64_t PacketHeader::() { |
93 | return proto.offsetinblock(); |
94 | } |
95 | |
96 | int PacketHeader::() { |
97 | return packetLen; |
98 | } |
99 | |
100 | void PacketHeader::(const char * buf, size_t size) { |
101 | int16_t protoLen; |
102 | assert(size > sizeof(packetLen) + sizeof(protoLen)); |
103 | packetLen = ReadBigEndian32FromArray(buf); |
104 | protoLen = ReadBigEndian16FromArray(buf + sizeof(packetLen)); |
105 | |
106 | if (packetLen < static_cast<int>(sizeof(int32_t)) || protoLen < 0 |
107 | || static_cast<int>(sizeof(packetLen) + sizeof(protoLen)) + protoLen > static_cast<int>(size)) { |
108 | THROW(HdfsIOException, "Invalid PacketHeader, packetLen is %d, protoLen is %hd, buf size is %zu" , packetLen, |
109 | protoLen, size); |
110 | } |
111 | |
112 | if (!proto.ParseFromArray(buf + sizeof(packetLen) + sizeof(protoLen), |
113 | protoLen)) { |
114 | THROW(HdfsIOException, |
115 | "PacketHeader cannot parse PacketHeaderProto from datanode response." ); |
116 | } |
117 | } |
118 | |
119 | void PacketHeader::(char * buf, size_t size) { |
120 | buf = WriteBigEndian32ToArray(packetLen, buf); |
121 | buf = WriteBigEndian16ToArray(proto.ByteSize(), buf); |
122 | proto.SerializeToArray(buf, size - sizeof(int32_t) - sizeof(int16_t)); |
123 | } |
124 | |
125 | } |
126 | } |
127 | |