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
29using std::size_t;
30
31namespace arrow {
32namespace util {
33
34// ----------------------------------------------------------------------
35// Snappy implementation
36
37Status SnappyCodec::MakeCompressor(std::shared_ptr<Compressor>* out) {
38 return Status::NotImplemented("Streaming compression unsupported with Snappy");
39}
40
41Status SnappyCodec::MakeDecompressor(std::shared_ptr<Decompressor>* out) {
42 return Status::NotImplemented("Streaming decompression unsupported with Snappy");
43}
44
45Status 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
50Status 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
74int64_t SnappyCodec::MaxCompressedLen(int64_t input_len,
75 const uint8_t* ARROW_ARG_UNUSED(input)) {
76 return snappy::MaxCompressedLength(input_len);
77}
78
79Status 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