2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU Library General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 // Created by: Kent Gustavsson <nedo80@gmail.com>
22 // Created on: Mon Mar 6 21:41:03 2006
25 #include "fileblock.h"
30 /* MS-DOS time/date conversion routines derived from: */
33 * linux/fs/msdos/misc.c
35 * Written 1992,1993 by Werner Almesberger
38 /* Convert a MS-DOS time/date pair (unspecified local time zones) to a UNIX
41 time_t date_dos2unix(unsigned short time
,unsigned short date
)
44 tm
.tm_year
= 1980 + (date
>> 9) - 1900,
45 tm
.tm_mon
= ((date
>> 5) & 15) - 1,
46 tm
.tm_mday
= date
& 31,
47 tm
.tm_hour
= time
>> 11,
48 tm
.tm_min
= (time
>> 5) & 63,
49 tm
.tm_sec
= (time
& 31)*2,
50 tm
.tm_isdst
= -1; /* unknown; mktime will guess */
54 FileBlock::FileBlock(std::istream
&in
) : RARBlock(in
),
57 unsigned int end
= in
.tellg();
58 start
= end
- size
- headsize
;
60 in
.seekg(end
+ 20-size
-headsize
);
64 time
+= in
.get() *256;
66 date
+= in
.get() *256;
67 filedate
=date_dos2unix(time
,date
);
69 in
.seekg(end
+ 25-size
-headsize
);
76 unsigned int filenamesize
= in
.get();
77 filenamesize
+= in
.get() * 256;
79 in
.seekg(4, std::ios::cur
);
80 char m
[filenamesize
+1];
84 in
.seekg(8, std::ios::cur
);
87 in
.read(m
, filenamesize
);
91 if ( flags
& 0x0400 ) /* Salt field present */
93 in
.seekg(min(in
.tellg() + std::streamoff(8),
94 std::streampos(start
+ headsize
)));
97 /* Extended time stamp field present */
98 if ( flags
& 0x1000 &&
99 in
.tellg() + std::streamoff(2) <= start
+ headsize
)
106 if ( ( flags
& 0xE0 ) == 0xE0 )
112 /* Derived from _parse_ext_time function in "rarfile" Python module.
113 http://rarfile.berlios.de/ */
115 FileBlock::ParseXtime()
117 unsigned int flags
= in
.get();
118 flags
+= in
.get() * 256;
122 unsigned int field_flags
= flags
>> field
* 4 & 0xF;
124 unsigned long frac
= 0; /* 100 ns units; 24 bits */
125 if ( field_flags
& 8 ) /* mtime field present */
127 filedate
+= field_flags
>> 2 & 1;
129 for ( unsigned int i
= 0; i
< (field_flags
& 3); ++i
)
132 frac
+= in
.get() << 16;
135 /* Add frac * 100 nanoseconds to timestamp */
137 /* Not interested in the three other time fields */
141 field_flags
= flags
>> field
* 4 & 0xF;
142 if ( 0 != (field_flags
& 8) )
144 in
.seekg(field_flags
& 3, std::ios::cur
);
150 FileBlock::GetFileDate()
155 FileBlock::~FileBlock()
161 FileBlock::isFolder()
167 FileBlock::isCompressed()
173 FileBlock::GetDataSize()
179 FileBlock::GetFileName()
185 FileBlock::GetData(char *buf
, unsigned int offset
, unsigned int len
)
187 std::streampos old
= in
.tellg();
189 in
.seekg(start
+ headsize
+ offset
);
191 if ( offset
> size
|| !len
)
193 if ( offset
+ len
> size
)