1 /********************************************************************************
2 * *
3 * M e m o r y S t r e a m C l a s s e s *
4 * *
5 *********************************************************************************
6 * Copyright (C) 1997,2006 by Jeroen van der Zijp. All Rights Reserved. *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU Lesser General Public *
10 * License as published by the Free Software Foundation; either *
11 * version 2.1 of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
21 *********************************************************************************
22 * $Id: FXMemoryStream.cpp,v 1.17 2006/01/22 17:58:35 fox Exp $ *
23 ********************************************************************************/
24 #include "xincs.h"
25 #include "fxver.h"
26 #include "fxdefs.h"
27 #include "FXHash.h"
28 #include "FXStream.h"
29 #include "FXString.h"
30 #include "FXObject.h"
31 #include "FXStream.h"
32 #include "FXMemoryStream.h"
33
34
35 /*
36 Notes:
37 - Also need memory mapped file stream.
38 */
39
40
41 using namespace FX;
42
43
44 /*******************************************************************************/
45
46 namespace FX {
47
48
49 // Initialize memory stream
FXMemoryStream(const FXObject * cont)50 FXMemoryStream::FXMemoryStream(const FXObject* cont):FXStream(cont){
51 }
52
53
54 // Write at least count bytes from the buffer
writeBuffer(FXuval count)55 FXuval FXMemoryStream::writeBuffer(FXuval count){
56 if(owns){ setSpace(getSpace()+count); }
57 return endptr-wrptr;
58 }
59
60
61 // Read at least count bytes into the buffer
readBuffer(FXuval)62 FXuval FXMemoryStream::readBuffer(FXuval){
63 return wrptr-rdptr;
64 }
65
66
67 // Open a stream, possibly with an initial data array
open(FXStreamDirection save_or_load,FXuchar * data)68 bool FXMemoryStream::open(FXStreamDirection save_or_load,FXuchar* data){
69 if(save_or_load!=FXStreamSave && save_or_load!=FXStreamLoad){fxerror("FXMemoryStream::open: illegal stream direction.\n");}
70 if(FXStream::open(save_or_load,data?ULONG_MAX:16UL,data)){
71 if(save_or_load==FXStreamSave){
72 wrptr=begptr;
73 rdptr=begptr;
74 }
75 else{
76 wrptr=endptr;
77 rdptr=begptr;
78 }
79 return true;
80 }
81 return false;
82 }
83
84
85 // Open a stream, possibly with initial data array of certain size
open(FXStreamDirection save_or_load,FXuval size,FXuchar * data)86 bool FXMemoryStream::open(FXStreamDirection save_or_load,FXuval size,FXuchar* data){
87 if(save_or_load!=FXStreamSave && save_or_load!=FXStreamLoad){fxerror("FXMemoryStream::open: illegal stream direction.\n");}
88 if(FXStream::open(save_or_load,size,data)){
89 if(save_or_load==FXStreamSave){
90 wrptr=begptr;
91 rdptr=begptr;
92 }
93 else{
94 wrptr=endptr;
95 rdptr=begptr;
96 }
97 return true;
98 }
99 return false;
100 }
101
102
103 // Take buffer away from stream
takeBuffer(FXuchar * & data,FXuval & size)104 void FXMemoryStream::takeBuffer(FXuchar*& data,FXuval& size){
105 data=begptr;
106 size=endptr-begptr;
107 begptr=NULL;
108 wrptr=NULL;
109 rdptr=NULL;
110 endptr=NULL;
111 owns=false;
112 }
113
114
115 // Give buffer to stream
giveBuffer(FXuchar * data,FXuval size)116 void FXMemoryStream::giveBuffer(FXuchar *data,FXuval size){
117 if(data==NULL){ fxerror("FXMemoryStream::giveBuffer: NULL buffer argument.\n"); }
118 if(owns){FXFREE(&begptr);}
119 begptr=data;
120 endptr=data+size;
121 if(dir==FXStreamSave){
122 wrptr=begptr;
123 rdptr=begptr;
124 }
125 else{
126 wrptr=endptr;
127 rdptr=begptr;
128 }
129 owns=true;
130 }
131
132
133 // Close the stream
close()134 bool FXMemoryStream::close(){
135 if(dir){
136 if(owns){FXFREE(&begptr);}
137 begptr=NULL;
138 wrptr=NULL;
139 rdptr=NULL;
140 endptr=NULL;
141 owns=false;
142 return FXStream::close();
143 }
144 return false;
145 }
146
147
148 // Move to position; if saving and we own the buffer, try to resize
149 // and 0-fill the space; if loading and not out of range, move the pointer;
150 // otherwise, return error code.
position(FXlong offset,FXWhence whence)151 bool FXMemoryStream::position(FXlong offset,FXWhence whence){
152 if(dir==FXStreamDead){ fxerror("FXMemoryStream::position: stream is not open.\n"); }
153 if(code==FXStreamOK){
154 if(whence==FXFromCurrent) offset=offset+pos;
155 else if(whence==FXFromEnd) offset=offset+endptr-begptr;
156 if(dir==FXStreamSave){
157 if(begptr+offset>endptr){
158 if(!owns){ setError(FXStreamFull); return false; }
159 setSpace(offset);
160 if(begptr+offset>endptr) return false;
161 }
162 wrptr=begptr+offset;
163 }
164 else{
165 if(begptr+offset>endptr){ setError(FXStreamEnd); return false; }
166 rdptr=begptr+offset;
167 }
168 pos=offset;
169 return true;
170 }
171 return false;
172 }
173
174
175 }
176