0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
BlockHeader.cc
Go to the documentation of this file.
1 /* -*- c++ -*-
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; version 3 of the
9  * License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
28 #include <Common/Compat.h>
29 
30 #include "BlockHeader.h"
31 
32 #include <Common/Serialization.h>
33 #include <Common/Checksum.h>
34 #include <Common/Error.h>
35 #include <Common/Logger.h>
36 
38 
39 #include <cstring>
40 
41 using namespace Hypertable;
42 using namespace Serialization;
43 
44 namespace {
45  const size_t VersionLengths[BlockHeader::LatestVersion+1] = { 26, 28 };
46 }
47 
48 const uint16_t BlockHeader::LatestVersion;
49 
50 BlockHeader::BlockHeader(uint16_t version, const char *magic) :
51  m_flags(0), m_data_length(0), m_data_zlength(0), m_data_checksum(0),
52  m_compression_type((uint16_t)-1), m_version(version) {
53  HT_ASSERT(version <= LatestVersion);
54  if (magic)
55  memcpy(m_magic, magic, 10);
56  else
57  memset(m_magic, 0, 10);
58 }
59 
60 
61 void
63 
64  // Original format put the checksum at the end
65  if (m_version == 0) {
66  uint8_t *buf = base + encoded_length() - 2;
67  encode_i16(&buf, fletcher32(base, encoded_length()-2));
68  return;
69  }
70 
71  uint8_t *buf = base + 10;
72  encode_i16(&buf, fletcher32(base+12, encoded_length()-12));
73 }
74 
75 
77  return VersionLengths[m_version];
78 }
79 
82 void BlockHeader::encode(uint8_t **bufp) {
83 
85 
86  memcpy(*bufp, m_magic, 10);
87  (*bufp) += 10;
88 
89  if (m_version != 0) {
90  (*bufp) += 2; // space for checksum
91  encode_i16(bufp, m_flags);
92  }
93 
94  *(*bufp)++ = (uint8_t)encoded_length();
95  *(*bufp)++ = (uint8_t)m_compression_type;
99 }
100 
101 
104 void BlockHeader::decode(const uint8_t **bufp, size_t *remainp) {
105  const uint8_t *base = *bufp;
106 
107  if (*remainp < encoded_length())
109 
110  memcpy(m_magic, *bufp, 10);
111  (*bufp) += 10;
112  *remainp -= 10;
113 
114  if (m_version != 0) {
115  uint16_t header_checksum = decode_i16(bufp, remainp);
116  uint16_t header_checksum_computed = fletcher32(base+12, encoded_length()-12);
117  if (header_checksum_computed != header_checksum)
119  "Header checksum mismatch: %u (computed) != %u (stored)",
120  (unsigned)header_checksum_computed, (unsigned)header_checksum);
121  m_flags = decode_i16(bufp, remainp);
122  }
123 
124  uint16_t header_length = decode_byte(bufp, remainp);
125 
126  if (header_length != encoded_length())
127  HT_THROWF(Error::BLOCK_COMPRESSOR_BAD_HEADER, "Unexpected header length"
128  ": %lu, expecting: %lu", (Lu)header_length, (Lu)encoded_length());
129 
130  m_compression_type = decode_byte(bufp, remainp);
131 
134  "Unsupported compression type (%d)", (int)m_compression_type);
135 
136  m_data_checksum = decode_i32(bufp, remainp);
137  m_data_length = decode_i32(bufp, remainp);
138  m_data_zlength = decode_i32(bufp, remainp);
139 
140 }
141 
142 
143 bool BlockHeader::equals(const BlockHeader &other) const {
144  if (m_version == other.m_version &&
145  !memcmp(m_magic, other.m_magic, 10) &&
146  m_data_length == other.m_data_length &&
147  m_data_zlength == other.m_data_zlength &&
148  m_data_checksum == other.m_data_checksum) {
149  if (m_version > 0)
150  return m_flags == other.m_flags;
151  return true;
152  }
153  return false;
154 }
uint32_t m_data_checksum
Checksum of (possibly compressed) data stored within the block.
Definition: BlockHeader.h:226
static const uint16_t LatestVersion
Definition: BlockHeader.h:52
uint16_t m_compression_type
Type of data compression used (see BlockCompressionCodec::Type)
Definition: BlockHeader.h:229
uint32_t m_data_zlength
Compressed length of the data stored within the block.
Definition: BlockHeader.h:223
Declarations for BlockCompressionCodec.
Declarations for BlockHeader.
bool equals(const BlockHeader &other) const
Equality test.
Definition: BlockHeader.cc:143
uint32_t decode_i32(const uint8_t **bufp, size_t *remainp)
Decode a 32-bit integer in little-endian order.
#define HT_ASSERT(_e_)
Definition: Logger.h:396
uint32_t fletcher32(const void *data8, size_t len8)
Compute fletcher32 checksum for arbitary data.
Definition: Checksum.cc:42
uint16_t m_version
Serialization format version number
Definition: BlockHeader.h:233
uint16_t decode_i16(const uint8_t **bufp, size_t *remainp)
Decode a 16-bit integer in little-endian order.
Logging routines and macros.
void encode_i32(uint8_t **bufp, uint32_t val)
Encode a 32-bit integer in little-endian order.
Compatibility Macros for C/C++.
void encode_i16(uint8_t **bufp, uint16_t val)
Encode a 16-bit integer in little-endian order.
Functions to serialize/deserialize primitives to/from a memory buffer.
virtual void decode(const uint8_t **bufp, size_t *remainp)
Decodes serialized block header.
Definition: BlockHeader.cc:104
Hypertable definitions
Implementation of checksum routines.
uint16_t m_flags
Flags.
Definition: BlockHeader.h:217
#define HT_THROWF(_code_, _fmt_,...)
Definition: Error.h:490
virtual size_t encoded_length()
Returns length of serizlized block header.
Definition: BlockHeader.cc:76
long unsigned int Lu
Shortcut for printf formats.
Definition: String.h:47
void write_header_checksum(uint8_t *base)
Computes and writes checksum field.
Definition: BlockHeader.cc:62
Base class for block headers.
Definition: BlockHeader.h:48
uint8_t decode_byte(const uint8_t **bufp, size_t *remainp)
Decodes a single byte from the given buffer.
Definition: Serialization.h:73
uint32_t m_data_length
Uncompressed length of the data stored within the block.
Definition: BlockHeader.h:220
Error codes, Exception handling, error logging.
#define HT_THROW(_code_, _msg_)
Definition: Error.h:478
BlockHeader(uint16_t version=LatestVersion, const char *magic=0)
Constructor.
Definition: BlockHeader.cc:50
char m_magic[10]
"Magic" string used to identify start of block header
Definition: BlockHeader.h:214
virtual void encode(uint8_t **bufp)
Encodes serialized representation of block header.
Definition: BlockHeader.cc:82