snappy 0.0.13 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +28 -1
  3. data/Gemfile +6 -1
  4. data/README.md +28 -4
  5. data/Rakefile +1 -0
  6. data/ext/extconf.rb +21 -24
  7. data/lib/snappy.rb +3 -1
  8. data/lib/snappy/hadoop.rb +22 -0
  9. data/lib/snappy/hadoop/reader.rb +58 -0
  10. data/lib/snappy/hadoop/writer.rb +51 -0
  11. data/lib/snappy/reader.rb +11 -7
  12. data/lib/snappy/shim.rb +30 -0
  13. data/lib/snappy/version.rb +3 -1
  14. data/lib/snappy/writer.rb +8 -9
  15. data/smoke.sh +8 -0
  16. data/snappy.gemspec +6 -30
  17. data/test/hadoop/test-snappy-hadoop-reader.rb +103 -0
  18. data/test/hadoop/test-snappy-hadoop-writer.rb +48 -0
  19. data/test/test-snappy-hadoop.rb +22 -0
  20. data/vendor/snappy/AUTHORS +1 -0
  21. data/vendor/snappy/CMakeLists.txt +174 -0
  22. data/vendor/snappy/CONTRIBUTING.md +26 -0
  23. data/vendor/snappy/COPYING +54 -0
  24. data/vendor/snappy/NEWS +180 -0
  25. data/vendor/snappy/README.md +149 -0
  26. data/vendor/snappy/cmake/SnappyConfig.cmake +1 -0
  27. data/vendor/snappy/cmake/config.h.in +62 -0
  28. data/vendor/snappy/format_description.txt +110 -0
  29. data/vendor/snappy/framing_format.txt +135 -0
  30. data/vendor/snappy/snappy-c.cc +90 -0
  31. data/vendor/snappy/snappy-c.h +138 -0
  32. data/vendor/snappy/snappy-internal.h +224 -0
  33. data/vendor/snappy/snappy-sinksource.cc +104 -0
  34. data/vendor/snappy/snappy-sinksource.h +182 -0
  35. data/vendor/snappy/snappy-stubs-internal.cc +42 -0
  36. data/vendor/snappy/snappy-stubs-internal.h +561 -0
  37. data/vendor/snappy/snappy-stubs-public.h.in +94 -0
  38. data/vendor/snappy/snappy-test.cc +612 -0
  39. data/vendor/snappy/snappy-test.h +573 -0
  40. data/vendor/snappy/snappy.cc +1515 -0
  41. data/vendor/snappy/snappy.h +203 -0
  42. data/vendor/snappy/snappy_unittest.cc +1410 -0
  43. metadata +38 -46
