Feathercoin  0.5.0
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
format.cc
Go to the documentation of this file.
1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
4 
5 #include "table/format.h"
6 
7 #include "leveldb/env.h"
8 #include "port/port.h"
9 #include "table/block.h"
10 #include "util/coding.h"
11 #include "util/crc32c.h"
12 
13 namespace leveldb {
14 
15 void BlockHandle::EncodeTo(std::string* dst) const {
16  // Sanity check that all fields have been set
17  assert(offset_ != ~static_cast<uint64_t>(0));
18  assert(size_ != ~static_cast<uint64_t>(0));
19  PutVarint64(dst, offset_);
20  PutVarint64(dst, size_);
21 }
22 
24  if (GetVarint64(input, &offset_) &&
25  GetVarint64(input, &size_)) {
26  return Status::OK();
27  } else {
28  return Status::Corruption("bad block handle");
29  }
30 }
31 
32 void Footer::EncodeTo(std::string* dst) const {
33 #ifndef NDEBUG
34  const size_t original_size = dst->size();
35 #endif
38  dst->resize(2 * BlockHandle::kMaxEncodedLength); // Padding
39  PutFixed32(dst, static_cast<uint32_t>(kTableMagicNumber & 0xffffffffu));
40  PutFixed32(dst, static_cast<uint32_t>(kTableMagicNumber >> 32));
41  assert(dst->size() == original_size + kEncodedLength);
42 }
43 
45  const char* magic_ptr = input->data() + kEncodedLength - 8;
46  const uint32_t magic_lo = DecodeFixed32(magic_ptr);
47  const uint32_t magic_hi = DecodeFixed32(magic_ptr + 4);
48  const uint64_t magic = ((static_cast<uint64_t>(magic_hi) << 32) |
49  (static_cast<uint64_t>(magic_lo)));
50  if (magic != kTableMagicNumber) {
51  return Status::InvalidArgument("not an sstable (bad magic number)");
52  }
53 
54  Status result = metaindex_handle_.DecodeFrom(input);
55  if (result.ok()) {
56  result = index_handle_.DecodeFrom(input);
57  }
58  if (result.ok()) {
59  // We skip over any leftover data (just padding for now) in "input"
60  const char* end = magic_ptr + 8;
61  *input = Slice(end, input->data() + input->size() - end);
62  }
63  return result;
64 }
65 
67  const ReadOptions& options,
68  const BlockHandle& handle,
69  BlockContents* result) {
70  result->data = Slice();
71  result->cachable = false;
72  result->heap_allocated = false;
73 
74  // Read the block contents as well as the type/crc footer.
75  // See table_builder.cc for the code that built this structure.
76  size_t n = static_cast<size_t>(handle.size());
77  char* buf = new char[n + kBlockTrailerSize];
78  Slice contents;
79  Status s = file->Read(handle.offset(), n + kBlockTrailerSize, &contents, buf);
80  if (!s.ok()) {
81  delete[] buf;
82  return s;
83  }
84  if (contents.size() != n + kBlockTrailerSize) {
85  delete[] buf;
86  return Status::Corruption("truncated block read");
87  }
88 
89  // Check the crc of the type and the block contents
90  const char* data = contents.data(); // Pointer to where Read put the data
91  if (options.verify_checksums) {
92  const uint32_t crc = crc32c::Unmask(DecodeFixed32(data + n + 1));
93  const uint32_t actual = crc32c::Value(data, n + 1);
94  if (actual != crc) {
95  delete[] buf;
96  s = Status::Corruption("block checksum mismatch");
97  return s;
98  }
99  }
100 
101  switch (data[n]) {
102  case kNoCompression:
103  if (data != buf) {
104  // File implementation gave us pointer to some other data.
105  // Use it directly under the assumption that it will be live
106  // while the file is open.
107  delete[] buf;
108  result->data = Slice(data, n);
109  result->heap_allocated = false;
110  result->cachable = false; // Do not double-cache
111  } else {
112  result->data = Slice(buf, n);
113  result->heap_allocated = true;
114  result->cachable = true;
115  }
116 
117  // Ok
118  break;
119  case kSnappyCompression: {
120  size_t ulength = 0;
121  if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) {
122  delete[] buf;
123  return Status::Corruption("corrupted compressed block contents");
124  }
125  char* ubuf = new char[ulength];
126  if (!port::Snappy_Uncompress(data, n, ubuf)) {
127  delete[] buf;
128  delete[] ubuf;
129  return Status::Corruption("corrupted compressed block contents");
130  }
131  delete[] buf;
132  result->data = Slice(ubuf, ulength);
133  result->heap_allocated = true;
134  result->cachable = true;
135  break;
136  }
137  default:
138  delete[] buf;
139  return Status::Corruption("bad block type");
140  }
141 
142  return Status::OK();
143 }
144 
145 } // namespace leveldb
void PutFixed32(std::string *dst, uint32_t value)
Definition: coding.cc:35
uint64_t size() const
Definition: format.h:31
virtual Status Read(uint64_t offset, size_t n, Slice *result, char *scratch) const =0
bool Snappy_Uncompress(const char *input_data, size_t input_length, char *output)
Definition: port_posix.h:145
const char * data() const
Definition: slice.h:40
void PutVarint64(std::string *dst, uint64_t v)
Definition: coding.cc:92
uint64_t offset_
Definition: format.h:41
Status DecodeFrom(Slice *input)
Definition: format.cc:23
static Status Corruption(const Slice &msg, const Slice &msg2=Slice())
Definition: status.h:38
uint32_t DecodeFixed32(const char *ptr)
Definition: coding.h:58
uint32_t Unmask(uint32_t masked_crc)
Definition: crc32c.h:37
static Status OK()
Definition: status.h:32
bool Snappy_GetUncompressedLength(const char *input, size_t length, size_t *result)
Definition: port_posix.h:136
static Status InvalidArgument(const Slice &msg, const Slice &msg2=Slice())
Definition: status.h:44
void EncodeTo(std::string *dst) const
Definition: format.cc:15
unsigned int uint32_t
Definition: stdint.h:21
size_t size() const
Definition: slice.h:43
unsigned long long uint64_t
Definition: stdint.h:22
uint64_t size_
Definition: format.h:42
uint32_t Value(const char *data, size_t n)
Definition: crc32c.h:20
uint64_t offset() const
Definition: format.h:27
bool GetVarint64(Slice *input, uint64_t *value)
Definition: coding.cc:160
bool ok() const
Definition: status.h:52
Status ReadBlock(RandomAccessFile *file, const ReadOptions &options, const BlockHandle &handle, BlockContents *result)
Definition: format.cc:66