1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "System/CachedFileStream.h"
25 #include "Interface.h"
27 CachedFileStream::CachedFileStream(const char* stream
, bool autoFree
)
29 ExtractFileFromPath( filename
, stream
);
30 PathJoin( originalfile
, core
->CachePath
, filename
, NULL
);
32 str
= _fopen( originalfile
, "rb" );
33 if (str
== NULL
) { // File was not found in cache
35 _FILE
* src
= _fopen( stream
, "rb" );
37 core
->CachedFileStreamPtrCount
++;
39 _FILE
* dest
= _fopen( originalfile
, "wb" );
41 core
->CachedFileStreamPtrCount
++;
43 void* buff
= malloc( 1024 * 1000 );
45 size_t len
= _fread( buff
, 1, 1024 * 1000, src
);
46 size_t c
= _fwrite( buff
, 1, len
, dest
);
48 printf("CachedFileStream failed to write to cached file '%s' (from '%s')\n", originalfile
, stream
);
51 } while (!_feof( src
));
55 core
->CachedFileStreamPtrCount
--;
59 core
->CachedFileStreamPtrCount
--;
61 } else { // Don't cache files already on hdd
62 strncpy(originalfile
, stream
, _MAX_PATH
);
64 str
= _fopen( originalfile
, "rb" );
67 core
->CachedFileStreamPtrCount
++;
70 _fseek( str
, 0, SEEK_END
);
72 _fseek( str
, 0, SEEK_SET
);
74 this->autoFree
= autoFree
;
77 CachedFileStream::CachedFileStream(CachedFileStream
* cfs
, int startpos
,
78 int size
, bool autoFree
)
81 this->startpos
= startpos
;
82 this->autoFree
= autoFree
;
83 char cpath
[_MAX_PATH
];
84 PathJoin( cpath
, core
->CachePath
, cfs
->filename
, NULL
);
85 str
= _fopen( cpath
, "rb" );
87 str
= _fopen( cfs
->originalfile
, "rb" );
89 printf( "Can't open stream (maybe leaking?)\n" );
92 strncpy( originalfile
, cfs
->originalfile
, sizeof(originalfile
) );
93 strncpy( filename
, cfs
->filename
, sizeof(filename
) );
95 strncpy( originalfile
, cpath
, sizeof(originalfile
) );
96 strncpy( filename
, cfs
->filename
, sizeof(filename
) );
99 core
->CachedFileStreamPtrCount
++;
101 _fseek( str
, startpos
, SEEK_SET
);
107 CachedFileStream::~CachedFileStream(void)
109 if (autoFree
&& str
) {
111 core
->CachedFileStreamPtrCount
--;
116 //autoFree = false; //File stream destructor hack
119 int CachedFileStream::Read(void* dest
, unsigned int length
)
121 //we don't allow partial reads anyway, so it isn't a problem that
122 //i don't adjust length here (partial reads are evil)
123 if (Pos
+length
>size
) {
127 unsigned int c
= (unsigned int) _fread( dest
, 1, length
, str
);
132 ReadDecrypted( dest
, c
);
138 int CachedFileStream::Write(const void* src
, unsigned int length
)
140 // do encryption here if needed
142 unsigned int c
= (unsigned int) _fwrite( src
, 1, length
, str
);
147 //this is needed only if you want to Seek in a written file
154 int CachedFileStream::Seek(int newpos
, int type
)
157 case GEM_CURRENT_POS
:
158 _fseek( str
, newpos
, SEEK_CUR
);
162 case GEM_STREAM_START
:
163 _fseek( str
, startpos
+ newpos
, SEEK_SET
);
170 //we went past the buffer
172 printf("[Streams]: Invalid seek position: %ld (limit: %ld)\n",Pos
, size
);
178 /** No descriptions */
179 int CachedFileStream::ReadLine(void* buf
, unsigned int maxlen
)
184 unsigned char * p
= ( unsigned char * ) buf
;
194 while (i
< ( maxlen
- 1 )) {
195 int ch
= _fgetc( str
);
199 ch
^= GEM_ENCRYPTION_KEY
[Pos
& 63];
201 if (( ( char ) ch
) == '\n')
203 if (( ( char ) ch
) == '\t')
205 if (( ( char ) ch
) != '\r')
207 //Warning:this feof implementation reads forward one byte