added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / util / compression.hpp
1 /*************************************************************************
2  *
3  * REALM CONFIDENTIAL
4  * __________________
5  *
6  *  [2011] - [2016] Realm Inc
7  *  All Rights Reserved.
8  *
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.
18  *
19  **************************************************************************/
20
21 #ifndef REALM_UTIL_COMPRESSION_HPP
22 #define REALM_UTIL_COMPRESSION_HPP
23
24 #include <system_error>
25 #include <vector>
26 #include <string>
27 #include <stdint.h>
28 #include <stddef.h>
29 #include <memory>
30
31 #include <realm/binary_data.hpp>
32
33 namespace realm {
34 namespace util {
35 namespace compression {
36
37 enum class error {
38     out_of_memory = 1,
39     compress_buffer_too_small = 2,
40     compress_error = 3,
41     corrupt_input = 4,
42     incorrect_decompressed_size = 5,
43     decompress_error = 6
44 };
45
46 const std::error_category& error_category() noexcept;
47
48 std::error_code make_error_code(error) noexcept;
49
50 } // namespace compression
51 } // namespace util
52 } // namespace realm
53
54 namespace std {
55
56 template<> struct is_error_code_enum<realm::util::compression::error> {
57     static const bool value = true;
58 };
59
60 } // namespace std
61
62 namespace realm {
63 namespace util {
64 namespace compression {
65
66 class Alloc {
67 public:
68     // Returns null on "out of memory"
69     virtual void* alloc(size_t size) = 0;
70     virtual void free(void* addr) noexcept = 0;
71     virtual ~Alloc() {}
72 };
73
74 class CompressMemoryArena: public Alloc {
75 public:
76     void* alloc(size_t size) override final
77     {
78         size_t offset = m_offset;
79         size_t padding = offset % alignof (std::max_align_t);
80         if (padding > m_size - offset)
81             return nullptr;
82         offset += padding;
83         void* addr = m_buffer.get() + offset;
84         if (size > m_size - offset)
85             return nullptr;
86         m_offset = offset + size;
87         return addr;
88     }
89
90     void free(void*) noexcept override final
91     {
92         // No-op
93     }
94
95     void reset() noexcept
96     {
97         m_offset = 0;
98     }
99
100     size_t size() const noexcept
101     {
102         return m_size;
103     }
104
105     void resize(size_t size)
106     {
107         m_buffer = std::make_unique<char[]>(size); // Throws
108         m_size = size;
109         m_offset = 0;
110     }
111
112 private:
113     size_t m_size = 0, m_offset = 0;
114     std::unique_ptr<char[]> m_buffer;
115 };
116
117
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);
126
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);
137
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);
147
148
149 size_t allocate_and_compress(CompressMemoryArena& compress_memory_arena,
150                              BinaryData uncompressed_buf,
151                              std::vector<char>& compressed_buf);
152
153
154
155 } // namespace compression
156 } // namespace util
157 } // namespace realm
158
159 #endif // REALM_UTIL_COMPRESSION_HPP