VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.cpp@ 62890

Last change on this file since 62890 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.4 KB
Line 
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is the Netscape Portable Runtime (NSPR).
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998-2000
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38/*
39 * Robin J. Maxwell 11-22-96
40 */
41
42#include "prstrms.h"
43#include <string.h> // memmove
44
45//
46// Definition of macros _PRSTR_BP, _PRSTR_DELBUF, and _PRSTR_DELBUF_C.
47//
48// _PRSTR_BP is the protected member of class ios that is returned
49// by the public method rdbuf().
50//
51// _PRSTR_DELBUF is the method or data member of class ios, if available,
52// with which we can ensure that the ios destructor does not delete
53// the associated streambuf. If such a method or data member does not
54// exist, define _PRSTR_DELBUF to be empty.
55//
56// _PRSTR_DELBUF_C is just _PRSTR_DELBUF qualified by a base class.
57//
58
59#if defined(__GNUC__)
60#define _PRSTR_BP _strbuf
61#define _PRSTR_DELBUF(x) /* as nothing */
62#define _PRSTR_DELBUF_C(c, x) /* as nothing */
63#elif defined(WIN32)
64#define _PRSTR_BP bp
65#define _PRSTR_DELBUF(x) delbuf(x)
66#define _PRSTR_DELBUF_C(c, x) c::_PRSTR_DELBUF(x)
67#elif defined(VMS)
68#undef _PRSTR_BP
69#define _PRSTR_DELBUF(x) /* as nothing */
70#define _PRSTR_DELBUF_C(c, x) /* as nothing */
71#elif defined(OSF1)
72#define _PRSTR_BP m_psb
73#define _PRSTR_DELBUF(x) /* as nothing */
74#define _PRSTR_DELBUF_C(c, x) /* as nothing */
75#elif defined(QNX)
76#define PRFSTREAMS_BROKEN
77#else
78#define _PRSTR_BP bp
79// Unix compilers don't believe in encapsulation
80// At least on Solaris this is also ignored
81#define _PRSTR_DELBUF(x) delbuf = x
82#define _PRSTR_DELBUF_C(c, x) c::_PRSTR_DELBUF(x)
83#endif
84
85const PRIntn STRM_BUFSIZ = 8192;
86
87#if !defined (PRFSTREAMS_BROKEN)
88
89PRfilebuf::PRfilebuf():
90_fd(0),
91_opened(PR_FALSE),
92_allocated(PR_FALSE)
93{
94}
95
96PRfilebuf::PRfilebuf(PRFileDesc *fd):
97streambuf(),
98_fd(fd),
99_opened(PR_FALSE),
100_allocated(PR_FALSE)
101{
102}
103
104PRfilebuf::PRfilebuf(PRFileDesc *fd, char * buffptr, int bufflen):
105_fd(fd),
106_opened(PR_FALSE),
107_allocated(PR_FALSE)
108{
109 PRfilebuf::setbuf(buffptr, bufflen);
110}
111
112PRfilebuf::~PRfilebuf()
113{
114 if (_opened){
115 close();
116 }else
117 sync();
118 if (_allocated)
119 delete base();
120}
121
122PRfilebuf*
123PRfilebuf::open(const char *name, int mode, int flags)
124{
125 if (_fd != 0)
126 return 0; // error if already open
127 PRIntn PRmode = 0;
128 // translate mode argument
129 if (!(mode & ios::nocreate))
130 PRmode |= PR_CREATE_FILE;
131 //if (mode & ios::noreplace)
132 // PRmode |= O_EXCL;
133 if (mode & ios::app){
134 mode |= ios::out;
135 PRmode |= PR_APPEND;
136 }
137 if (mode & ios::trunc){
138 mode |= ios::out; // IMPLIED
139 PRmode |= PR_TRUNCATE;
140 }
141 if (mode & ios::out){
142 if (mode & ios::in)
143 PRmode |= PR_RDWR;
144 else
145 PRmode |= PR_WRONLY;
146 if (!(mode & (ios::in|ios::app|ios::ate|ios::noreplace))){
147 mode |= ios::trunc; // IMPLIED
148 PRmode |= PR_TRUNCATE;
149 }
150 }else if (mode & ios::in)
151 PRmode |= PR_RDONLY;
152 else
153 return 0; // error if not ios:in or ios::out
154
155
156 //
157 // The usual portable across unix crap...
158 // NT gets a hokey piece of junk layer that prevents
159 // access to the API.
160#ifdef WIN32
161 _fd = PR_Open(name, PRmode, PRmode);
162#else
163 _fd = PR_Open(name, PRmode, flags);
164#endif
165 if (_fd == 0)
166 return 0;
167 _opened = PR_TRUE;
168 if ((!unbuffered()) && (!ebuf())){
169 char * sbuf = new char[STRM_BUFSIZ];
170 if (!sbuf)
171 unbuffered(1);
172 else{
173 _allocated = PR_TRUE;
174 streambuf::setb(sbuf,sbuf+STRM_BUFSIZ,0);
175 }
176 }
177 if (mode & ios::ate){
178 if (seekoff(0,ios::end,mode)==EOF){
179 close();
180 return 0;
181 }
182 }
183 return this;
184}
185
186PRfilebuf*
187PRfilebuf::attach(PRFileDesc *fd)
188{
189 _opened = PR_FALSE;
190 _fd = fd;
191 return this;
192}
193
194int
195PRfilebuf::overflow(int c)
196{
197 if (allocate()==EOF) // make sure there is a reserve area
198 return EOF;
199 if (PRfilebuf::sync()==EOF) // sync before new buffer created below
200 return EOF;
201
202 if (!unbuffered())
203 setp(base(),ebuf());
204
205 if (c!=EOF){
206 if ((!unbuffered()) && (pptr() < epptr())) // guard against recursion
207 sputc(c);
208 else{
209 if (PR_Write(_fd, &c, 1)!=1)
210 return(EOF);
211 }
212 }
213 return(1); // return something other than EOF if successful
214}
215
216int
217PRfilebuf::underflow()
218{
219 int count;
220 unsigned char tbuf;
221
222 if (in_avail())
223 return (int)(unsigned char) *gptr();
224
225 if (allocate()==EOF) // make sure there is a reserve area
226 return EOF;
227 if (PRfilebuf::sync()==EOF)
228 return EOF;
229
230 if (unbuffered())
231 {
232 if (PR_Read(_fd,(void *)&tbuf,1)<=0)
233 return EOF;
234 return (int)tbuf;
235 }
236
237 if ((count=PR_Read(_fd,(void *)base(),blen())) <= 0)
238 return EOF; // reached EOF
239 setg(base(),base(),base()+count);
240 return (int)(unsigned char) *gptr();
241}
242
243streambuf*
244PRfilebuf::setbuf(char *buffptr, PRstreambuflen bufflen)
245{
246 if (is_open() && (ebuf()))
247 return 0;
248 if ((!buffptr) || (bufflen <= 0))
249 unbuffered(1);
250 else
251 setb(buffptr, buffptr+bufflen, 0);
252 return this;
253}
254
255streampos
256PRfilebuf::seekoff(streamoff offset, ios::seek_dir dir, int /* mode */)
257{
258 if (PR_GetDescType(_fd) == PR_DESC_FILE){
259 PRSeekWhence fdir;
260 PRInt32 retpos;
261 switch (dir) {
262 case ios::beg :
263 fdir = PR_SEEK_SET;
264 break;
265 case ios::cur :
266 fdir = PR_SEEK_CUR;
267 break;
268 case ios::end :
269 fdir = PR_SEEK_END;
270 break;
271 default:
272 // error
273 return(EOF);
274 }
275
276 if (PRfilebuf::sync()==EOF)
277 return EOF;
278 if ((retpos=PR_Seek(_fd, offset, fdir))==-1L)
279 return (EOF);
280 return((streampos)retpos);
281 }else
282 return (EOF);
283}
284
285
286int
287PRfilebuf::sync()
288{
289 PRInt32 count;
290
291 if (_fd==0)
292 return(EOF);
293
294 if (!unbuffered()){
295 // Sync write area
296 if ((count=out_waiting())!=0){
297 PRInt32 nout;
298 if ((nout =PR_Write(_fd,
299 (void *) pbase(),
300 (unsigned int)count)) != count){
301 if (nout > 0) {
302 // should set _pptr -= nout
303 pbump(-(int)nout);
304 memmove(pbase(), pbase()+nout, (int)(count-nout));
305 }
306 return(EOF);
307 }
308 }
309 setp(0,0); // empty put area
310
311 if (PR_GetDescType(_fd) == PR_DESC_FILE){
312 // Sockets can't seek; don't need this
313 if ((count=in_avail()) > 0){
314 if (PR_Seek(_fd, -count, PR_SEEK_CUR)!=-1L)
315 {
316 return (EOF);
317 }
318 }
319 }
320 setg(0,0,0); // empty get area
321 }
322 return(0);
323}
324
325PRfilebuf *
326PRfilebuf::close()
327{
328 int retval;
329 if (_fd==0)
330 return 0;
331
332 retval = sync();
333
334 if ((PR_Close(_fd)==0) || (retval==EOF))
335 return 0;
336 _fd = 0;
337 return this;
338}
339
340PRifstream::PRifstream():
341istream(new PRfilebuf)
342{
343 _PRSTR_DELBUF(0);
344}
345
346PRifstream::PRifstream(PRFileDesc *fd):
347istream(new PRfilebuf(fd))
348{
349 _PRSTR_DELBUF(0);
350}
351
352PRifstream::PRifstream(PRFileDesc *fd, char *buff, int bufflen):
353istream(new PRfilebuf(fd, buff, bufflen))
354{
355 _PRSTR_DELBUF(0);
356}
357
358PRifstream::PRifstream(const char * name, int mode, int flags):
359istream(new PRfilebuf)
360{
361 _PRSTR_DELBUF(0);
362 if (!rdbuf()->open(name, (mode|ios::in), flags))
363 clear(rdstate() | ios::failbit);
364}
365
366PRifstream::~PRifstream()
367{
368 sync();
369
370 delete rdbuf();
371#ifdef _PRSTR_BP
372 _PRSTR_BP = 0;
373#endif
374}
375
376streambuf *
377PRifstream::setbuf(char * ptr, int len)
378{
379 if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){
380 clear(rdstate() | ios::failbit);
381 return 0;
382 }
383 return rdbuf();
384}
385
386void
387PRifstream::attach(PRFileDesc *fd)
388{
389 if (!(rdbuf()->attach(fd)))
390 clear(rdstate() | ios::failbit);
391}
392
393void
394PRifstream::open(const char * name, int mode, int flags)
395{
396 if (is_open() || !(rdbuf()->open(name, (mode|ios::in), flags)))
397 clear(rdstate() | ios::failbit);
398}
399
400void
401PRifstream::close()
402{
403 clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit));
404}
405
406PRofstream::PRofstream():
407ostream(new PRfilebuf)
408{
409 _PRSTR_DELBUF(0);
410}
411
412PRofstream::PRofstream(PRFileDesc *fd):
413ostream(new PRfilebuf(fd))
414{
415 _PRSTR_DELBUF(0);
416}
417
418PRofstream::PRofstream(PRFileDesc *fd, char *buff, int bufflen):
419ostream(new PRfilebuf(fd, buff, bufflen))
420{
421 _PRSTR_DELBUF(0);
422}
423
424PRofstream::PRofstream(const char *name, int mode, int flags):
425ostream(new PRfilebuf)
426{
427 _PRSTR_DELBUF(0);
428 if (!rdbuf()->open(name, (mode|ios::out), flags))
429 clear(rdstate() | ios::failbit);
430}
431
432PRofstream::~PRofstream()
433{
434 flush();
435
436 delete rdbuf();
437#ifdef _PRSTR_BP
438 _PRSTR_BP = 0;
439#endif
440}
441
442streambuf *
443PRofstream::setbuf(char * ptr, int len)
444{
445 if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){
446 clear(rdstate() | ios::failbit);
447 return 0;
448 }
449 return rdbuf();
450}
451
452void
453PRofstream::attach(PRFileDesc *fd)
454{
455 if (!(rdbuf()->attach(fd)))
456 clear(rdstate() | ios::failbit);
457}
458
459void
460PRofstream::open(const char * name, int mode, int flags)
461{
462 if (is_open() || !(rdbuf()->open(name, (mode|ios::out), flags)))
463 clear(rdstate() | ios::failbit);
464}
465
466void
467PRofstream::close()
468{
469 clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit));
470}
471
472PRfstream::PRfstream():
473iostream(new PRfilebuf)
474{
475 _PRSTR_DELBUF_C(istream, 0);
476 _PRSTR_DELBUF_C(ostream, 0);
477}
478
479PRfstream::PRfstream(PRFileDesc *fd):
480iostream(new PRfilebuf(fd))
481{
482 _PRSTR_DELBUF_C(istream, 0);
483 _PRSTR_DELBUF_C(ostream, 0);
484}
485
486PRfstream::PRfstream(PRFileDesc *fd, char *buff, int bufflen):
487iostream(new PRfilebuf(fd, buff, bufflen))
488{
489 _PRSTR_DELBUF_C(istream, 0);
490 _PRSTR_DELBUF_C(ostream, 0);
491}
492
493PRfstream::PRfstream(const char *name, int mode, int flags):
494iostream(new PRfilebuf)
495{
496 _PRSTR_DELBUF_C(istream, 0);
497 _PRSTR_DELBUF_C(ostream, 0);
498 if (!rdbuf()->open(name, (mode|(ios::in|ios::out)), flags))
499 clear(rdstate() | ios::failbit);
500}
501
502PRfstream::~PRfstream()
503{
504 sync();
505 flush();
506
507 delete rdbuf();
508#ifdef _PRSTR_BP
509 istream::_PRSTR_BP = 0;
510 ostream::_PRSTR_BP = 0;
511#endif
512}
513
514streambuf *
515PRfstream::setbuf(char * ptr, int len)
516{
517 if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){
518 clear(rdstate() | ios::failbit);
519 return 0;
520 }
521 return rdbuf();
522}
523
524void
525PRfstream::attach(PRFileDesc *fd)
526{
527 if (!(rdbuf()->attach(fd)))
528 clear(rdstate() | ios::failbit);
529}
530
531void
532PRfstream::open(const char * name, int mode, int flags)
533{
534 if (is_open() || !(rdbuf()->open(name, (mode|(ios::in|ios::out)), flags)))
535 clear(rdstate() | ios::failbit);
536}
537
538void
539PRfstream::close()
540{
541 clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit));
542}
543
544#else
545
546// fix it sometime
547
548int fix_prfstreams () { return 0; }
549
550#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette