1 // Description:
2 // SDL_RWops wrapper for compressed stream.
3 //
4 // Copyright (C) 2001 Frank Becker
5 //
6 // This program is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free Software
8 // Foundation; either version 2 of the License, or (at your option) any later
9 // version.
10 //
11 // This program is distributed in the hope that it will be useful, but WITHOUT
12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
14 //
15 #include "zrwops.hpp"
16
17 #include <stdlib.h>
18 #include "Trace.hpp"
19
ziStream_seek(struct SDL_RWops * context,int offset,int whence)20 int ziStream_seek(struct SDL_RWops *context,int offset,int whence)
21 {
22 ziStream &zi = *((ziStream*)context->hidden.unknown.data1);
23 int pos = zi.currentPos();
24 int delta = 0;
25 #if 0
26 LOG_INFO << "ziStream_seek pos=" << pos
27 << " whence=" << whence
28 << " offset=" << offset
29 << endl;
30 #endif
31
32 switch( whence)
33 {
34 case SEEK_SET:
35 //LOG_INFO << "ziStream_seek SEEK_SET\n";
36 delta = offset - pos;
37 break;
38
39 case SEEK_END:
40 //LOG_INFO << "ziStream_seek SEEK_END\n";
41 if( zi.fileSize() < 0)
42 {
43 LOG_ERROR << "Cannot seek from END in this stream.\n";
44 return -1;
45 }
46 //LOG_INFO << "ziStream_seek END size=" << zi.fileSize() << " offset=" << offset << endl;
47 delta = zi.fileSize() - offset - pos; // -1;
48 break;
49
50 case SEEK_CUR:
51 //LOG_INFO << "ziStream_seek SEEK_CUR\n";
52 delta = offset;
53 break;
54
55 default:
56 //LOG_INFO << "ziStream_seek unknown whence value!" << endl;
57 return -1;
58 break;
59 }
60
61 if( delta < 0)
62 {
63 int fromStart = pos + delta;
64 if( fromStart < 0) fromStart = 0;
65
66 //reset to beginning of file
67 zi.reset();
68 //LOG_INFO << "ziStream_seek reset\n";
69
70 delta = fromStart;
71 }
72
73 if( delta > 0)
74 {
75 //LOG_INFO << "ziStream_seek read " << delta << "\n";
76 char *dumpBuffer = new char[ delta];
77 zi.read( dumpBuffer, delta);
78 delete [] dumpBuffer;
79 //LOG_INFO << "ziStream_seek new pos = " << zi.currentPos() << "\n";
80 }
81
82 return zi.currentPos();
83 }
ziStream_read(struct SDL_RWops * context,void * ptr,int size,int maxnum)84 int ziStream_read(struct SDL_RWops *context, void *ptr, int size, int maxnum)
85 {
86 ziStream &zi = *((ziStream*)context->hidden.unknown.data1);
87 zi.read( (char*)ptr, size*maxnum);
88 return( maxnum);
89 }
ziStream_write(struct SDL_RWops *,const void *,int,int)90 int ziStream_write(struct SDL_RWops *,const void *,int,int)
91 {
92 LOG_ERROR << "ziStream_write not implemented!\n";
93 return -1;
94 }
ziStream_close(struct SDL_RWops * context)95 int ziStream_close(struct SDL_RWops *context)
96 {
97 if( context)
98 {
99 SDL_FreeRW( context);
100 }
101 return(0);
102 }
103
RWops_from_ziStream(ziStream & zi)104 SDL_RWops *RWops_from_ziStream( ziStream &zi)
105 {
106 SDL_RWops *rwops;
107
108 rwops = SDL_AllocRW();
109 if ( rwops != NULL ) {
110 rwops->seek = ziStream_seek;
111 rwops->read = ziStream_read;
112 rwops->write = ziStream_write;
113 rwops->close = ziStream_close;
114 rwops->hidden.unknown.data1 = &zi;
115 }
116 return( rwops);
117 }
118
119