Streambuf.cpp

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //------------------------------------------------------------------------------
00003 //                              Streambuf.cpp
00004 //------------------------------------------------------------------------------
00005 //  Copyright (c) 1999 by Vladislav Grinchenko
00006 //
00007 //  This library is free software; you can redistribute it and/or
00008 //  modify it under the terms of the GNU Library General Public
00009 //  License as published by the Free Software Foundation; either
00010 //  version 2 of the License, or (at your option) any later version.
00011 //
00012 //------------------------------------------------------------------------------
00013 //  Created: 12/02/99
00014 //------------------------------------------------------------------------------
00015 
00016 #include "assa/Streambuf.h"
00017 #include "assa/MemDump.h"
00018 
00019 using namespace ASSA;
00020 
00021 //  Old comment:
00022 //
00023 //  "Maximum frame size that can be transmitted unfragmented by TCP
00024 //   with MTU 1500 (1500-20-60). TCP frame can have options
00025 //   (up to 60 bytes) which, if ignored, might cause fragmentation.
00026 //   Also, the length of the IP packet must be evenly divisible by 8."
00027 //
00028 //  On 100Mb networks, the reasonable buffer size seems to be 64K.
00029 
00034 // const int Streambuf::MAXTCPFRAMESZ = 65536;  // 64K
00035 
00036 void
00037 io_ptrs::
00038 dump () const 
00039 {
00040 #ifdef LOG_PACKET
00041     trace_with_mask("io_ptrs::dump",STRMBUF);
00042     int len;
00043 
00044     DL((STRMBUF,"---Ptr------:---Val---\n"));
00045     DL((STRMBUF,"m_read_base.: 0x%x\n", (u_long)m_read_base));
00046     DL((STRMBUF,"m_read_ptr..: 0x%x\n", (u_long)m_read_ptr ));
00047     DL((STRMBUF,"m_read_end..: 0x%x\n", (u_long)m_read_end ));
00048 
00049     if (m_read_ptr && (len = m_read_end - m_read_ptr) > 0) {
00050         MemDump get_area (m_read_ptr, len);
00051         DL((STRMBUF,"\n%s\n", get_area.getMemDump ()));
00052     }
00053 
00054     DL((STRMBUF,"m_write_base: 0x%x\n", (u_long)m_write_base));
00055     DL((STRMBUF,"m_write_ptr.: 0x%x\n", (u_long)m_write_ptr ));
00056     DL((STRMBUF,"m_write_end.: 0x%x\n", (u_long)m_write_end ));
00057 
00058     if (m_write_base && (len = m_write_ptr - m_write_base) > 0) {
00059         MemDump put_area (m_write_base, len);
00060         DL((STRMBUF,"%s\n", put_area.getMemDump ()));
00061     }
00062 
00063     DL((STRMBUF,"m_buf_base..: 0x%x\n", (u_long)m_buf_base  ));
00064     DL((STRMBUF,"m_buf_end...: 0x%x\n", (u_long)m_buf_end   ));
00065     DL((STRMBUF,"------------:---------\n");
00066 
00067 #endif
00068 }
00069 
00070 int 
00071 Streambuf::
00072 snextc ()
00073 {   
00074     trace_with_mask("Streambuf::snextc",STRMBUFTRACE);
00075 
00076     if (m_read_ptr >= m_read_end && underflow () == EOF) {
00077         return EOF;
00078     }
00079     return m_read_ptr++, sgetc (); 
00080 }
00081 
00082 void
00083 Streambuf::
00084 setg (char* gbeg_, char* gnext_, char* gend_)
00085 {
00086     trace_with_mask("Streambuf::setg",STRMBUFTRACE);
00087 
00088     m_read_base = gbeg_;
00089     m_read_ptr  = gnext_;
00090     m_read_end  = gend_;
00091 }
00092 
00093 void
00094 Streambuf::
00095 setb (char* b_, char* eb_, int del_)
00096 {
00097     trace_with_mask("Streambuf::setb",STRMBUFTRACE);
00098 
00099     if (m_buf_base && !(m_flags & USER_BUF))
00100         delete m_buf_base;
00101 
00102     m_buf_base = b_;
00103     m_buf_end = eb_;
00104     
00105     if (del_)
00106         m_flags &= ~ USER_BUF; // clear bit
00107     else
00108         m_flags |= USER_BUF; // set bit
00109 
00110     dump ();
00111 }
00112 
00113 Streambuf*
00114 Streambuf::
00115 setbuf (char* p_, int len_)
00116 {
00117     trace_with_mask("Streambuf::setb",STRMBUFTRACE);
00118 
00119     if (sync () == EOF) // Flush out all pending bytes before
00120         return NULL;    // resetting buffer. Also, first time around,
00121     // calling sync() suppose to set put area
00122     // pointers.
00123 
00124     if (p_ == NULL || len_ == 0) {
00125         DL((STRMBUF,"Unbuffered IO set.\n"));
00126         unbuffered (1);
00127         // We do it from doalloc instead - vlg
00128         // setb (m_shortbuf, m_shortbuf+1, 0);
00129     }
00130     else {
00131         DL((STRMBUF,"Buffered IO set.\n"));
00132         unbuffered (0);
00133         setb (p_, p_ + len_, 0);
00134     }
00135     setp (0, 0);
00136     setg (0, 0, 0);
00137 
00138     return this;
00139 }
00140 
00141 int
00142 Streambuf::
00143 xsgetn (char* data_, int len_)
00144 {
00145     trace_with_mask("Streambuf::xsgetn",STRMBUFTRACE);
00146 
00147     /*
00148       Get area is empty and nothing is on the socket.
00149     */
00150     int count = m_read_end - m_read_ptr; // Bytes in Get area
00151 
00152     if (count == 0 && underflow () == EOF) {
00153         DL((STRMBUFTRACE,"returning %d. count: %d\n", EOF));
00154         return EOF;
00155     }
00156     count = m_read_end - m_read_ptr; // Adjusted bytes in Get area
00157 
00158     DL((STRMBUFTRACE,"Adjusted bytes in Get Area: %d\n",count));
00159 
00160     if (count > len_) {
00161         count = len_;
00162     }
00163 
00164     if (count <= 0) {
00165         count = 0;  // Peer closed connection
00166     }
00167     else if (count > 20) {
00168         memcpy (data_, m_read_ptr, count);
00169         m_read_ptr += count;
00170     }
00171     else {
00172         char* s = data_;
00173         char* p = m_read_ptr;
00174         int i = count;
00175         while (i-- > 0) {
00176             *s++ = *p++;
00177         }
00178         m_read_ptr = p;
00179     }
00180     DL((STRMBUFTRACE,"Transferred %d bytes to user-space buffer\n", count));
00181 
00182     return (count);
00183 }
00184 
00185 int
00186 Streambuf::
00187 uflow ()
00188 {
00189     trace_with_mask("Streambuf::uflow",STRMBUFTRACE);
00190 
00191     if (underflow () == EOF)
00192         return EOF;
00193     dump ();
00194     return *(unsigned char *) m_read_ptr++;
00195 }
00196 
00197 int
00198 Streambuf::
00199 xsputn (const char* data_, int len_)
00200 {
00201     trace_with_mask("Streambuf::xsputn",STRMBUFTRACE);
00202 
00203     const char* s = data_;
00204     int more = len_;
00205     if (more <= 0) {
00206         return 0;
00207     }
00208 
00209     for (;;) {
00210         int count = m_write_end - m_write_ptr; // Space available
00211 
00212         if (count > 0) {
00213 
00214             if (count > more) // Enough buffer space
00215                 count = more;
00216 
00217             if (count > 20) {
00218                 memcpy (m_write_ptr, s, count);
00219                 s += count;
00220                 m_write_ptr += count;
00221             }
00222             else if (count <= 0) {
00223                 count = 0;
00224             }
00225             else {
00226                 char* p = m_write_ptr;
00227                 int i;
00228 
00229                 for (i=count; --i >= 0;) {
00230                     *p++ = *s++;
00231                 }
00232                 m_write_ptr = p;
00233             }
00234             more -= count;
00235         } // if (count>0)
00236         
00237         if (more == 0 || overflow ((unsigned char) *s++) == EOF) {
00238             break;
00239         }
00240         more--;
00241 
00242     } // for (;;)
00243 
00244     return (len_ - more);
00245 }
00246 
00247 
00248 int
00249 Streambuf::doallocate ()
00250 {
00251     trace_with_mask("Streambuf::doallocate",STRMBUFTRACE);
00252 
00253     char* buf;
00254     buf = new char [1024];
00255     if (buf == NULL) {
00256         return EOF;
00257     }
00258     setb (buf, buf+1024, 1);
00259 
00260     return 1;
00261 }
00262 

Generated on Mon Dec 19 16:37:15 2005 for libassa by  doxygen 1.4.5