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