Merge pull request #258 from Alb3e3/fix/export-installed-header-paths

Honor CMAKE_INSTALL_INCLUDEDIR in exported header paths
diff --git a/README.md b/README.md
index a4368d7..64eccfb 100644
--- a/README.md
+++ b/README.md
@@ -75,6 +75,10 @@
 cd build && cmake ../ && make
 ```
 
+MSVC users must manually set `SNAPPY_HAVE_SSSE3`, `SNAPPY_HAVE_X86_CRC32`,
+`SNAPPY_HAVE_BMI2`, `SNAPPY_HAVE_NEON_CRC32`, and `SNAPPY_HAVE_NEON` due to
+MSVC's incorrect architecture detection, if using pre-`/arch:AVX2`.
+
 Usage
 =====
 
diff --git a/snappy-c.cc b/snappy-c.cc
index 6da18d8..fc2d5d3 100644
--- a/snappy-c.cc
+++ b/snappy-c.cc
@@ -45,6 +45,25 @@
   return SNAPPY_OK;
 }
 
+snappy_status snappy_compress_with_level(const char* input, size_t input_length,
+                                         int compression_level,
+                                         char* compressed,
+                                         size_t* compressed_length) {
+  if (*compressed_length < snappy_max_compressed_length(input_length)) {
+    return SNAPPY_BUFFER_TOO_SMALL;
+  }
+  if (compression_level < SNAPPY_MIN_COMPRESSION_LEVEL ||
+      compression_level > SNAPPY_MAX_COMPRESSION_LEVEL) {
+    return SNAPPY_INVALID_INPUT;
+  }
+  snappy::RawCompress(input, input_length, compressed, compressed_length,
+                      snappy::CompressionOptions{/*level=*/compression_level});
+  if (*compressed_length == 0) {
+    return SNAPPY_INVALID_INPUT;
+  }
+  return SNAPPY_OK;
+}
+
 snappy_status snappy_uncompress(const char* compressed,
                                 size_t compressed_length,
                                 char* uncompressed,
diff --git a/snappy-c.h b/snappy-c.h
index e228785..4dfdcdb 100644
--- a/snappy-c.h
+++ b/snappy-c.h
@@ -57,7 +57,8 @@
  * If it is not at least equal to "snappy_max_compressed_length(input_length)",
  * SNAPPY_BUFFER_TOO_SMALL is returned. After successful compression,
  * <compressed_length> contains the true length of the compressed output,
- * and SNAPPY_OK is returned.
+ * and SNAPPY_OK is returned. Compression level is 1. For using other
+ * compression levels, call snappy_compress_with_level.
  *
  * An <input_length> of 2^32 or more returns SNAPPY_INVALID_INPUT with
  * <compressed_length> set to 0 and nothing written.
@@ -71,10 +72,20 @@
  *   }
  *   free(output);
  */
-snappy_status snappy_compress(const char* input,
-                              size_t input_length,
-                              char* compressed,
-                              size_t* compressed_length);
+snappy_status snappy_compress(const char* input, size_t input_length,
+                              char* compressed, size_t* compressed_length);
+
+/*
+ * Same as above but uses compression_level which must be between
+ * SNAPPY_MIN_COMPRESSION_LEVEL and SNAPPY_MAX_COMPRESSION_LEVEL.
+ */
+#define SNAPPY_MIN_COMPRESSION_LEVEL 1
+#define SNAPPY_MAX_COMPRESSION_LEVEL 2
+
+snappy_status snappy_compress_with_level(const char* input, size_t input_length,
+                                         int compression_level,
+                                         char* compressed,
+                                         size_t* compressed_length);
 
 /*
  * Given data in "compressed[0..compressed_length-1]" generated by
diff --git a/snappy-internal.h b/snappy-internal.h
index 582e886..f88490f 100644
--- a/snappy-internal.h
+++ b/snappy-internal.h
@@ -53,14 +53,10 @@
 #define SNAPPY_HAVE_RVV 0
 #endif
 
-#ifdef SNAPPY_RVV_1
+#if SNAPPY_RVV_1 || SNAPPY_RVV_0_7
 #define VSETVL_E8M2 __riscv_vsetvl_e8m2
 #define VLE8_V_U8M2 __riscv_vle8_v_u8m2
 #define VSE8_V_U8M2 __riscv_vse8_v_u8m2
-#elif SNAPPY_RVV_0_7
-#define VSETVL_E8M2 vsetvl_e8m2
-#define VLE8_V_U8M2 vle8_v_u8m2
-#define VSE8_V_U8M2 vse8_v_u8m2
 #endif
 
 #if SNAPPY_HAVE_SSSE3 || SNAPPY_HAVE_NEON
@@ -157,7 +153,7 @@
  private:
   char* mem_;        // the allocated memory, never nullptr
   size_t size_;      // the size of the allocated memory, never 0
-  bool owns_mem_;    // whether the destructor should free mem_
+  bool owns_mem_;
   uint16_t* table_;  // the pointer to the hashtable
   char* input_;      // the pointer to the input scratch buffer
   char* output_;     // the pointer to the output scratch buffer
diff --git a/snappy.cc b/snappy.cc
index 555588a..add72f8 100644
--- a/snappy.cc
+++ b/snappy.cc
@@ -76,7 +76,6 @@
 #include <cstring>
 #include <limits>
 #include <memory>
-#include <new>
 #include <string>
 #include <utility>
 #include <vector>
@@ -2469,17 +2468,6 @@
   *compressed_length = (writer.CurrentDestination() - compressed);
 }
 
-void RawCompress(const char* input, size_t input_length, char* compressed,
-                 size_t* compressed_length, CompressionOptions options,
-                 CompressionContext* ctx) {
-  ByteArraySource reader(input, input_length);
-  UncheckedByteArraySink writer(compressed);
-  Compress(&reader, &writer, options, ctx);
-
-  // Compute how many bytes were added
-  *compressed_length = (writer.CurrentDestination() - compressed);
-}
-
 void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length,
                           char* compressed, size_t* compressed_length) {
   RawCompressFromIOVec(iov, uncompressed_length, compressed, compressed_length,
@@ -2497,6 +2485,17 @@
   *compressed_length = writer.CurrentDestination() - compressed;
 }
 
+void RawCompress(const char* input, size_t input_length, char* compressed,
+                 size_t* compressed_length, CompressionOptions options,
+                 CompressionContext* ctx) {
+  ByteArraySource reader(input, input_length);
+  UncheckedByteArraySink writer(compressed);
+  Compress(&reader, &writer, options, ctx);
+
+  // Compute how many bytes were added
+  *compressed_length = (writer.CurrentDestination() - compressed);
+}
+
 size_t Compress(const char* input, size_t input_length,
                 std::string* compressed) {
   return Compress(input, input_length, compressed, CompressionOptions{});
diff --git a/snappy.h b/snappy.h
index 9f05ca4..1c44868 100644
--- a/snappy.h
+++ b/snappy.h
@@ -50,9 +50,9 @@
   class Source;
   class Sink;
 
-  namespace internal {
-  class WorkingMemory;
-  }  // end namespace internal
+namespace internal {
+class WorkingMemory;
+}  // end namespace internal
 
   struct CompressionOptions {
     // Compression level.
@@ -212,6 +212,8 @@
   // "*compressed_length" is set to the length of the compressed output, or to
   // zero, with nothing written, if "input_length" is 2^32 or more.
   //
+  // "*compressed_length" is set to the length of the compressed output.
+  //
   // Example:
   //    char* output = new char[snappy::MaxCompressedLength(input_length)];
   //    size_t output_length;
@@ -223,7 +225,6 @@
                    size_t* compressed_length);
   void RawCompress(const char* input, size_t input_length, char* compressed,
                    size_t* compressed_length, CompressionOptions options);
-
   // Same as the above, but uses the working memory of "*ctx" instead of
   // allocating it internally. See CompressionContext.
   void RawCompress(const char* input, size_t input_length, char* compressed,
diff --git a/snappy_unittest.cc b/snappy_unittest.cc
index bbce75b..57d617b 100644
--- a/snappy_unittest.cc
+++ b/snappy_unittest.cc
@@ -28,6 +28,7 @@
 
 #include <algorithm>
 #include <cinttypes>
+#include <cstdint>
 #include <cmath>
 #include <cstdlib>
 #include <random>