| author | |
| committer | |
| log | 89f9c5cb373c81af5cb052cd9e68e44a123d0b04 |
| tree | 1c4d428ad6138ff50d62c0d054acb5b23e31926d |
| parent | 7e2755646f5c9cab9973708a79c8aaa369d148e7 |
2 files changed, 137 insertions(+), 67 deletions(-)
lib/std/compress/zstandard/decode/block.zig+60-36| ... | ... | @@ -23,7 +23,6 @@ pub const Error = error{ |
| 23 | 23 | ReservedBlock, |
| 24 | 24 | MalformedRleBlock, |
| 25 | 25 | MalformedCompressedBlock, |
| 26 | EndOfStream, | |
| 27 | 26 | }; |
| 28 | 27 | |
| 29 | 28 | pub const DecodeState = struct { |
| ... | ... | @@ -92,11 +91,17 @@ pub const DecodeState = struct { |
| 92 | 91 | /// stream and Huffman tree from `literals` and reads the FSE tables from |
| 93 | 92 | /// `source`. |
| 94 | 93 | /// |
| 95 | /// Errors: | |
| 96 | /// - returns `error.BitStreamHasNoStartBit` if the (reversed) literal bitstream's | |
| 97 | /// first byte does not have any bits set. | |
| 98 | /// - returns `error.TreelessLiteralsFirst` `literals` is a treeless literals section | |
| 99 | /// and the decode state does not have a Huffman tree from a previous block. | |
| 94 | /// Errors returned: | |
| 95 | /// - `error.BitStreamHasNoStartBit` if the (reversed) literal bitstream's | |
| 96 | /// first byte does not have any bits set | |
| 97 | /// - `error.TreelessLiteralsFirst` `literals` is a treeless literals | |
| 98 | /// section and the decode state does not have a Huffman tree from a | |
| 99 | /// previous block | |
| 100 | /// - `error.RepeatModeFirst` on the first call if one of the sequence FSE | |
| 101 | /// tables is set to repeat mode | |
| 102 | /// - `error.MalformedAccuracyLog` if an FSE table has an invalid accuracy | |
| 103 | /// - `error.MalformedFseTable` if there are errors decoding an FSE table | |
| 104 | /// - `error.EndOfStream` if `source` ends before all FSE tables are read | |
| 100 | 105 | pub fn prepare( |
| 101 | 106 | self: *DecodeState, |
| 102 | 107 | source: anytype, |
| ... | ... | @@ -132,8 +137,10 @@ pub const DecodeState = struct { |
| 132 | 137 | } |
| 133 | 138 | } |
| 134 | 139 | |
| 135 | /// Read initial FSE states for sequence decoding. Returns `error.EndOfStream` | |
| 136 | /// if `bit_reader` does not contain enough bits. | |
| 140 | /// Read initial FSE states for sequence decoding. | |
| 141 | /// | |
| 142 | /// Errors returned: | |
| 143 | /// - `error.EndOfStream` if `bit_reader` does not contain enough bits. | |
| 137 | 144 | pub fn readInitialFseState(self: *DecodeState, bit_reader: *readers.ReverseBitReader) error{EndOfStream}!void { |
| 138 | 145 | self.literal.state = try bit_reader.readBitsNoEof(u9, self.literal.accuracy_log); |
| 139 | 146 | self.offset.state = try bit_reader.readBitsNoEof(u8, self.offset.accuracy_log); |
| ... | ... | @@ -308,13 +315,19 @@ pub const DecodeState = struct { |
| 308 | 315 | } || DecodeLiteralsError; |
| 309 | 316 | |
| 310 | 317 | /// Decode one sequence from `bit_reader` into `dest`, written starting at |
| 311 | /// `write_pos` and update FSE states if `last_sequence` is `false`. Returns | |
| 312 | /// `error.MalformedSequence` error if the decompressed sequence would be longer | |
| 313 | /// than `sequence_size_limit` or the sequence's offset is too large; returns | |
| 314 | /// `error.EndOfStream` if `bit_reader` does not contain enough bits; returns | |
| 315 | /// `error.UnexpectedEndOfLiteralStream` if the decoder state's literal streams | |
| 316 | /// do not contain enough literals for the sequence (this may mean the literal | |
| 317 | /// stream or the sequence is malformed). | |
| 318 | /// `write_pos` and update FSE states if `last_sequence` is `false`. | |
| 319 | /// `prepare()` must be called for the block before attempting to decode | |
| 320 | /// sequences. | |
| 321 | /// | |
| 322 | /// Errors returned: | |
| 323 | /// - `error.MalformedSequence` if the decompressed sequence would be | |
| 324 | /// longer than `sequence_size_limit` or the sequence's offset is too | |
| 325 | /// large | |
| 326 | /// - `error.UnexpectedEndOfLiteralStream` if the decoder state's literal | |
| 327 | /// streams do not contain enough literals for the sequence (this may | |
| 328 | /// mean the literal stream or the sequence is malformed). | |
| 329 | /// - `error.OffsetCodeTooLarge` if an invalid offset code is found | |
| 330 | /// - `error.EndOfStream` if `bit_reader` does not contain enough bits | |
| 318 | 331 | pub fn decodeSequenceSlice( |
| 319 | 332 | self: *DecodeState, |
| 320 | 333 | dest: []u8, |
| ... | ... | @@ -336,7 +349,8 @@ pub const DecodeState = struct { |
| 336 | 349 | return sequence_length; |
| 337 | 350 | } |
| 338 | 351 | |
| 339 | /// Decode one sequence from `bit_reader` into `dest`; see `decodeSequenceSlice`. | |
| 352 | /// Decode one sequence from `bit_reader` into `dest`; see | |
| 353 | /// `decodeSequenceSlice`. | |
| 340 | 354 | pub fn decodeSequenceRingBuffer( |
| 341 | 355 | self: *DecodeState, |
| 342 | 356 | dest: *RingBuffer, |
| ... | ... | @@ -364,7 +378,7 @@ pub const DecodeState = struct { |
| 364 | 378 | try self.initLiteralStream(self.literal_streams.four[self.literal_stream_index]); |
| 365 | 379 | } |
| 366 | 380 | |
| 367 | pub fn initLiteralStream(self: *DecodeState, bytes: []const u8) error{BitStreamHasNoStartBit}!void { | |
| 381 | fn initLiteralStream(self: *DecodeState, bytes: []const u8) error{BitStreamHasNoStartBit}!void { | |
| 368 | 382 | try self.literal_stream_reader.init(bytes); |
| 369 | 383 | } |
| 370 | 384 | |
| ... | ... | @@ -393,12 +407,14 @@ pub const DecodeState = struct { |
| 393 | 407 | PrefixNotFound, |
| 394 | 408 | } || LiteralBitsError; |
| 395 | 409 | |
| 396 | /// Decode `len` bytes of literals into `dest`. `literals` should be the | |
| 397 | /// `LiteralsSection` that was passed to `prepare()`. Returns | |
| 398 | /// `error.MalformedLiteralsLength` if the number of literal bytes decoded by | |
| 399 | /// `self` plus `len` is greater than the regenerated size of `literals`. | |
| 400 | /// Returns `error.UnexpectedEndOfLiteralStream` and `error.PrefixNotFound` if | |
| 401 | /// there are problems decoding Huffman compressed literals. | |
| 410 | /// Decode `len` bytes of literals into `dest`. | |
| 411 | /// | |
| 412 | /// Errors returned: | |
| 413 | /// - `error.MalformedLiteralsLength` if the number of literal bytes | |
| 414 | /// decoded by `self` plus `len` is greater than the regenerated size of | |
| 415 | /// `literals` | |
| 416 | /// - `error.UnexpectedEndOfLiteralStream` and `error.PrefixNotFound` if | |
| 417 | /// there are problems decoding Huffman compressed literals | |
| 402 | 418 | pub fn decodeLiteralsSlice( |
| 403 | 419 | self: *DecodeState, |
| 404 | 420 | dest: []u8, |
| ... | ... | @@ -561,7 +577,6 @@ pub const DecodeState = struct { |
| 561 | 577 | /// - `error.MalformedRleBlock` if the block is an RLE block and `src.len < 1` |
| 562 | 578 | /// - `error.MalformedCompressedBlock` if there are errors decoding a |
| 563 | 579 | /// compressed block |
| 564 | /// - `error.EndOfStream` if the sequence bit stream ends unexpectedly | |
| 565 | 580 | pub fn decodeBlock( |
| 566 | 581 | dest: []u8, |
| 567 | 582 | src: []const u8, |
| ... | ... | @@ -738,7 +753,8 @@ pub fn decodeBlockRingBuffer( |
| 738 | 753 | /// `error.SequenceBufferTooSmall` are returned (the maximum block size is an |
| 739 | 754 | /// upper bound for the size of both buffers). See `decodeBlock` |
| 740 | 755 | /// and `decodeBlockRingBuffer` for function that can decode a block without |
| 741 | /// these extra copies. | |
| 756 | /// these extra copies. `error.EndOfStream` is returned if `source` does not | |
| 757 | /// contain enough bytes. | |
| 742 | 758 | pub fn decodeBlockReader( |
| 743 | 759 | dest: *RingBuffer, |
| 744 | 760 | source: anytype, |
| ... | ... | @@ -820,6 +836,10 @@ pub fn decodeBlockHeader(src: *const [3]u8) frame.ZStandard.Block.Header { |
| 820 | 836 | }; |
| 821 | 837 | } |
| 822 | 838 | |
| 839 | /// Decode the header of a block. | |
| 840 | /// | |
| 841 | /// Errors returned: | |
| 842 | /// - `error.EndOfStream` if `src.len < 3` | |
| 823 | 843 | pub fn decodeBlockHeaderSlice(src: []const u8) error{EndOfStream}!frame.ZStandard.Block.Header { |
| 824 | 844 | if (src.len < 3) return error.EndOfStream; |
| 825 | 845 | return decodeBlockHeader(src[0..3]); |
| ... | ... | @@ -828,9 +848,14 @@ pub fn decodeBlockHeaderSlice(src: []const u8) error{EndOfStream}!frame.ZStandar |
| 828 | 848 | /// Decode a `LiteralsSection` from `src`, incrementing `consumed_count` by the |
| 829 | 849 | /// number of bytes the section uses. |
| 830 | 850 | /// |
| 831 | /// Errors: | |
| 832 | /// - returns `error.MalformedLiteralsHeader` if the header is invalid | |
| 833 | /// - returns `error.MalformedLiteralsSection` if there are errors decoding | |
| 851 | /// Errors returned: | |
| 852 | /// - `error.MalformedLiteralsHeader` if the header is invalid | |
| 853 | /// - `error.MalformedLiteralsSection` if there are decoding errors | |
| 854 | /// - `error.MalformedAccuracyLog` if compressed literals have invalid | |
| 855 | /// accuracy | |
| 856 | /// - `error.MalformedFseTable` if compressed literals have invalid FSE table | |
| 857 | /// - `error.MalformedHuffmanTree` if there are errors decoding a Huffamn tree | |
| 858 | /// - `error.EndOfStream` if there are not enough bytes in `src` | |
| 834 | 859 | pub fn decodeLiteralsSectionSlice( |
| 835 | 860 | src: []const u8, |
| 836 | 861 | consumed_count: *usize, |
| ... | ... | @@ -886,11 +911,7 @@ pub fn decodeLiteralsSectionSlice( |
| 886 | 911 | } |
| 887 | 912 | |
| 888 | 913 | /// Decode a `LiteralsSection` from `src`, incrementing `consumed_count` by the |
| 889 | /// number of bytes the section uses. | |
| 890 | /// | |
| 891 | /// Errors: | |
| 892 | /// - returns `error.MalformedLiteralsHeader` if the header is invalid | |
| 893 | /// - returns `error.MalformedLiteralsSection` if there are errors decoding | |
| 914 | /// number of bytes the section uses. See `decodeLiterasSectionSlice()`. | |
| 894 | 915 | pub fn decodeLiteralsSection( |
| 895 | 916 | source: anytype, |
| 896 | 917 | buffer: []u8, |
| ... | ... | @@ -961,6 +982,9 @@ fn decodeStreams(size_format: u2, stream_data: []const u8) !LiteralsSection.Stre |
| 961 | 982 | } |
| 962 | 983 | |
| 963 | 984 | /// Decode a literals section header. |
| 985 | /// | |
| 986 | /// Errors returned: | |
| 987 | /// - `error.EndOfStream` if there are not enough bytes in `source` | |
| 964 | 988 | pub fn decodeLiteralsHeader(source: anytype) !LiteralsSection.Header { |
| 965 | 989 | const byte0 = try source.readByte(); |
| 966 | 990 | const block_type = @intToEnum(LiteralsSection.BlockType, byte0 & 0b11); |
| ... | ... | @@ -1011,9 +1035,9 @@ pub fn decodeLiteralsHeader(source: anytype) !LiteralsSection.Header { |
| 1011 | 1035 | |
| 1012 | 1036 | /// Decode a sequences section header. |
| 1013 | 1037 | /// |
| 1014 | /// Errors: | |
| 1015 | /// - returns `error.ReservedBitSet` is the reserved bit is set | |
| 1016 | /// - returns `error.MalformedSequencesHeader` if the header is invalid | |
| 1038 | /// Errors returned: | |
| 1039 | /// - `error.ReservedBitSet` if the reserved bit is set | |
| 1040 | /// - `error.EndOfStream` if there are not enough bytes in `source` | |
| 1017 | 1041 | pub fn decodeSequencesHeader( |
| 1018 | 1042 | source: anytype, |
| 1019 | 1043 | ) !SequencesSection.Header { |
lib/std/compress/zstandard/decompress.zig+77-31| ... | ... | @@ -25,11 +25,12 @@ pub fn isSkippableMagic(magic: u32) bool { |
| 25 | 25 | |
| 26 | 26 | /// Returns the kind of frame at the beginning of `src`. |
| 27 | 27 | /// |
| 28 | /// Errors: | |
| 29 | /// - returns `error.BadMagic` if `source` begins with bytes not equal to the | |
| 28 | /// Errors returned: | |
| 29 | /// - `error.BadMagic` if `source` begins with bytes not equal to the | |
| 30 | 30 | /// Zstandard frame magic number, or outside the range of magic numbers for |
| 31 | 31 | /// skippable frames. |
| 32 | pub fn decodeFrameType(source: anytype) !frame.Kind { | |
| 32 | /// - `error.EndOfStream` if `source` contains fewer than 4 bytes | |
| 33 | pub fn decodeFrameType(source: anytype) error{ BadMagic, EndOfStream }!frame.Kind { | |
| 33 | 34 | const magic = try source.readIntLittle(u32); |
| 34 | 35 | return if (magic == frame.ZStandard.magic_number) |
| 35 | 36 | .zstandard |
| ... | ... | @@ -45,12 +46,23 @@ const ReadWriteCount = struct { |
| 45 | 46 | }; |
| 46 | 47 | |
| 47 | 48 | /// Decodes the frame at the start of `src` into `dest`. Returns the number of |
| 48 | /// bytes read from `src` and written to `dest`. | |
| 49 | /// bytes read from `src` and written to `dest`. This function can only decode | |
| 50 | /// frames that declare the decompressed content size. | |
| 49 | 51 | /// |
| 50 | /// Errors: | |
| 51 | /// - returns `error.UnknownContentSizeUnsupported` | |
| 52 | /// - returns `error.ContentTooLarge` | |
| 53 | /// - returns `error.BadMagic` | |
| 52 | /// Errors returned: | |
| 53 | /// - `error.UnknownContentSizeUnsupported` if the frame does not declare the | |
| 54 | /// uncompressed content size | |
| 55 | /// - `error.ContentTooLarge` if `dest` is smaller than the uncompressed data | |
| 56 | /// - `error.BadMagic` if the first 4 bytes of `src` is not a valid magic | |
| 57 | /// number for a Zstandard or Skippable frame | |
| 58 | /// - `error.DictionaryIdFlagUnsupported` if the frame uses a dictionary | |
| 59 | /// - `error.ChecksumFailure` if `verify_checksum` is true and the frame | |
| 60 | /// contains a checksum that does not match the checksum of the decompressed | |
| 61 | /// data | |
| 62 | /// - `error.ReservedBitSet` if the reserved bit of the frame header is set | |
| 63 | /// - `error.UnusedBitSet` if the unused bit of the frame header is set | |
| 64 | /// - `error.EndOfStream` if `src` does not contain a complete frame | |
| 65 | /// - an error in `block.Error` if there are errors decoding a block | |
| 54 | 66 | pub fn decodeFrame( |
| 55 | 67 | dest: []u8, |
| 56 | 68 | src: []const u8, |
| ... | ... | @@ -66,6 +78,7 @@ pub fn decodeFrame( |
| 66 | 78 | }; |
| 67 | 79 | } |
| 68 | 80 | |
| 81 | /// Returns the frame checksum corresponding to the data fed into `hasher` | |
| 69 | 82 | pub fn computeChecksum(hasher: *std.hash.XxHash64) u32 { |
| 70 | 83 | const hash = hasher.final(); |
| 71 | 84 | return @intCast(u32, hash & 0xFFFFFFFF); |
| ... | ... | @@ -74,20 +87,31 @@ pub fn computeChecksum(hasher: *std.hash.XxHash64) u32 { |
| 74 | 87 | const FrameError = error{ |
| 75 | 88 | DictionaryIdFlagUnsupported, |
| 76 | 89 | ChecksumFailure, |
| 90 | EndOfStream, | |
| 77 | 91 | } || InvalidBit || block.Error; |
| 78 | 92 | |
| 79 | 93 | /// Decode a Zstandard frame from `src` into `dest`, returning the number of |
| 80 | /// bytes read from `src` and written to `dest`; if the frame does not declare | |
| 81 | /// its decompressed content size `error.UnknownContentSizeUnsupported` is | |
| 82 | /// returned. Returns `error.DictionaryIdFlagUnsupported` if the frame uses a | |
| 83 | /// dictionary, and `error.ChecksumFailure` if `verify_checksum` is `true` and | |
| 84 | /// the frame contains a checksum that does not match the checksum computed from | |
| 85 | /// the decompressed frame. | |
| 94 | /// bytes read from `src` and written to `dest`. The first four bytes of `src` | |
| 95 | /// must be the magic number for a Zstandard frame. | |
| 96 | /// | |
| 97 | /// Error returned: | |
| 98 | /// - `error.UnknownContentSizeUnsupported` if the frame does not declare the | |
| 99 | /// uncompressed content size | |
| 100 | /// - `error.ContentTooLarge` if `dest` is smaller than the uncompressed data | |
| 101 | /// number for a Zstandard or Skippable frame | |
| 102 | /// - `error.DictionaryIdFlagUnsupported` if the frame uses a dictionary | |
| 103 | /// - `error.ChecksumFailure` if `verify_checksum` is true and the frame | |
| 104 | /// contains a checksum that does not match the checksum of the decompressed | |
| 105 | /// data | |
| 106 | /// - `error.ReservedBitSet` if the reserved bit of the frame header is set | |
| 107 | /// - `error.UnusedBitSet` if the unused bit of the frame header is set | |
| 108 | /// - `error.EndOfStream` if `src` does not contain a complete frame | |
| 109 | /// - an error in `block.Error` if there are errors decoding a block | |
| 86 | 110 | pub fn decodeZStandardFrame( |
| 87 | 111 | dest: []u8, |
| 88 | 112 | src: []const u8, |
| 89 | 113 | verify_checksum: bool, |
| 90 | ) (error{ UnknownContentSizeUnsupported, ContentTooLarge, EndOfStream } || FrameError)!ReadWriteCount { | |
| 114 | ) (error{ UnknownContentSizeUnsupported, ContentTooLarge } || FrameError)!ReadWriteCount { | |
| 91 | 115 | assert(readInt(u32, src[0..4]) == frame.ZStandard.magic_number); |
| 92 | 116 | var consumed_count: usize = 4; |
| 93 | 117 | |
| ... | ... | @@ -127,7 +151,18 @@ pub const FrameContext = struct { |
| 127 | 151 | has_checksum: bool, |
| 128 | 152 | block_size_max: usize, |
| 129 | 153 | |
| 130 | pub fn init(frame_header: frame.ZStandard.Header, window_size_max: usize, verify_checksum: bool) !FrameContext { | |
| 154 | const Error = error{ DictionaryIdFlagUnsupported, WindowSizeUnknown, WindowTooLarge }; | |
| 155 | /// Validates `frame_header` and returns the associated `FrameContext`. | |
| 156 | /// | |
| 157 | /// Errors returned: | |
| 158 | /// - `error.DictionaryIdFlagUnsupported` if the frame uses a dictionary | |
| 159 | /// - `error.WindowSizeUnknown` if the frame does not have a valid window size | |
| 160 | /// - `error.WindowTooLarge` if the window size is larger than | |
| 161 | pub fn init( | |
| 162 | frame_header: frame.ZStandard.Header, | |
| 163 | window_size_max: usize, | |
| 164 | verify_checksum: bool, | |
| 165 | ) Error!FrameContext { | |
| 131 | 166 | if (frame_header.descriptor.dictionary_id_flag != 0) return error.DictionaryIdFlagUnsupported; |
| 132 | 167 | |
| 133 | 168 | const window_size_raw = frameWindowSize(frame_header) orelse return error.WindowSizeUnknown; |
| ... | ... | @@ -147,19 +182,29 @@ pub const FrameContext = struct { |
| 147 | 182 | }; |
| 148 | 183 | |
| 149 | 184 | /// Decode a Zstandard from from `src` and return the decompressed bytes; see |
| 150 | /// `decodeZStandardFrame()`. Returns `error.WindowSizeUnknown` if the frame | |
| 151 | /// does not declare its content size or a window descriptor (this indicates a | |
| 152 | /// malformed frame). | |
| 185 | /// `decodeZStandardFrame()`. `allocator` is used to allocate both the returned | |
| 186 | /// slice and internal buffers used during decoding. The first four bytes of | |
| 187 | /// `src` must be the magic number for a Zstandard frame. | |
| 153 | 188 | /// |
| 154 | /// Errors: | |
| 155 | /// - returns `error.WindowTooLarge` | |
| 156 | /// - returns `error.WindowSizeUnknown` | |
| 189 | /// Errors returned: | |
| 190 | /// - `error.WindowSizeUnknown` if the frame does not have a valid window size | |
| 191 | /// - `error.WindowTooLarge` if the window size is larger than | |
| 192 | /// `window_size_max` | |
| 193 | /// - `error.DictionaryIdFlagUnsupported` if the frame uses a dictionary | |
| 194 | /// - `error.ChecksumFailure` if `verify_checksum` is true and the frame | |
| 195 | /// contains a checksum that does not match the checksum of the decompressed | |
| 196 | /// data | |
| 197 | /// - `error.ReservedBitSet` if the reserved bit of the frame header is set | |
| 198 | /// - `error.UnusedBitSet` if the unused bit of the frame header is set | |
| 199 | /// - `error.EndOfStream` if `src` does not contain a complete frame | |
| 200 | /// - `error.OutOfMemory` if `allocator` cannot allocate enough memory | |
| 201 | /// - an error in `block.Error` if there are errors decoding a block | |
| 157 | 202 | pub fn decodeZStandardFrameAlloc( |
| 158 | 203 | allocator: std.mem.Allocator, |
| 159 | 204 | src: []const u8, |
| 160 | 205 | verify_checksum: bool, |
| 161 | 206 | window_size_max: usize, |
| 162 | ) (error{ WindowSizeUnknown, WindowTooLarge, OutOfMemory, EndOfStream } || FrameError)![]u8 { | |
| 207 | ) (error{OutOfMemory} || FrameContext.Error || FrameError)![]u8 { | |
| 163 | 208 | var result = std.ArrayList(u8).init(allocator); |
| 164 | 209 | assert(readInt(u32, src[0..4]) == frame.ZStandard.magic_number); |
| 165 | 210 | var consumed_count: usize = 4; |
| ... | ... | @@ -222,7 +267,7 @@ fn decodeFrameBlocks( |
| 222 | 267 | src: []const u8, |
| 223 | 268 | consumed_count: *usize, |
| 224 | 269 | hash: ?*std.hash.XxHash64, |
| 225 | ) block.Error!usize { | |
| 270 | ) (error{EndOfStream} || block.Error)!usize { | |
| 226 | 271 | // These tables take 7680 bytes |
| 227 | 272 | var literal_fse_data: [types.compressed_block.table_size_max.literal]Table.Fse = undefined; |
| 228 | 273 | var match_fse_data: [types.compressed_block.table_size_max.match]Table.Fse = undefined; |
| ... | ... | @@ -252,7 +297,8 @@ fn decodeFrameBlocks( |
| 252 | 297 | return written_count; |
| 253 | 298 | } |
| 254 | 299 | |
| 255 | /// Decode the header of a skippable frame. | |
| 300 | /// Decode the header of a skippable frame. The first four bytes of `src` must | |
| 301 | /// be a valid magic number for a Skippable frame. | |
| 256 | 302 | pub fn decodeSkippableHeader(src: *const [8]u8) frame.Skippable.Header { |
| 257 | 303 | const magic = readInt(u32, src[0..4]); |
| 258 | 304 | assert(isSkippableMagic(magic)); |
| ... | ... | @@ -263,8 +309,8 @@ pub fn decodeSkippableHeader(src: *const [8]u8) frame.Skippable.Header { |
| 263 | 309 | }; |
| 264 | 310 | } |
| 265 | 311 | |
| 266 | /// Returns the window size required to decompress a frame, or `null` if it cannot be | |
| 267 | /// determined, which indicates a malformed frame header. | |
| 312 | /// Returns the window size required to decompress a frame, or `null` if it | |
| 313 | /// cannot be determined (which indicates a malformed frame header). | |
| 268 | 314 | pub fn frameWindowSize(header: frame.ZStandard.Header) ?u64 { |
| 269 | 315 | if (header.window_descriptor) |descriptor| { |
| 270 | 316 | const exponent = (descriptor & 0b11111000) >> 3; |
| ... | ... | @@ -279,10 +325,10 @@ pub fn frameWindowSize(header: frame.ZStandard.Header) ?u64 { |
| 279 | 325 | const InvalidBit = error{ UnusedBitSet, ReservedBitSet }; |
| 280 | 326 | /// Decode the header of a Zstandard frame. |
| 281 | 327 | /// |
| 282 | /// Errors: | |
| 283 | /// - returns `error.UnusedBitSet` if the unused bits of the header are set | |
| 284 | /// - returns `error.ReservedBitSet` if the reserved bits of the header are | |
| 285 | /// set | |
| 328 | /// Errors returned: | |
| 329 | /// - `error.UnusedBitSet` if the unused bits of the header are set | |
| 330 | /// - `error.ReservedBitSet` if the reserved bits of the header are set | |
| 331 | /// - `error.EndOfStream` if `source` does not contain a complete header | |
| 286 | 332 | pub fn decodeZStandardHeader(source: anytype) (error{EndOfStream} || InvalidBit)!frame.ZStandard.Header { |
| 287 | 333 | const descriptor = @bitCast(frame.ZStandard.Header.Descriptor, try source.readByte()); |
| 288 | 334 |