1/*
2 * Copyright 2017-present Facebook, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <type_traits>
20
21#include <folly/io/Cursor.h>
22#include <folly/io/IOBuf.h>
23#include <folly/lang/Bits.h>
24
25/**
26 * Helper functions for compression codecs.
27 */
28namespace folly {
29namespace io {
30namespace compression {
31namespace detail {
32
33/**
34 * Reads sizeof(T) bytes, and returns false if not enough bytes are available.
35 * Returns true if the first n bytes are equal to prefix when interpreted as
36 * a little endian T.
37 */
38template <typename T>
39typename std::enable_if<std::is_unsigned<T>::value, bool>::type
40dataStartsWithLE(const IOBuf* data, T prefix, uint64_t n = sizeof(T)) {
41 DCHECK_GT(n, 0);
42 DCHECK_LE(n, sizeof(T));
43 T value;
44 Cursor cursor{data};
45 if (!cursor.tryReadLE(value)) {
46 return false;
47 }
48 const T mask = n == sizeof(T) ? T(-1) : (T(1) << (8 * n)) - 1;
49 return prefix == (value & mask);
50}
51
52template <typename T>
53typename std::enable_if<std::is_arithmetic<T>::value, std::string>::type
54prefixToStringLE(T prefix, uint64_t n = sizeof(T)) {
55 DCHECK_GT(n, 0);
56 DCHECK_LE(n, sizeof(T));
57 prefix = Endian::little(prefix);
58 std::string result;
59 result.resize(n);
60 memcpy(&result[0], &prefix, n);
61 return result;
62}
63
64} // namespace detail
65} // namespace compression
66} // namespace io
67} // namespace folly
68