1 /*
2  * Copyright (c) 2016-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under both the BSD-style license (found in the
6  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7  * in the COPYING file in the root directory of this source tree).
8  */
9 #pragma once
10 
11 #include "Options.h"
12 #include "Pzstd.h"
13 #include "utils/ScopeGuard.h"
14 
15 #include <cstdio>
16 #include <string>
17 #include <cstdint>
18 #include <memory>
19 
20 namespace pzstd {
21 
check(std::string source,std::string decompressed)22 inline bool check(std::string source, std::string decompressed) {
23   std::unique_ptr<std::uint8_t[]> sBuf(new std::uint8_t[1024]);
24   std::unique_ptr<std::uint8_t[]> dBuf(new std::uint8_t[1024]);
25 
26   auto sFd = std::fopen(source.c_str(), "rb");
27   auto dFd = std::fopen(decompressed.c_str(), "rb");
28   auto guard = makeScopeGuard([&] {
29     std::fclose(sFd);
30     std::fclose(dFd);
31   });
32 
33   size_t sRead, dRead;
34 
35   do {
36     sRead = std::fread(sBuf.get(), 1, 1024, sFd);
37     dRead = std::fread(dBuf.get(), 1, 1024, dFd);
38     if (std::ferror(sFd) || std::ferror(dFd)) {
39       return false;
40     }
41     if (sRead != dRead) {
42       return false;
43     }
44 
45     for (size_t i = 0; i < sRead; ++i) {
46       if (sBuf.get()[i] != dBuf.get()[i]) {
47         return false;
48       }
49     }
50   } while (sRead == 1024);
51   if (!std::feof(sFd) || !std::feof(dFd)) {
52     return false;
53   }
54   return true;
55 }
56 
roundTrip(Options & options)57 inline bool roundTrip(Options& options) {
58   if (options.inputFiles.size() != 1) {
59     return false;
60   }
61   std::string source = options.inputFiles.front();
62   std::string compressedFile = std::tmpnam(nullptr);
63   std::string decompressedFile = std::tmpnam(nullptr);
64   auto guard = makeScopeGuard([&] {
65     std::remove(compressedFile.c_str());
66     std::remove(decompressedFile.c_str());
67   });
68 
69   {
70     options.outputFile = compressedFile;
71     options.decompress = false;
72     if (pzstdMain(options) != 0) {
73       return false;
74     }
75   }
76   {
77     options.decompress = true;
78     options.inputFiles.front() = compressedFile;
79     options.outputFile = decompressedFile;
80     if (pzstdMain(options) != 0) {
81       return false;
82     }
83   }
84   return check(source, decompressedFile);
85 }
86 }
87