NCBI C++ Toolkit Cross Reference

C++/src/util/transmissionrw.cpp


  1 /*  $Id: transmissionrw.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: Anatoliy Kuznetsov
 27  *
 28  * File Description:  Transmission control.
 29  *
 30  */
 31 
 32 #include <ncbi_pch.hpp>
 33 #include <corelib/ncbidbg.hpp>
 34 #include <corelib/ncbi_bswap.hpp>
 35 #include <corelib/ncbistr.hpp>
 36 #include <util/util_exception.hpp>
 37 #include <util/transmissionrw.hpp>
 38 
 39 BEGIN_NCBI_SCOPE
 40 
 41 static const Uint4 sStartWord = 0x01020304;
 42 static const Uint4 sEndPacket = 0xFFFFFFFF;
 43 
 44 CTransmissionWriter::CTransmissionWriter(IWriter* wrt, 
 45                                          EOwnership own_writer,
 46                                          ESendEofPacket send_eof)
 47     : m_Wrt(wrt),
 48       m_OwnWrt(own_writer),
 49       m_SendEof(send_eof)
 50 {
 51     _ASSERT(wrt);
 52 
 53     size_t written;
 54     ERW_Result res = m_Wrt->Write(&sStartWord, sizeof(sStartWord), &written);
 55     if (res != eRW_Success || written != sizeof(sStartWord)) {
 56         NCBI_THROW(CIOException, eWrite,  "Cannot write the byte order");
 57     }
 58 }
 59 
 60 
 61 CTransmissionWriter::~CTransmissionWriter()
 62 {
 63     if (m_SendEof == eSendEofPacket) {
 64         m_Wrt->Write(&sEndPacket, sizeof(sEndPacket));       
 65     }
 66     if (m_OwnWrt) {
 67         delete m_Wrt;
 68     }
 69 }
 70 
 71 namespace {
 72 class CIOBytesCountGuard 
 73 {
 74 public:
 75     CIOBytesCountGuard(size_t* ret, const size_t& count)
 76         : m_Ret(ret), m_Count(count) 
 77     {}
 78 
 79     ~CIOBytesCountGuard() { if (m_Ret) *m_Ret = m_Count; }
 80 private:
 81     size_t* m_Ret;
 82     const size_t& m_Count;
 83 };
 84 } // namespace
 85 
 86 ERW_Result CTransmissionWriter::Write(const void* buf,
 87                                       size_t      count,
 88                                       size_t*     bytes_written)
 89 {
 90     ERW_Result res;
 91     size_t wrt_count = 0;
 92     CIOBytesCountGuard guard(bytes_written, wrt_count);
 93 
 94     if(count == sEndPacket) {
 95         const char* b = (const char*)buf;
 96         size_t cnt = count / 2;
 97         res = x_WritePacket(b, cnt, wrt_count);
 98         if (res != eRW_Success)
 99             return res;
100         size_t wrt_count1 = 0;
101         res = x_WritePacket(b+cnt, count - cnt, wrt_count1);
102         wrt_count += wrt_count1;
103         return res;
104     }
105     return x_WritePacket(buf, count, wrt_count);
106 }
107 
108 ERW_Result CTransmissionWriter::x_WritePacket(const void* buf,
109                                               size_t      count,
110                                               size_t&     bytes_written)
111 {
112     bytes_written = 0;
113     Uint4 cnt = (Uint4)count;
114     size_t written = 0;
115     ERW_Result res = m_Wrt->Write(&cnt, sizeof(cnt), &written);
116     if (res != eRW_Success) 
117         return res;
118     if (written != sizeof(cnt))
119         return eRW_Error;
120     for (const char* ptr = (char*)buf; count > 0; ptr += written) {
121         res = m_Wrt->Write(ptr, count, &written);
122         if (res != eRW_Success) 
123                 return res;
124         count -= written;
125         bytes_written += written;
126     }
127     return res;
128 }
129 
130 ERW_Result CTransmissionWriter::Flush(void)
131 {
132     return m_Wrt->Flush();
133 }
134 
135 
136 
137 CTransmissionReader::CTransmissionReader(IReader* rdr, EOwnership own_reader)
138     : m_Rdr(rdr),
139       m_OwnRdr(own_reader),
140       m_PacketBytesToRead(0),
141       m_ByteSwap(false),
142       m_StartRead(false)
143 {
144     return;
145 }
146 
147 
148 CTransmissionReader::~CTransmissionReader()
149 {
150     if (m_OwnRdr) {
151         delete m_Rdr;
152     }
153 }
154 
155 
156 ERW_Result CTransmissionReader::Read(void*    buf,
157                                      size_t   count,
158                                      size_t*  bytes_read)
159 {
160     ERW_Result res;
161     size_t read_count = 0;
162     CIOBytesCountGuard guard(bytes_read, read_count);
163 
164     if (!m_StartRead) {
165         res = x_ReadStart();
166         if (res != eRW_Success) {
167             return res;
168         }
169     }
170 
171     // read packet header
172     while (m_PacketBytesToRead == 0) {
173         Uint4 cnt;
174         res = x_ReadRepeated(&cnt, sizeof(cnt));
175         if (res != eRW_Success) { 
176             return res;
177         }
178         if (m_ByteSwap) {
179             m_PacketBytesToRead = CByteSwap::GetInt4((unsigned char*)&cnt);
180         } else {
181             m_PacketBytesToRead = cnt;
182         }
183     }
184 
185     if (m_PacketBytesToRead == sEndPacket) 
186         return  eRW_Eof;
187 
188     size_t to_read = min(count, m_PacketBytesToRead);
189 
190     res = m_Rdr->Read(buf, to_read, &read_count);
191     m_PacketBytesToRead -= read_count;
192 
193     return res;
194 }
195 
196 
197 ERW_Result CTransmissionReader::PendingCount(size_t* count)
198 {
199     return m_Rdr->PendingCount(count);
200 }
201 
202 
203 ERW_Result CTransmissionReader::x_ReadStart()
204 {
205     _ASSERT(!m_StartRead);
206 
207     m_StartRead = true;
208 
209     ERW_Result res;
210     unsigned start_word_coming;
211 
212     res = x_ReadRepeated(&start_word_coming, sizeof(start_word_coming));
213     if (res != eRW_Success) {
214         return res;
215     }
216     m_ByteSwap = (start_word_coming != sStartWord);
217 
218     //    _ASSERT(start_word_coming == 0x01020304 || 
219     //            start_word_coming == 0x04030201);
220 
221     if (start_word_coming != sStartWord &&
222         start_word_coming != 0x04030201)
223         NCBI_THROW(CUtilException, eWrongData,
224                    "Cannot determine the byte order. Got: " 
225                    + NStr::UIntToString(start_word_coming, 0, 16));
226 
227     return res;
228 }
229 
230 
231 ERW_Result CTransmissionReader::x_ReadRepeated(void* buf, size_t count)
232 {
233     ERW_Result res = eRW_Success;
234     char* ptr = (char*)buf;
235     size_t read;
236     
237     for( ; count > 0; count -= read, ptr += read) {
238         res = m_Rdr->Read(ptr, count, &read);
239         if (res != eRW_Success) {
240             return res;
241        }
242     }
243     return res;
244 }
245 
246 
247 END_NCBI_SCOPE
248 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.