/[pcsx2_0.9.7]/trunk/pcsx2/CDVD/IsoFS/IsoFile.cpp
ViewVC logotype

Contents of /trunk/pcsx2/CDVD/IsoFS/IsoFile.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 7 months ago) by william
File size: 5524 byte(s)
committing r3113 initial commit again...
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16
17 #include "PrecompiledHeader.h"
18
19 #include "IsoFS.h"
20 #include "IsoFile.h"
21
22 IsoFile::IsoFile(SectorSource& reader, const wxString& filename)
23 : internalReader(reader)
24 , fileEntry(IsoDirectory(reader).FindFile(filename))
25 {
26 Init();
27 }
28
29 IsoFile::IsoFile(const IsoDirectory& dir, const wxString& filename)
30 : internalReader(dir.GetReader())
31 , fileEntry(dir.FindFile(filename))
32 {
33 Init();
34 }
35
36 IsoFile::IsoFile(SectorSource& reader, const IsoFileDescriptor& fileEntry)
37 : internalReader(reader)
38 , fileEntry(fileEntry)
39 {
40 Init();
41 }
42
43 void IsoFile::Init()
44 {
45 //pxAssertDev( fileEntry.IsFile(), "IsoFile Error: Filename points to a directory." );
46
47 currentSectorNumber = fileEntry.lba;
48 currentOffset = 0;
49 sectorOffset = 0;
50 maxOffset = std::max<u32>( 0, fileEntry.size );
51
52 if(maxOffset > 0)
53 internalReader.readSector(currentSector, currentSectorNumber);
54 }
55
56 IsoFile::~IsoFile() throw()
57 {
58 }
59
60 u32 IsoFile::seek(u32 absoffset)
61 {
62 u32 endOffset = absoffset;
63
64 int oldSectorNumber = currentSectorNumber;
65 int newSectorNumber = fileEntry.lba + (int)(endOffset / sectorLength);
66
67 if(oldSectorNumber != newSectorNumber)
68 {
69 internalReader.readSector(currentSector, newSectorNumber);
70 }
71
72 currentOffset = endOffset;
73 currentSectorNumber = newSectorNumber;
74 sectorOffset = (int)(currentOffset % sectorLength);
75
76 return currentOffset;
77 }
78
79 // Returns the new offset in the file. Out-of-bounds seeks are automatically truncated at 0
80 // and fileLength.
81 u32 IsoFile::seek(s64 offset, wxSeekMode ref_position)
82 {
83 switch( ref_position )
84 {
85 case wxFromStart:
86 pxAssertDev( offset >= 0 && offset <= (s64)ULONG_MAX, "Invalid seek position from start." );
87 return seek(offset);
88
89 case wxFromCurrent:
90 // truncate negative values to zero, and positive values to 4gb
91 return seek( std::min( std::max<s64>(0, (s64)currentOffset+offset), (s64)ULONG_MAX ) );
92
93 case wxFromEnd:
94 // truncate negative values to zero, and positive values to 4gb
95 return seek( std::min( std::max<s64>(0, (s64)fileEntry.size+offset), (s64)ULONG_MAX ) );
96
97 jNO_DEFAULT;
98 }
99
100 return 0; // unreachable
101 }
102
103 void IsoFile::reset()
104 {
105 seek(0);
106 }
107
108 // Returns the number of bytes actually skipped.
109 s32 IsoFile::skip(s32 n)
110 {
111 s32 oldOffset = currentOffset;
112
113 if (n<0) return 0;
114
115 seek(currentOffset+n);
116
117 return currentOffset - oldOffset;
118 }
119
120 u32 IsoFile::getSeekPos() const
121 {
122 return currentOffset;
123 }
124
125 bool IsoFile::eof() const
126 {
127 return (currentOffset == maxOffset);
128 }
129
130 // loads the current sector index into the CurrentSector buffer.
131 void IsoFile::makeDataAvailable()
132 {
133 if (sectorOffset >= sectorLength)
134 {
135 currentSectorNumber++;
136 internalReader.readSector(currentSector, currentSectorNumber);
137 sectorOffset -= sectorLength;
138 }
139 }
140
141 u8 IsoFile::readByte()
142 {
143 if(currentOffset >= maxOffset)
144 throw Exception::EndOfStream();
145
146 makeDataAvailable();
147
148 currentOffset++;
149
150 return currentSector[sectorOffset++];
151 }
152
153 // Reads data from a single sector at a time. Reads cannot cross sector boundaries.
154 int IsoFile::internalRead(void* dest, int off, int len)
155 {
156 if (len > 0)
157 {
158 size_t slen = len;
159 if (slen > (maxOffset - currentOffset))
160 {
161 slen = (int) (maxOffset - currentOffset);
162 }
163
164 memcpy_fast((u8*)dest + off, currentSector + sectorOffset, slen);
165
166 sectorOffset += slen;
167 currentOffset += slen;
168 return slen;
169 }
170 return 0;
171 }
172
173 // returns the number of bytes actually read.
174 s32 IsoFile::read(void* dest, s32 len)
175 {
176 pxAssert( dest != NULL );
177 pxAssert( len >= 0 ); // should we silent-fail on negative length reads? prolly not...
178
179 if( len <= 0 ) return 0;
180
181 int off = 0;
182
183 int totalLength = 0;
184
185 int firstSector = internalRead(dest, off, std::min(len, sectorLength - sectorOffset));
186 off += firstSector;
187 len -= firstSector;
188 totalLength += firstSector;
189
190 // Read whole sectors
191 while ((len >= sectorLength) && (currentOffset < maxOffset))
192 {
193 makeDataAvailable();
194 int n = internalRead(dest, off, sectorLength);
195 off += n;
196 len -= n;
197 totalLength += n;
198 }
199
200 // Read remaining, if any
201 if (len > 0) {
202 makeDataAvailable();
203 int lastSector = internalRead(dest, off, len);
204 totalLength += lastSector;
205 }
206
207 return totalLength;
208 }
209
210 // Reads data until it reaches a newline character (either \n, \r, or ASCII-Z). The caller is
211 // responsible for handling files with DOS-style newlines (CR/LF pairs), if needed. The resulting
212 // string has no newlines.
213 //
214 // Read data is unformatted 8 bit / Ascii. If the source file is known to be UTF8, use the fromUTF8()
215 // conversion helper provided by PCSX2 utility classes.
216 //
217 std::string IsoFile::readLine()
218 {
219 std::string s;
220 s.reserve( 512 );
221
222 while( !eof() )
223 {
224 u8 c = read<u8>();
225
226 if((c=='\n') || (c=='\r') || (c==0))
227 break;
228
229 s += c;
230 }
231
232 return s;
233 }
234
235 u32 IsoFile::getLength()
236 {
237 return maxOffset;
238 }
239
240 const IsoFileDescriptor& IsoFile::getEntry()
241 {
242 return fileEntry;
243 }

  ViewVC Help
Powered by ViewVC 1.1.22