1 /* $Id: fcgibuf.cpp 103491 2007-05-04 17:18:18Z kazimird $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Eugene Vasilchenko
27 *
28 * File Description:
29 * FCGI streambufs
30 *
31 */
32
33 #include <ncbi_pch.hpp>
34 #include <corelib/ncbistd.hpp>
35 #include <fcgiapp.h>
36 #include "fcgibuf.hpp"
37 #include <algorithm>
38
39
40 BEGIN_NCBI_SCOPE
41
42
CCgiObuffer(FCGX_Stream * out)43 CCgiObuffer::CCgiObuffer(FCGX_Stream* out)
44 : m_out(out), m_cnt(0)
45 {
46 if (!m_out || m_out->isReader) {
47 THROW1_TRACE(runtime_error, "CCgiObuffer: out is not writer");
48 }
49
50 setp((CT_CHAR_TYPE*) m_out->wrNext, (CT_CHAR_TYPE*) m_out->stop);
51 }
52
53
~CCgiObuffer(void)54 CCgiObuffer::~CCgiObuffer(void)
55 {
56 (void) sync();
57 }
58
59
overflow(CT_INT_TYPE c)60 CT_INT_TYPE CCgiObuffer::overflow(CT_INT_TYPE c)
61 {
62 m_cnt += ((unsigned char*) pptr()) - m_out->wrNext;
63
64 _ASSERT(m_out->stop == (unsigned char*) epptr());
65 m_out->wrNext = (unsigned char*) pptr();
66
67 if (m_out->wrNext == m_out->stop) {
68 if (m_out->isClosed || !m_out->emptyBuffProc) {
69 return CT_EOF;
70 }
71
72 m_out->emptyBuffProc(m_out, false);
73 if (m_out->wrNext == m_out->stop) {
74 if ( !m_out->isClosed ) {
75 THROW1_TRACE(runtime_error,
76 "CCgiObuffer::overflow: error in emptyBuffProc");
77 }
78 return CT_EOF;
79 }
80
81 setp((CT_CHAR_TYPE*) m_out->wrNext, (CT_CHAR_TYPE*) m_out->stop);
82 }
83
84 return CT_EQ_INT_TYPE(c, CT_EOF)
85 ? CT_NOT_EOF(CT_EOF) : sputc(CT_TO_CHAR_TYPE(c));
86 }
87
88
sync(void)89 int CCgiObuffer::sync(void)
90 {
91 CT_INT_TYPE oflow = overflow(CT_EOF);
92 if ( CT_EQ_INT_TYPE(oflow, CT_EOF) )
93 return -1;
94 int flush = FCGX_FFlush(m_out);
95 setp((CT_CHAR_TYPE*) m_out->wrNext, (CT_CHAR_TYPE*) m_out->stop);
96 return flush ? -1 : 0;
97 }
98
99
CCgiIbuffer(FCGX_Stream * in)100 CCgiIbuffer::CCgiIbuffer(FCGX_Stream* in)
101 : m_in(in), m_cnt(0)
102 {
103 if (!m_in || !m_in->isReader) {
104 THROW1_TRACE(runtime_error, "CCgiObuffer: in is not reader");
105 }
106
107 x_Setg();
108 }
109
110
x_Setg(void)111 void CCgiIbuffer::x_Setg(void)
112 {
113 m_cnt += m_in->stop - m_in->rdNext;
114 setg((CT_CHAR_TYPE*) m_in->stopUnget,
115 (CT_CHAR_TYPE*) m_in->rdNext, (CT_CHAR_TYPE*) m_in->stop);
116 }
117
118
underflow(void)119 CT_INT_TYPE CCgiIbuffer::underflow(void)
120 {
121 _ASSERT(m_in->stop == (unsigned char*) egptr());
122 m_in->rdNext = (unsigned char*) gptr();
123
124 if (m_in->rdNext == m_in->stop) {
125 if (m_in->isClosed || !m_in->fillBuffProc) {
126 return CT_EOF;
127 }
128
129 m_in->fillBuffProc(m_in);
130 if (m_in->rdNext == m_in->stop) {
131 if ( !m_in->isClosed ) {
132 THROW1_TRACE(runtime_error,
133 "CCgiIbuffer::underflow: error in fillBuffProc");
134 }
135 return CT_EOF;
136 }
137
138 m_in->stopUnget = m_in->rdNext;
139 x_Setg();
140 }
141
142 return sgetc();
143 }
144
145
146 END_NCBI_SCOPE
147