1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#include "factory.h"
#include <library/cpp/streams/bzip2/bzip2.h>
#include <library/cpp/streams/factory/open_common/factory.h>
#include <util/stream/holder.h>
#include <util/stream/file.h>
#include <library/cpp/streams/lz/lz.h>
#include <util/stream/str.h>
#include <util/stream/zlib.h>
#include <util/stream/multi.h>
#include <util/generic/ptr.h>
#include <util/generic/string.h>
namespace {
template <class T>
struct TInputHolderX: public T {
inline decltype(T().Get()) Set(T t) noexcept {
t.Swap(*this);
return this->Get();
}
};
template <class T>
struct TInputHolderX<T*> {
static inline T* Set(T* t) noexcept {
return t;
}
};
template <class TInput>
struct TStringMultiInput: private TInputHolderX<TInput>, private TString, private THolder<IInputStream>, public TMultiInput {
TStringMultiInput(const TString& head, TInput tail)
: TString(head)
, THolder<IInputStream>(new TStringInput(*this))
, TMultiInput(THolder<IInputStream>::Get(), this->Set(tail))
{
}
~TStringMultiInput() override {
}
};
}
template <class TInput>
THolder<IInputStream> OpenMaybeCompressedInputX(TInput input) {
const size_t MAX_SIGNATURE_SIZE = 4;
char buffer[MAX_SIGNATURE_SIZE];
TString header(buffer, input->Load(buffer, MAX_SIGNATURE_SIZE));
if (header.size() == MAX_SIGNATURE_SIZE) {
// any lz
THolder<IInputStream> lz = TryOpenOwnedLzDecompressor(new TStringMultiInput<TInput>(header, input));
if (lz.Get()) {
return lz;
}
}
THolder<IInputStream> multi(new TStringMultiInput<TInput>(header, input));
// gzip
const TStringBuf GZIP = "\x1F\x8B";
const TStringBuf ZLIB = "\x78\x9C";
if (header.StartsWith(GZIP) || header.StartsWith(ZLIB)) {
return MakeHolder<THoldingStream<TBufferedZLibDecompress>>(std::move(multi));
}
// bzip2
constexpr TStringBuf BZIP2 = "BZ";
if (header.StartsWith(BZIP2)) {
return MakeHolder<THoldingStream<TBZipDecompress>>(std::move(multi));
}
return multi;
}
THolder<IInputStream> OpenMaybeCompressedInput(IInputStream* input) {
return OpenMaybeCompressedInputX(input);
}
THolder<IInputStream> OpenOwnedMaybeCompressedInput(THolder<IInputStream> input) {
return OpenMaybeCompressedInputX(TAtomicSharedPtr<IInputStream>(input));
}
THolder<IInputStream> OpenMaybeCompressedInput(const TString& path) {
if (!path || path == TStringBuf("-")) {
return OpenOwnedMaybeCompressedInput(OpenStdin());
}
return OpenOwnedMaybeCompressedInput(MakeHolder<TFileInput>(path));
}
THolder<IInputStream> OpenMaybeCompressedInput(const TString& path, ui32 bufSize) {
if (!path || path == TStringBuf("-")) {
return OpenOwnedMaybeCompressedInput(OpenStdin(bufSize));
}
return OpenOwnedMaybeCompressedInput(MakeHolder<TFileInput>(path, bufSize));
}
|