1 /*************************************************************************
6 * [2011] - [2016] Realm Inc
9 * NOTICE: All information contained herein is, and remains
10 * the property of Realm Incorporated and its suppliers,
11 * if any. The intellectual and technical concepts contained
12 * herein are proprietary to Realm Incorporated
13 * and its suppliers and may be covered by U.S. and Foreign Patents,
14 * patents in process, and are protected by trade secret or copyright law.
15 * Dissemination of this information or reproduction of this material
16 * is strictly forbidden unless prior written permission is obtained
17 * from Realm Incorporated.
19 **************************************************************************/
21 #ifndef REALM_UTIL_COMPRESSION_HPP
22 #define REALM_UTIL_COMPRESSION_HPP
24 #include <system_error>
31 #include <realm/binary_data.hpp>
35 namespace compression {
39 compress_buffer_too_small = 2,
42 incorrect_decompressed_size = 5,
46 const std::error_category& error_category() noexcept;
48 std::error_code make_error_code(error) noexcept;
50 } // namespace compression
56 template<> struct is_error_code_enum<realm::util::compression::error> {
57 static const bool value = true;
64 namespace compression {
68 // Returns null on "out of memory"
69 virtual void* alloc(size_t size) = 0;
70 virtual void free(void* addr) noexcept = 0;
74 class CompressMemoryArena: public Alloc {
76 void* alloc(size_t size) override final
78 size_t offset = m_offset;
79 size_t padding = offset % alignof (std::max_align_t);
80 if (padding > m_size - offset)
83 void* addr = m_buffer.get() + offset;
84 if (size > m_size - offset)
86 m_offset = offset + size;
90 void free(void*) noexcept override final
100 size_t size() const noexcept
105 void resize(size_t size)
107 m_buffer = std::make_unique<char[]>(size); // Throws
113 size_t m_size = 0, m_offset = 0;
114 std::unique_ptr<char[]> m_buffer;
118 /// compress_bound() calculates an upper bound on the size of the compressed
119 /// data. The caller can use this function to allocate memory buffer calling
120 /// compress(). \a uncompressed_buf is the buffer with uncompresed data. The
121 /// size of the uncompressed data is \a uncompressed_size. \a compression_level
122 /// is described under compress(). \a bound is set to the upper bound at
123 /// return. The returned error code is of category compression::error_category.
124 std::error_code compress_bound(const char* uncompressed_buf, size_t uncompressed_size,
125 size_t& bound, int compression_level = 1);
127 /// compress() compresses the data in the \a uncompressed_buf of size \a
128 /// uncompressed_size into \a compressed_buf. compress() resizes \a
129 /// compressed_buf. At return, \a compressed_buf has the size of the compressed
130 /// data. \a compression_level is [1-9] with 1 the fastest for the current zlib
131 /// implementation. The returned error code is of category
132 /// compression::error_category.
133 std::error_code compress(const char* uncompressed_buf, size_t uncompressed_size,
134 char* compressed_buf, size_t compressed_buf_size,
135 size_t& compressed_size, int compression_level = 1,
136 Alloc* custom_allocator = nullptr);
138 /// decompress() decompresses the data in \param compressed_buf of size \a
139 /// compresed_size into \a decompressed_buf. \a decompressed_size is the
140 /// expected size of the decompressed data. \a decompressed_buf must have size
141 /// at least \a decompressed_size. decompress() throws on errors, including the
142 /// error where the size of the decompressed data is unequal to
143 /// decompressed_size. The returned error code is of category
144 /// compression::error_category.
145 std::error_code decompress(const char* compressed_buf, size_t compressed_size,
146 char* decompressed_buf, size_t decompressed_size);
149 size_t allocate_and_compress(CompressMemoryArena& compress_memory_arena,
150 BinaryData uncompressed_buf,
151 std::vector<char>& compressed_buf);
155 } // namespace compression
159 #endif // REALM_UTIL_COMPRESSION_HPP