summaryrefslogtreecommitdiffstats
path: root/kdat/File.h
blob: 0dda512eb17ed5c7806a5fd1c6fd58c9d40644c6 (plain)
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// KDat - a tar-based DAT archiver
// Copyright (C) 1998-2000  Sean Vyain, svyain@mail.tds.net
// Copyright (C) 2001-2002  Lawrence Widman, kdat@cardiothink.com
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#ifndef File_H
#define File_H

#include <stdio.h>

#include <qptrlist.h>
#include <qstring.h>

#include "Range.h"
#include "kdat.h"

/**
 * @short This class represents a single file or directory in a tar file.
 */
class File {
    bool _stubbed;
    union {
        struct {
            int _size;
            int _mtime;
            int _startRecord;
            int _endRecord;
        } _data;
        struct {
            FILE* _fptr;
            int   _offset;
        } _stub;
    } _union;
    QString     _name;
    File*       _parent;
    QPtrList<File> _children;
    RangeList   _ranges;
public:
    /**
     * Create a new file entry.
     *
     * @param parent      The directory file entry that contains this file.
     * @param size        The size of the file in bytes.
     * @param mtime       The last modification time of the file in seconds since
     *                    the Epoch.
     * @param startRecord The first tar record number in the file.
     * @param endRecord   The last tar record number in the file.
     * @param name        The file name.  If the file name ends with a '/' then it
     *                    is assumed to be a directory name.  Only the last part of
     *                    the file's path name should be passed in.  The rest of the
     *                    path is determined by this file entry's ancestors.
     */
    File( File* parent, int size, int mtime, int startRecord, int endRecord, const QString & name );
    
    /**
     * Create a new stubbed instance of a file entry.  The file pointer and
     * offset specify where the actual instance data can be found.  The real
     * data is read on demand when one of the accessor functions is called.
     *
     * @param parent The directory file entry that contains this file.
     * @param fptr   The open index file containing this file entry.  The file
     *               must be left open so that the file entry information can
     *               be read at a later time.
     * @param offset The offset that will be seeked to when reading the file
     *               entry information.
     */
    File( File* parent, FILE* fptr, int offset );

    /**
     * Destroy the file entry and all of its children.
     */
    ~File();
    
    /**
     * Insure that all of the data fields for this file entry have been read
     * in.  If the file entry is a stub then the actual data is read from the
     * index file.  If the file entry is not a stub then no action is taken.
     *
     * @param version The version of the old tape index.
     */
    void read( int version = KDAT_INDEX_FILE_VERSION );

    /**
     * Recursively read the instance for this file entry and all of it's
     * children.  This method is used when converting from an older index format.
     *
     * @param version The version of the old tape index.
     */
    void readAll( int version );
    
    /**
     * Write out the file entry to the open file.  Entries for each of its
     * children will also be written.
     */
    void write( FILE* fptr );

    /**
     * Determine whether this file entry represents a directory.  If the file
     * name ends in a '/' then it is assumed that it is a directory.
     *
     * @return TRUE if the file represents a directory, or FALSE if it is an
     *         ordinary file.
     */
    bool isDirectory();

    /**
     * Get the size of the file.
     *
     * @return The size, in bytes, of the file.
     */
    int getSize();

    /**
     * Get the last modification time for the file.
     *
     * @ return The last time the file was modified, in seconds since the Epoch.
     */
    int getMTime();

    /**
     * Get the tar record number for the file.  This is the number of 512-byte
     * tar blocks that must be read before getting to this file.
     *
     * @return The tar record number for the file.
     */
    int getStartRecord();

    /**
     * Get the tar record number that is just past the end of the file.  This
     * number minus the start record gives the number of 512-byte tar blocks
     * that this file occupies in the archive.
     *
     * @return The last tar record number for the file.
     */
    int getEndRecord();

    /**
     * Get the name of this file.  Only the last component of the full path
     * name is returned.
     *
     * @return The file's name.
     */
    QString getName();

    /**
     * Get the full path name of the file.
     *
     * @return The full path to the file.
     */
    QString getFullPathName();

    /**
     * Get the file entry's parent.  A NULL parent indicates that this is one
     * of (possibly) many top level directories within the tar archive.
     *
     * @return A pointer to the file entry that contains this file entry.
     */
    File* getParent();

    /**
     * Get the children of this file entry.  A normal file will never have any
     * children.  A directory may or may not have children.
     *
     * @return A list of the immediate children of this file entry.
     */
    const QPtrList<File>& getChildren();

    /**
     * Get the list of ranges of this file and all of its children.
     *
     * @return A list of ranges.
     */
    const QPtrList<Range>& getRanges();

    /**
     * Add a new file entry as a child of this file entry.
     *
     * @param file The file to add.
     */
    void addChild( File* file );

    /**
     * Recursively calculate the list of ranges for all of the file's children.
     */
    void calcRanges();
};

#endif