143 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			143 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| **	Command & Conquer Red Alert(tm)
 | |
| **	Copyright 2025 Electronic Arts Inc.
 | |
| **
 | |
| **	This program is free software: you can redistribute it and/or modify
 | |
| **	it under the terms of the GNU General Public License as published by
 | |
| **	the Free Software Foundation, either version 3 of the License, or
 | |
| **	(at your option) any later version.
 | |
| **
 | |
| **	This program is distributed in the hope that it will be useful,
 | |
| **	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| **	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| **	GNU General Public License for more details.
 | |
| **
 | |
| **	You should have received a copy of the GNU General Public License
 | |
| **	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | |
| */
 | |
| 
 | |
| 
 | |
| #include "streamer.h"
 | |
| #ifdef _WIN32
 | |
|   #include <windows.h>
 | |
| #endif
 | |
| 
 | |
| 
 | |
| Streamer::Streamer() : streambuf()
 | |
| {
 | |
|   int state=unbuffered();
 | |
|   unbuffered(0);  // 0 = buffered, 1 = unbuffered
 | |
| }
 | |
|  
 | |
| Streamer::~Streamer()
 | |
| {
 | |
|   sync();
 | |
|   delete[](base());
 | |
| }
 | |
| 
 | |
| int Streamer::setOutputDevice(OutputDevice *device)
 | |
| {
 | |
|   Output_Device=device;
 | |
|   return(0);
 | |
| }
 | |
| 
 | |
| 
 | |
| // put n chars from string into buffer
 | |
| int Streamer::xsputn(const char* buf, int size) //implementation of sputn
 | |
| {
 | |
| 
 | |
|   if (size<=0)  // Nothing to do
 | |
|     return(0);
 | |
| 
 | |
|   const unsigned char *ptr=(const unsigned char *)buf;
 | |
|   for (int i=0; i<size; i++, ptr++)
 | |
|   {
 | |
|     if(*ptr=='\n')
 | |
|     {
 | |
|       if (overflow(*ptr)==EOF)
 | |
|         return(i);
 | |
|     }
 | |
|     else if (sputc(*ptr)==EOF)
 | |
|       return(i);
 | |
|   }
 | |
|   return(size);
 | |
| }
 | |
| 
 | |
| // Flush the buffer and make more room if needed
 | |
| int Streamer::overflow(int c)
 | |
| {
 | |
| 
 | |
|   if (c==EOF)
 | |
|     return(sync());
 | |
|   if ((pbase()==0) && (doallocate()==0))
 | |
|     return(EOF);
 | |
|   if((pptr() >= epptr()) && (sync()==EOF))
 | |
|     return(EOF);
 | |
|   else {
 | |
|     sputc(c);
 | |
|     if ((unbuffered() && c=='\n' || pptr() >= epptr())
 | |
|         && sync()==EOF) {
 | |
|       return(EOF);
 | |
|     }
 | |
|     return(c);
 | |
|   }
 | |
| }
 | |
| 
 | |
| // This is a write only stream, this should never happen
 | |
| int Streamer::underflow(void)
 | |
| {
 | |
|   return(EOF);
 | |
| }
 | |
| 
 | |
| int Streamer::doallocate()
 | |
| {
 | |
| 
 | |
|   if (base()==NULL)
 | |
|   {
 | |
|     char *buf=new char[(2*STREAMER_BUFSIZ)];   // deleted by destructor
 | |
|     memset(buf,0,2*STREAMER_BUFSIZ);
 | |
| 
 | |
|     // Buffer
 | |
|     setb(
 | |
|        buf,         // base pointer
 | |
|        buf+STREAMER_BUFSIZ,  // ebuf pointer (end of buffer);
 | |
|        0);          // 0 = manual deletion of buff 
 | |
| 
 | |
|     // Get area
 | |
|     setg(
 | |
|         buf,   // eback 
 | |
|         buf,   // gptr
 | |
|         buf);  // egptr
 | |
| 
 | |
|     buf+=STREAMER_BUFSIZ;
 | |
|     // Put area
 | |
|     setp(buf,buf+STREAMER_BUFSIZ);
 | |
|     return(1);
 | |
|   }
 | |
|   else
 | |
|     return(0);
 | |
| }
 | |
| 
 | |
| 
 | |
| int Streamer::sync()
 | |
| {
 | |
|   if (pptr()<=pbase()) {
 | |
|     return(0);
 | |
|   }
 | |
| 
 | |
|   int wlen=pptr()-pbase();
 | |
| 
 | |
|   if (Output_Device)
 | |
|   {
 | |
|     Output_Device->print(pbase(),wlen);
 | |
|   }
 | |
| 
 | |
|   if (unbuffered()) {
 | |
|     setp(pbase(),pbase());
 | |
|   }
 | |
|   else {
 | |
|     setp(pbase(),pbase()+STREAMER_BUFSIZ);
 | |
|   }
 | |
|   return(0);
 | |
| }
 | 
