"Fossies" - the Fresh Open Source Software Archive 
Member "muscle/zlib/TarFileWriter.h" (21 Nov 2020, 7048 Bytes) of package /linux/privat/muscle7.62.zip:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "TarFileWriter.h" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
7.61_vs_7.62.
1 /* This file is Copyright 2000-2013 Meyer Sound Laboratories Inc. See the included LICENSE.txt file for details. */
2
3 #ifndef TarFileUtilityFunctions_h
4 #define TarFileUtilityFunctions_h
5
6 #include "support/NotCopyable.h"
7 #include "dataio/SeekableDataIO.h"
8
9 namespace muscle {
10
11 /** These TarFileWriter class writes .tar files in a cross-platform-compatible manner.
12 * (I use this code instead of libtar because libtar doesn't work under Windows,
13 * and it doesn't support streaming data into a tar file easily). Currently
14 * only the writing of a .tar file is supported; at some point I may add
15 * support for reading .tar files as well.
16 */
17 class TarFileWriter : public NotCopyable
18 {
19 public:
20 /** Default constructor. */
21 TarFileWriter();
22
23 /** Constructor.
24 * @param outputFileName Name/path of the .tar file to write to
25 * @param append If true, written data will be appended to this file; otherwise
26 * if the file already exists it will be deleted and replaced.
27 * This constructor is equivalent to the default constructor, plus calling SetFile().
28 */
29 TarFileWriter(const char * outputFileName, bool append);
30
31 /** Constructor.
32 * @param dio Reference to a DataIO object to use to write out the .tar file data.
33 * This constructor is equivalent to the default constructor, plus calling SetFile().
34 */
35 TarFileWriter(const DataIORef & dio);
36
37 /** Destructor. */
38 ~TarFileWriter();
39
40 /** Writes any pending updates to the .tar file (if necessary), then closes the file (if one is open)
41 * and returns this object to its basic just-default-constructed state.
42 * @returns B_NO_ERROR on success, or an error code if there was an error writing out pending header-data changes.
43 * Note that this method will always unreference any held DataIO and reset our state to default, even if it returns an error-code.
44 */
45 status_t Close();
46
47 /** Unreferences the currently held DataIO (if any) and attempts to open the new .tar file for writing.
48 * @param outputFileName Name/path of the .tar file to write to
49 * @param append If true, new written data will be appended to the existing file; otherwise
50 * if the file already exists it will be deleted and replaced.
51 */
52 status_t SetFile(const char * outputFileName, bool append);
53
54 /** Unreferences the currently held DataIO (if any) and uses the specified DataIO instead.
55 * @param dioRef Reference to The DataIORef to use to output .tar data to, or a NULL Ref to close only.
56 * @note if (dioRef) isn't referencing a SeekableDataIORef, then you are required to pass a valid/correct file-size
57 * arguments to WriteFileHeader(). If (dioRef) is referencing a SeekableDataIORef, then the file-size argument
58 * can optionally passed in as 0, and the TarFileWriter will update the header-fields automatically based on how
59 * much file-data was actually written.
60 */
61 void SetFile(const DataIORef & dioRef);
62
63 /** Writes a .tar header fle-block with the given information.
64 * @param fileName The name of the member file as it should be recorded inside the .tar file.
65 * @param fileMode The file-mode bits that should be stored with this file.
66 * @param ownerID The file's owner's numeric user ID
67 * @param groupID The file's group's numeric user ID
68 * @param modificationTime A timestamp indicating the file's last modification time (microseconds since 1970)
69 * @param linkIndicator one of the TAR_LINK_INDICATOR_* values
70 * @param linkedFileName Name of the linked file (if any);
71 * @param fileSize if you know the size of the file in advance, you can pass in the file-size (in bytes) in this argument.
72 * Note that if the DataIORef object the TarFileWriter isn't a SeekableDataIORef, then passing in the
73 * correct file size here is mandatory, as the TarFileWriter will be unable to seek back and patch up
74 * the file-size header field later. OTOH if you are using a SeekableDataIORef and don't know the file-size
75 * up-front, you can just pass in zero here.
76 * @returns B_NO_ERROR on success, or an error code on failure.
77 */
78 status_t WriteFileHeader(const char * fileName, uint32 fileMode, uint32 ownerID, uint32 groupID, uint64 modificationTime, int linkIndicator, const char * linkedFileName, uint64 fileSize);
79
80 /** Writes (numBytes) of data into the currently active file-block.
81 * Three must be a file-header currently active for this call to succeed.
82 * @param fileData Pointer to some data bytes to write into the tar file.
83 * @param numBytes How many bytes (fileData) points to.
84 * @returns B_NO_ERROR on success, or an error code on failure.
85 */
86 status_t WriteFileData(const uint8 * fileData, uint32 numBytes);
87
88 /** Updates the current file-header-block and resets our state to receive the next one.
89 * @returns B_NO_ERROR on success (or if no file-header-block was open), or an error code if there was an error updating the file-header-block.
90 * @note that Close() and WriteFileHeader() will call FinishCurrentFileDataBlock() implicitly when necessary, so
91 * calling this method isn't strictly necessary.
92 */
93 status_t FinishCurrentFileDataBlock();
94
95 /** These values may be passed to the (linkIndicator) argument of WriteFileHeader() to indicate what kind of filesystem-object the header is describing. */
96 enum {
97 TAR_LINK_INDICATOR_NORMAL_FILE = 0, /**< A normal data-file */
98 TAR_LINK_INDICATOR_HARD_LINK, /**< A hard-link */
99 TAR_LINK_INDICATOR_SYMBOLIC_LINK, /**< A symbolic link */
100 TAR_LINK_INDICATOR_CHARACTER_SPECIAL, /**< A file representing a character-based device */
101 TAR_LINK_INDICATOR_BLOCK_SPECIAL, /**< A file representing a block-based device */
102 TAR_LINK_INDICATOR_DIRECTORY, /**< A directory */
103 TAR_LINK_INDICATOR_FIFO, /**< A FIFO (named pipe) file*/
104 TAR_LINK_INDICATOR_CONTIGUOUS_FILE, /**< A contiguous file */
105 NUM_TAR_LINK_INDICATORS /**< Guard value */
106 };
107
108 /** Returns true iff we successfully opened the .tar output file. */
109 bool IsFileOpen() const {return (_writerIO() != NULL);}
110
111 /** Returns true iff we successfully started a .tar record block and it is currently open. */
112 bool IsFileDataBlockOpen() const {return (_currentHeaderOffset >= 0);}
113
114 private:
115 enum {TAR_BLOCK_SIZE=512};
116
117 void UpdateCurrentHeaderChecksum();
118
119 DataIORef _writerIO;
120 SeekableDataIORef _seekableWriterIO; // pre-downcast reference, for convenience. Will be NULL if our DataIO isn't a SeekableDataIO!
121 int64 _currentHeaderOffset;
122 uint8 _currentHeaderBytes[TAR_BLOCK_SIZE];
123 uint64 _prestatedFileSize; // as passed in to WriteFileHeader()
124 uint64 _currentSeekPosition; // gotta track this manually since (_seekableWriterIO()) may be NULL)
125 };
126
127 } // end namespace muscle
128
129 #endif