|
NCBI Home IEB Home C++ Toolkit docs C Toolkit source browser C Toolkit source browser (2) |
NCBI C++ Toolkit Cross ReferenceC++/src/util/transmissionrw.cpp |
source navigation diff markup identifier search freetext search file search |
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 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |