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
100
101
102
103
104
105
106
|
/*
Mod Organizer archive handling
Copyright (C) 2012 Sebastian Herbord, 2020 MO2 Team. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MULTIOUTPUTSTREAM_H
#define MULTIOUTPUTSTREAM_H
#include <filesystem>
#include <functional>
#include <memory>
#include <vector>
#include <7zip/IStream.h>
#include "fileio.h"
#include "unknown_impl.h"
/** This class allows you to open and output to multiple file handles at a time.
* It implements the ISequentalOutputStream interface and has some extra functions
* which are used by the CArchiveExtractCallback class to basically open and
* set the timestamp on all the files.
*
* Note that the handling on errors could be better.
*/
class MultiOutputStream : public IOutStream
{
UNKNOWN_1_INTERFACE(IOutStream);
public:
// Callback for write. Args are: 1) number of bytes that have been
// written for this call, 2) number of bytes that have been written
// in total.
using WriteCallback = std::function<void(UInt32, UInt64)>;
MultiOutputStream(WriteCallback callback = {});
virtual ~MultiOutputStream();
/** Opens the supplied files.
*
* @returns true if all went OK, false if any file failed to open
*/
bool Open(std::vector<std::filesystem::path> const& fileNames);
/** Closes all the files opened by the last open
*
* Note if there are any errors, the code will merely report the last one.
*/
HRESULT Close();
/** Sets the modification time on the open files
*
* @returns true if all files had the time set succesfully, false otherwise
* note that this will give up as soon as it gets an error
*/
bool SetMTime(FILETIME const* mTime);
// ISequentialOutStream interface
/** Write data to all the streams
*
* The processedSize returned will be the same as size, unless
* there was an error, in which case it might or might not be different.
* @warn If an error happens, the code will not attempt any further writing,
* so some files might not get written to at all
*/
STDMETHOD(Write)(const void* data, UInt32 size, UInt32* processedSize) throw() override;
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64* newPosition) throw() override;
STDMETHOD(SetSize)(UInt64 newSize) throw() override;
HRESULT GetSize(UInt64* size);
private:
WriteCallback m_WriteCallback;
/** This is the amount of data written to *any one* file.
*
* If there are errors writing to one of the files, this might or might
* not match what was actually written to another of the files
*/
UInt64 m_ProcessedSize;
/** All the files opened for this 'stream'
*
*/
std::vector<IO::FileOut> m_Files;
};
#endif // MULTIOUTPUTSTREAM_H
|