@@ -0,0 +1,573 @@
1
+ // Copyright 2011 Google Inc. All Rights Reserved.
2
+ //
3
+ // Redistribution and use in source and binary forms, with or without
4
+ // modification, are permitted provided that the following conditions are
5
+ // met:
6
+ //
7
+ // * Redistributions of source code must retain the above copyright
8
+ // notice, this list of conditions and the following disclaimer.
9
+ // * Redistributions in binary form must reproduce the above
10
+ // copyright notice, this list of conditions and the following disclaimer
11
+ // in the documentation and/or other materials provided with the
12
+ // distribution.
13
+ // * Neither the name of Google Inc. nor the names of its
14
+ // contributors may be used to endorse or promote products derived from
15
+ // this software without specific prior written permission.
16
+ //
17
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ //
29
+ // Various stubs for the unit tests for the open-source version of Snappy.
30
+
31
+ #ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_
32
+ #define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_
33
+
34
+ #include <iostream>
35
+ #include <string>
36
+
37
+ #include "snappy-stubs-internal.h"
38
+
39
+ #include <stdio.h>
40
+ #include <stdarg.h>
41
+
42
+ #ifdef HAVE_SYS_MMAN_H
43
+ #include <sys/mman.h>
44
+ #endif
45
+
46
+ #ifdef HAVE_SYS_RESOURCE_H
47
+ #include <sys/resource.h>
48
+ #endif
49
+
50
+ #ifdef HAVE_SYS_TIME_H
51
+ #include <sys/time.h>
52
+ #endif
53
+
54
+ #ifdef HAVE_WINDOWS_H
55
+ #include <windows.h>
56
+ #endif
57
+
58
+ #include <string>
59
+
60
+ #ifdef HAVE_GTEST
61
+
62
+ #include <gtest/gtest.h>
63
+ #undef TYPED_TEST
64
+ #define TYPED_TEST TEST
65
+ #define INIT_GTEST(argc, argv) ::testing::InitGoogleTest(argc, *argv)
66
+
67
+ #else
68
+
69
+ // Stubs for if the user doesn't have Google Test installed.
70
+
71
+ #define TEST(test_case, test_subcase) \
72
+ void Test_ ## test_case ## _ ## test_subcase()
73
+ #define INIT_GTEST(argc, argv)
74
+
75
+ #define TYPED_TEST TEST
76
+ #define EXPECT_EQ CHECK_EQ
77
+ #define EXPECT_NE CHECK_NE
78
+ #define EXPECT_FALSE(cond) CHECK(!(cond))
79
+
80
+ #endif
81
+
82
+ #ifdef HAVE_GFLAGS
83
+
84
+ #include <gflags/gflags.h>
85
+
86
+ // This is tricky; both gflags and Google Test want to look at the command line
87
+ // arguments. Google Test seems to be the most happy with unknown arguments,
88
+ // though, so we call it first and hope for the best.
89
+ #define InitGoogle(argv0, argc, argv, remove_flags) \
90
+ INIT_GTEST(argc, argv); \
91
+ google::ParseCommandLineFlags(argc, argv, remove_flags);
92
+
93
+ #else
94
+
95
+ // If we don't have the gflags package installed, these can only be
96
+ // changed at compile time.
97
+ #define DEFINE_int32(flag_name, default_value, description) \
98
+ static int FLAGS_ ## flag_name = default_value;
99
+
100
+ #define InitGoogle(argv0, argc, argv, remove_flags) \
101
+ INIT_GTEST(argc, argv)
102
+
103
+ #endif
104
+
105
+ #ifdef HAVE_LIBZ
106
+ #include "zlib.h"
107
+ #endif
108
+
109
+ #ifdef HAVE_LIBLZO2
110
+ #include "lzo/lzo1x.h"
111
+ #endif
112
+
113
+ namespace {
114
+
115
+ namespace file {
116
+ int Defaults() { return 0; }
117
+
118
+ class DummyStatus {
119
+ public:
120
+ void CheckSuccess() { }
121
+ };
122
+
123
+ DummyStatus GetContents(
124
+ const std::string& filename, std::string* data, int unused) {
125
+ FILE* fp = fopen(filename.c_str(), "rb");
126
+ if (fp == NULL) {
127
+ perror(filename.c_str());
128
+ exit(1);
129
+ }
130
+
131
+ data->clear();
132
+ while (!feof(fp)) {
133
+ char buf[4096];
134
+ size_t ret = fread(buf, 1, 4096, fp);
135
+ if (ret == 0 && ferror(fp)) {
136
+ perror("fread");
137
+ exit(1);
138
+ }
139
+ data->append(std::string(buf, ret));
140
+ }
141
+
142
+ fclose(fp);
143
+
144
+ return DummyStatus();
145
+ }
146
+
147
+ inline DummyStatus SetContents(
148
+ const std::string& filename, const std::string& str, int unused) {
149
+ FILE* fp = fopen(filename.c_str(), "wb");
150
+ if (fp == NULL) {
151
+ perror(filename.c_str());
152
+ exit(1);
153
+ }
154
+
155
+ int ret = fwrite(str.data(), str.size(), 1, fp);
156
+ if (ret != 1) {
157
+ perror("fwrite");
158
+ exit(1);
159
+ }
160
+
161
+ fclose(fp);
162
+
163
+ return DummyStatus();
164
+ }
165
+ } // namespace file
166
+
167
+ } // namespace
168
+
169
+ namespace snappy {
170
+
171
+ #define FLAGS_test_random_seed 301
172
+ typedef string TypeParam;
173
+
174
+ void Test_CorruptedTest_VerifyCorrupted();
175
+ void Test_Snappy_SimpleTests();
176
+ void Test_Snappy_MaxBlowup();
177
+ void Test_Snappy_RandomData();
178
+ void Test_Snappy_FourByteOffset();
179
+ void Test_SnappyCorruption_TruncatedVarint();
180
+ void Test_SnappyCorruption_UnterminatedVarint();
181
+ void Test_SnappyCorruption_OverflowingVarint();
182
+ void Test_Snappy_ReadPastEndOfBuffer();
183
+ void Test_Snappy_FindMatchLength();
184
+ void Test_Snappy_FindMatchLengthRandom();
185
+
186
+ string ReadTestDataFile(const string& base, size_t size_limit);
187
+
188
+ string ReadTestDataFile(const string& base);
189
+
190
+ // A sprintf() variant that returns a std::string.
191
+ // Not safe for general use due to truncation issues.
192
+ string StringPrintf(const char* format, ...);
193
+
194
+ // A simple, non-cryptographically-secure random generator.
195
+ class ACMRandom {
196
+ public:
197
+ explicit ACMRandom(uint32 seed) : seed_(seed) {}
198
+
199
+ int32 Next();
200
+
201
+ int32 Uniform(int32 n) {
202
+ return Next() % n;
203
+ }
204
+ uint8 Rand8() {
205
+ return static_cast<uint8>((Next() >> 1) & 0x000000ff);
206
+ }
207
+ bool OneIn(int X) { return Uniform(X) == 0; }
208
+
209
+ // Skewed: pick "base" uniformly from range [0,max_log] and then
210
+ // return "base" random bits. The effect is to pick a number in the
211
+ // range [0,2^max_log-1] with bias towards smaller numbers.
212
+ int32 Skewed(int max_log);
213
+
214
+ private:
215
+ static const uint32 M = 2147483647L; // 2^31-1
216
+ uint32 seed_;
217
+ };
218
+
219
+ inline int32 ACMRandom::Next() {
220
+ static const uint64 A = 16807; // bits 14, 8, 7, 5, 2, 1, 0
221
+ // We are computing
222
+ // seed_ = (seed_ * A) % M, where M = 2^31-1
223
+ //
224
+ // seed_ must not be zero or M, or else all subsequent computed values
225
+ // will be zero or M respectively. For all other values, seed_ will end
226
+ // up cycling through every number in [1,M-1]
227
+ uint64 product = seed_ * A;
228
+
229
+ // Compute (product % M) using the fact that ((x << 31) % M) == x.
230
+ seed_ = (product >> 31) + (product & M);
231
+ // The first reduction may overflow by 1 bit, so we may need to repeat.
232
+ // mod == M is not possible; using > allows the faster sign-bit-based test.
233
+ if (seed_ > M) {
234
+ seed_ -= M;
235
+ }
236
+ return seed_;
237
+ }
238
+
239
+ inline int32 ACMRandom::Skewed(int max_log) {
240
+ const int32 base = (Next() - 1) % (max_log+1);
241
+ return (Next() - 1) & ((1u << base)-1);
242
+ }
243
+
244
+ // A wall-time clock. This stub is not super-accurate, nor resistant to the
245
+ // system time changing.
246
+ class CycleTimer {
247
+ public:
248
+ CycleTimer() : real_time_us_(0) {}
249
+
250
+ void Start() {
251
+ #ifdef WIN32
252
+ QueryPerformanceCounter(&start_);
253
+ #else
254
+ gettimeofday(&start_, NULL);
255
+ #endif
256
+ }
257
+
258
+ void Stop() {
259
+ #ifdef WIN32
260
+ LARGE_INTEGER stop;
261
+ LARGE_INTEGER frequency;
262
+ QueryPerformanceCounter(&stop);
263
+ QueryPerformanceFrequency(&frequency);
264
+
265
+ double elapsed = static_cast<double>(stop.QuadPart - start_.QuadPart) /
266
+ frequency.QuadPart;
267
+ real_time_us_ += elapsed * 1e6 + 0.5;
268
+ #else
269
+ struct timeval stop;
270
+ gettimeofday(&stop, NULL);
271
+
272
+ real_time_us_ += 1000000 * (stop.tv_sec - start_.tv_sec);
273
+ real_time_us_ += (stop.tv_usec - start_.tv_usec);
274
+ #endif
275
+ }
276
+
277
+ double Get() {
278
+ return real_time_us_ * 1e-6;
279
+ }
280
+
281
+ private:
282
+ int64 real_time_us_;
283
+ #ifdef WIN32
284
+ LARGE_INTEGER start_;
285
+ #else
286
+ struct timeval start_;
287
+ #endif
288
+ };
289
+
290
+ // Minimalistic microbenchmark framework.
291
+
292
+ typedef void (*BenchmarkFunction)(int, int);
293
+
294
+ class Benchmark {
295
+ public:
296
+ Benchmark(const string& name, BenchmarkFunction function) :
297
+ name_(name), function_(function) {}
298
+
299
+ Benchmark* DenseRange(int start, int stop) {
300
+ start_ = start;
301
+ stop_ = stop;
302
+ return this;
303
+ }
304
+
305
+ void Run();
306
+
307
+ private:
308
+ const string name_;
309
+ const BenchmarkFunction function_;
310
+ int start_, stop_;
311
+ };
312
+ #define BENCHMARK(benchmark_name) \
313
+ Benchmark* Benchmark_ ## benchmark_name = \
314
+ (new Benchmark(#benchmark_name, benchmark_name))
315
+
316
+ extern Benchmark* Benchmark_BM_UFlat;
317
+ extern Benchmark* Benchmark_BM_UIOVec;
318
+ extern Benchmark* Benchmark_BM_UValidate;
319
+ extern Benchmark* Benchmark_BM_ZFlat;
320
+
321
+ void ResetBenchmarkTiming();
322
+ void StartBenchmarkTiming();
323
+ void StopBenchmarkTiming();
324
+ void SetBenchmarkLabel(const string& str);
325
+ void SetBenchmarkBytesProcessed(int64 bytes);
326
+
327
+ #ifdef HAVE_LIBZ
328
+
329
+ // Object-oriented wrapper around zlib.
330
+ class ZLib {
331
+ public:
332
+ ZLib();
333
+ ~ZLib();
334
+
335
+ // Wipe a ZLib object to a virgin state. This differs from Reset()
336
+ // in that it also breaks any state.
337
+ void Reinit();
338
+
339
+ // Call this to make a zlib buffer as good as new. Here's the only
340
+ // case where they differ:
341
+ // CompressChunk(a); CompressChunk(b); CompressChunkDone(); vs
342
+ // CompressChunk(a); Reset(); CompressChunk(b); CompressChunkDone();
343
+ // You'll want to use Reset(), then, when you interrupt a compress
344
+ // (or uncompress) in the middle of a chunk and want to start over.
345
+ void Reset();
346
+
347
+ // According to the zlib manual, when you Compress, the destination
348
+ // buffer must have size at least src + .1%*src + 12. This function
349
+ // helps you calculate that. Augment this to account for a potential
350
+ // gzip header and footer, plus a few bytes of slack.
351
+ static int MinCompressbufSize(int uncompress_size) {
352
+ return uncompress_size + uncompress_size/1000 + 40;
353
+ }
354
+
355
+ // Compresses the source buffer into the destination buffer.
356
+ // sourceLen is the byte length of the source buffer.
357
+ // Upon entry, destLen is the total size of the destination buffer,
358
+ // which must be of size at least MinCompressbufSize(sourceLen).
359
+ // Upon exit, destLen is the actual size of the compressed buffer.
360
+ //
361
+ // This function can be used to compress a whole file at once if the
362
+ // input file is mmap'ed.
363
+ //
364
+ // Returns Z_OK if success, Z_MEM_ERROR if there was not
365
+ // enough memory, Z_BUF_ERROR if there was not enough room in the
366
+ // output buffer. Note that if the output buffer is exactly the same
367
+ // size as the compressed result, we still return Z_BUF_ERROR.
368
+ // (check CL#1936076)
369
+ int Compress(Bytef *dest, uLongf *destLen,
370
+ const Bytef *source, uLong sourceLen);
371
+
372
+ // Uncompresses the source buffer into the destination buffer.
373
+ // The destination buffer must be long enough to hold the entire
374
+ // decompressed contents.
375
+ //
376
+ // Returns Z_OK on success, otherwise, it returns a zlib error code.
377
+ int Uncompress(Bytef *dest, uLongf *destLen,
378
+ const Bytef *source, uLong sourceLen);
379
+
380
+ // Uncompress data one chunk at a time -- ie you can call this
381
+ // more than once. To get this to work you need to call per-chunk
382
+ // and "done" routines.
383
+ //
384
+ // Returns Z_OK if success, Z_MEM_ERROR if there was not
385
+ // enough memory, Z_BUF_ERROR if there was not enough room in the
386
+ // output buffer.
387
+
388
+ int UncompressAtMost(Bytef *dest, uLongf *destLen,
389
+ const Bytef *source, uLong *sourceLen);
390
+
391
+ // Checks gzip footer information, as needed. Mostly this just
392
+ // makes sure the checksums match. Whenever you call this, it
393
+ // will assume the last 8 bytes from the previous UncompressChunk
394
+ // call are the footer. Returns true iff everything looks ok.
395
+ bool UncompressChunkDone();
396
+
397
+ private:
398
+ int InflateInit(); // sets up the zlib inflate structure
399
+ int DeflateInit(); // sets up the zlib deflate structure
400
+
401
+ // These init the zlib data structures for compressing/uncompressing
402
+ int CompressInit(Bytef *dest, uLongf *destLen,
403
+ const Bytef *source, uLong *sourceLen);
404
+ int UncompressInit(Bytef *dest, uLongf *destLen,
405
+ const Bytef *source, uLong *sourceLen);
406
+ // Initialization method to be called if we hit an error while
407
+ // uncompressing. On hitting an error, call this method before
408
+ // returning the error.
409
+ void UncompressErrorInit();
410
+
411
+ // Helper function for Compress
412
+ int CompressChunkOrAll(Bytef *dest, uLongf *destLen,
413
+ const Bytef *source, uLong sourceLen,
414
+ int flush_mode);
415
+ int CompressAtMostOrAll(Bytef *dest, uLongf *destLen,
416
+ const Bytef *source, uLong *sourceLen,
417
+ int flush_mode);
418
+
419
+ // Likewise for UncompressAndUncompressChunk
420
+ int UncompressChunkOrAll(Bytef *dest, uLongf *destLen,
421
+ const Bytef *source, uLong sourceLen,
422
+ int flush_mode);
423
+
424
+ int UncompressAtMostOrAll(Bytef *dest, uLongf *destLen,
425
+ const Bytef *source, uLong *sourceLen,
426
+ int flush_mode);
427
+
428
+ // Initialization method to be called if we hit an error while
429
+ // compressing. On hitting an error, call this method before
430
+ // returning the error.
431
+ void CompressErrorInit();
432
+
433
+ int compression_level_; // compression level
434
+ int window_bits_; // log base 2 of the window size used in compression
435
+ int mem_level_; // specifies the amount of memory to be used by
436
+ // compressor (1-9)
437
+ z_stream comp_stream_; // Zlib stream data structure
438
+ bool comp_init_; // True if we have initialized comp_stream_
439
+ z_stream uncomp_stream_; // Zlib stream data structure
440
+ bool uncomp_init_; // True if we have initialized uncomp_stream_
441
+
442
+ // These are used only with chunked compression.
443
+ bool first_chunk_; // true if we need to emit headers with this chunk
444
+ };
445
+
446
+ #endif // HAVE_LIBZ
447
+
448
+ } // namespace snappy
449
+
450
+ DECLARE_bool(run_microbenchmarks);
451
+
452
+ static inline void RunSpecifiedBenchmarks() {
453
+ if (!FLAGS_run_microbenchmarks) {
454
+ return;
455
+ }
456
+
457
+ fprintf(stderr, "Running microbenchmarks.\n");
458
+ #ifndef NDEBUG
459
+ fprintf(stderr, "WARNING: Compiled with assertions enabled, will be slow.\n");
460
+ #endif
461
+ #ifndef __OPTIMIZE__
462
+ fprintf(stderr, "WARNING: Compiled without optimization, will be slow.\n");
463
+ #endif
464
+ fprintf(stderr, "Benchmark Time(ns) CPU(ns) Iterations\n");
465
+ fprintf(stderr, "---------------------------------------------------\n");
466
+
467
+ snappy::Benchmark_BM_UFlat->Run();
468
+ snappy::Benchmark_BM_UIOVec->Run();
469
+ snappy::Benchmark_BM_UValidate->Run();
470
+ snappy::Benchmark_BM_ZFlat->Run();
471
+
472
+ fprintf(stderr, "\n");
473
+ }
474
+
475
+ #ifndef HAVE_GTEST
476
+
477
+ static inline int RUN_ALL_TESTS() {
478
+ fprintf(stderr, "Running correctness tests.\n");
479
+ snappy::Test_CorruptedTest_VerifyCorrupted();
480
+ snappy::Test_Snappy_SimpleTests();
481
+ snappy::Test_Snappy_MaxBlowup();
482
+ snappy::Test_Snappy_RandomData();
483
+ snappy::Test_Snappy_FourByteOffset();
484
+ snappy::Test_SnappyCorruption_TruncatedVarint();
485
+ snappy::Test_SnappyCorruption_UnterminatedVarint();
486
+ snappy::Test_SnappyCorruption_OverflowingVarint();
487
+ snappy::Test_Snappy_ReadPastEndOfBuffer();
488
+ snappy::Test_Snappy_FindMatchLength();
489
+ snappy::Test_Snappy_FindMatchLengthRandom();
490
+ fprintf(stderr, "All tests passed.\n");
491
+
492
+ return 0;
493
+ }
494
+
495
+ #endif // HAVE_GTEST
496
+
497
+ // For main().
498
+ namespace snappy {
499
+
500
+ // Logging.
501
+
502
+ #define LOG(level) LogMessage()
503
+ #define VLOG(level) true ? (void)0 : \
504
+ snappy::LogMessageVoidify() & snappy::LogMessage()
505
+
506
+ class LogMessage {
507
+ public:
508
+ LogMessage() { }
509
+ ~LogMessage() {
510
+ std::cerr << std::endl;
511
+ }
512
+
513
+ LogMessage& operator<<(const std::string& msg) {
514
+ std::cerr << msg;
515
+ return *this;
516
+ }
517
+ LogMessage& operator<<(int x) {
518
+ std::cerr << x;
519
+ return *this;
520
+ }
521
+ };
522
+
523
+ // Asserts, both versions activated in debug mode only,
524
+ // and ones that are always active.
525
+
526
+ #define CRASH_UNLESS(condition) \
527
+ SNAPPY_PREDICT_TRUE(condition) ? (void)0 : \
528
+ snappy::LogMessageVoidify() & snappy::LogMessageCrash()
529
+
530
+ #ifdef _MSC_VER
531
+ // ~LogMessageCrash calls abort() and therefore never exits. This is by design
532
+ // so temporarily disable warning C4722.
533
+ #pragma warning(push)
534
+ #pragma warning(disable:4722)
535
+ #endif
536
+
537
+ class LogMessageCrash : public LogMessage {
538
+ public:
539
+ LogMessageCrash() { }
540
+ ~LogMessageCrash() {
541
+ std::cerr << std::endl;
542
+ abort();
543
+ }
544
+ };
545
+
546
+ #ifdef _MSC_VER
547
+ #pragma warning(pop)
548
+ #endif
549
+
550
+ // This class is used to explicitly ignore values in the conditional
551
+ // logging macros. This avoids compiler warnings like "value computed
552
+ // is not used" and "statement has no effect".
553
+
554
+ class LogMessageVoidify {
555
+ public:
556
+ LogMessageVoidify() { }
557
+ // This has to be an operator with a precedence lower than << but
558
+ // higher than ?:
559
+ void operator&(const LogMessage&) { }
560
+ };
561
+
562
+ #define CHECK(cond) CRASH_UNLESS(cond)
563
+ #define CHECK_LE(a, b) CRASH_UNLESS((a) <= (b))
564
+ #define CHECK_GE(a, b) CRASH_UNLESS((a) >= (b))
565
+ #define CHECK_EQ(a, b) CRASH_UNLESS((a) == (b))
566
+ #define CHECK_NE(a, b) CRASH_UNLESS((a) != (b))
567
+ #define CHECK_LT(a, b) CRASH_UNLESS((a) < (b))
568
+ #define CHECK_GT(a, b) CRASH_UNLESS((a) > (b))
569
+ #define CHECK_OK(cond) (cond).CheckSuccess()
570
+
571
+ } // namespace snappy
572
+
573
+ #endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_