648db22b |
1 | /* |
2 | * Copyright (c) Meta Platforms, Inc. and affiliates. |
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 | |
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 | |
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 | } |