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