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