xref: /netbsd-src/external/bsd/zstd/dist/contrib/pzstd/SkippableFrame.h (revision 3117ece4fc4a4ca4489ba793710b60b0d26bab6c)
1*3117ece4Schristos /*
2*3117ece4Schristos  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*3117ece4Schristos  * All rights reserved.
4*3117ece4Schristos  *
5*3117ece4Schristos  * This source code is licensed under both the BSD-style license (found in the
6*3117ece4Schristos  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*3117ece4Schristos  * in the COPYING file in the root directory of this source tree).
8*3117ece4Schristos  */
9*3117ece4Schristos #pragma once
10*3117ece4Schristos 
11*3117ece4Schristos #include "utils/Range.h"
12*3117ece4Schristos 
13*3117ece4Schristos #include <array>
14*3117ece4Schristos #include <cstddef>
15*3117ece4Schristos #include <cstdint>
16*3117ece4Schristos #include <cstdio>
17*3117ece4Schristos 
18*3117ece4Schristos namespace pzstd {
19*3117ece4Schristos /**
20*3117ece4Schristos  * We put a skippable frame before each frame.
21*3117ece4Schristos  * It contains a skippable frame magic number, the size of the skippable frame,
22*3117ece4Schristos  * and the size of the next frame.
23*3117ece4Schristos  * Each skippable frame is exactly 12 bytes in little endian format.
24*3117ece4Schristos  * The first 8 bytes are for compatibility with the ZSTD format.
25*3117ece4Schristos  * If we have N threads, the output will look like
26*3117ece4Schristos  *
27*3117ece4Schristos  * [0x184D2A50|4|size1] [frame1 of size size1]
28*3117ece4Schristos  * [0x184D2A50|4|size2] [frame2 of size size2]
29*3117ece4Schristos  * ...
30*3117ece4Schristos  * [0x184D2A50|4|sizeN] [frameN of size sizeN]
31*3117ece4Schristos  *
32*3117ece4Schristos  * Each sizeX is 4 bytes.
33*3117ece4Schristos  *
34*3117ece4Schristos  * These skippable frames should allow us to skip through the compressed file
35*3117ece4Schristos  * and only load at most N pages.
36*3117ece4Schristos  */
37*3117ece4Schristos class SkippableFrame {
38*3117ece4Schristos  public:
39*3117ece4Schristos   static constexpr std::size_t kSize = 12;
40*3117ece4Schristos 
41*3117ece4Schristos  private:
42*3117ece4Schristos   std::uint32_t frameSize_;
43*3117ece4Schristos   std::array<std::uint8_t, kSize> data_;
44*3117ece4Schristos   static constexpr std::uint32_t kSkippableFrameMagicNumber = 0x184D2A50;
45*3117ece4Schristos   // Could be improved if the size fits in less bytes
46*3117ece4Schristos   static constexpr std::uint32_t kFrameContentsSize = kSize - 8;
47*3117ece4Schristos 
48*3117ece4Schristos  public:
49*3117ece4Schristos    // Write the skippable frame to data_ in LE format.
50*3117ece4Schristos   explicit SkippableFrame(std::uint32_t size);
51*3117ece4Schristos 
52*3117ece4Schristos   // Read the skippable frame from bytes in LE format.
53*3117ece4Schristos   static std::size_t tryRead(ByteRange bytes);
54*3117ece4Schristos 
55*3117ece4Schristos   ByteRange data() const {
56*3117ece4Schristos     return {data_.data(), data_.size()};
57*3117ece4Schristos   }
58*3117ece4Schristos 
59*3117ece4Schristos   // Size of the next frame.
60*3117ece4Schristos   std::size_t frameSize() const {
61*3117ece4Schristos     return frameSize_;
62*3117ece4Schristos   }
63*3117ece4Schristos };
64*3117ece4Schristos }
65