1 | // Licensed to the Apache Software Foundation (ASF) under one |
2 | // or more contributor license agreements. See the NOTICE file |
3 | // distributed with this work for additional information |
4 | // regarding copyright ownership. The ASF licenses this file |
5 | // to you under the Apache License, Version 2.0 (the |
6 | // "License"); you may not use this file except in compliance |
7 | // with the License. You may obtain a copy of the License at |
8 | // |
9 | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | // |
11 | // Unless required by applicable law or agreed to in writing, |
12 | // software distributed under the License is distributed on an |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | // KIND, either express or implied. See the License for the |
15 | // specific language governing permissions and limitations |
16 | // under the License. |
17 | |
18 | #include "arrow/util/compression_snappy.h" |
19 | |
20 | #include <cstddef> |
21 | #include <cstdint> |
22 | #include <sstream> |
23 | |
24 | #include <snappy.h> |
25 | |
26 | #include "arrow/status.h" |
27 | #include "arrow/util/macros.h" |
28 | |
29 | using std::size_t; |
30 | |
31 | namespace arrow { |
32 | namespace util { |
33 | |
34 | // ---------------------------------------------------------------------- |
35 | // Snappy implementation |
36 | |
37 | Status SnappyCodec::MakeCompressor(std::shared_ptr<Compressor>* out) { |
38 | return Status::NotImplemented("Streaming compression unsupported with Snappy" ); |
39 | } |
40 | |
41 | Status SnappyCodec::MakeDecompressor(std::shared_ptr<Decompressor>* out) { |
42 | return Status::NotImplemented("Streaming decompression unsupported with Snappy" ); |
43 | } |
44 | |
45 | Status SnappyCodec::Decompress(int64_t input_len, const uint8_t* input, |
46 | int64_t output_buffer_len, uint8_t* output_buffer) { |
47 | return Decompress(input_len, input, output_buffer_len, output_buffer, nullptr); |
48 | } |
49 | |
50 | Status SnappyCodec::Decompress(int64_t input_len, const uint8_t* input, |
51 | int64_t output_buffer_len, uint8_t* output_buffer, |
52 | int64_t* output_len) { |
53 | size_t decompressed_size; |
54 | if (!snappy::GetUncompressedLength(reinterpret_cast<const char*>(input), |
55 | static_cast<size_t>(input_len), |
56 | &decompressed_size)) { |
57 | return Status::IOError("Corrupt snappy compressed data." ); |
58 | } |
59 | if (output_buffer_len < static_cast<int64_t>(decompressed_size)) { |
60 | return Status::Invalid("Output buffer size (" , output_buffer_len, ") must be " , |
61 | decompressed_size, " or larger." ); |
62 | } |
63 | if (output_len) { |
64 | *output_len = static_cast<int64_t>(decompressed_size); |
65 | } |
66 | if (!snappy::RawUncompress(reinterpret_cast<const char*>(input), |
67 | static_cast<size_t>(input_len), |
68 | reinterpret_cast<char*>(output_buffer))) { |
69 | return Status::IOError("Corrupt snappy compressed data." ); |
70 | } |
71 | return Status::OK(); |
72 | } |
73 | |
74 | int64_t SnappyCodec::MaxCompressedLen(int64_t input_len, |
75 | const uint8_t* ARROW_ARG_UNUSED(input)) { |
76 | return snappy::MaxCompressedLength(input_len); |
77 | } |
78 | |
79 | Status SnappyCodec::Compress(int64_t input_len, const uint8_t* input, |
80 | int64_t ARROW_ARG_UNUSED(output_buffer_len), |
81 | uint8_t* output_buffer, int64_t* output_len) { |
82 | size_t output_size; |
83 | snappy::RawCompress(reinterpret_cast<const char*>(input), |
84 | static_cast<size_t>(input_len), |
85 | reinterpret_cast<char*>(output_buffer), &output_size); |
86 | *output_len = static_cast<int64_t>(output_size); |
87 | return Status::OK(); |
88 | } |
89 | |
90 | } // namespace util |
91 | } // namespace arrow |
92 | |