source: xplcommon/src/xplcommon/BlockingStream.cc@ 30:1dde7e03353f

Last change on this file since 30:1dde7e03353f was 30:1dde7e03353f, checked in by István Váradi <ivaradi@…>, 11 years ago

A little cleanup

File size: 4.9 KB
Line 
1// Copyright (c) 2013 by István Váradi
2
3// This file is part of libxplcommon, a common utility library for
4// development related to X-Plane
5
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are met:
8
9// 1. Redistributions of source code must retain the above copyright notice, this
10// list of conditions and the following disclaimer.
11// 2. Redistributions in binary form must reproduce the above copyright notice,
12// this list of conditions and the following disclaimer in the documentation
13// and/or other materials provided with the distribution.
14
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26// The views and conclusions contained in the software and documentation are those
27// of the authors and should not be interpreted as representing official policies,
28// either expressed or implied, of the FreeBSD Project.
29
30//------------------------------------------------------------------------------
31
32#include "BlockingStream.h"
33
34#include "ReadingBuffer.h"
35#include "WritingBuffer.h"
36
37#include <cstring>
38#include <cstdio>
39
40//------------------------------------------------------------------------------
41
42using xplcommon::BlockingStream;
43
44using std::min;
45
46//------------------------------------------------------------------------------
47
48bool BlockingStream::isInterrupted()
49{
50 if (failed()) return false;
51
52 if (!interrupted) {
53 interrupted = event.check();
54 if (!interrupted && event.failed()) {
55 setErrorCode(event.getErrorCode());
56 }
57 }
58
59 return interrupted;
60}
61
62//------------------------------------------------------------------------------
63
64bool BlockingStream::read(void* dest, size_t length)
65{
66 unsigned char* d = reinterpret_cast<unsigned char*>(dest);
67
68 ReadingBuffer& readingBuffer = stream.getReadingBuffer();
69 while (length>0) {
70 size_t copied = readingBuffer.extract(d, length, readingOffset);
71 readingOffset += copied;
72 length -= copied;
73 d += copied;
74
75 if (length!=0) {
76 if (!fill()) return false;
77 }
78 }
79
80 return true;
81}
82
83//------------------------------------------------------------------------------
84
85bool BlockingStream::write(const void* src, size_t length)
86{
87 const unsigned char* s = reinterpret_cast<const unsigned char*>(src);
88
89 WritingBuffer& writingBuffer = stream.getWritingBuffer();
90 while(length>0) {
91 size_t copied = writingBuffer.append(s, length);
92 length -= copied;
93 s += copied;
94
95 if (length==0) break;
96 if (!flush()) return false;
97 }
98
99 return true;
100}
101
102//------------------------------------------------------------------------------
103
104bool BlockingStream::flush()
105{
106 WritingBuffer& writingBuffer = stream.getWritingBuffer();
107 while (!failed()) {
108 if (isInterrupted()) return false;
109
110 if (writingBuffer.write()) {
111 return true;
112 } else if (writingBuffer.failed()) {
113 setErrorCode(writingBuffer.getErrorCode());
114 return false;
115 } else {
116 Waiter* waiter = stream.getWaiter();
117 waiter->wait();
118 if (waiter->failed()) {
119 setErrorCode(waiter->getErrorCode());
120 }
121 }
122 }
123 return false;
124}
125
126//------------------------------------------------------------------------------
127
128bool BlockingStream::fill()
129{
130 ReadingBuffer& readingBuffer = stream.getReadingBuffer();
131
132 readingBuffer.reset();
133 readingOffset = 0;
134 while (true) {
135 if (isInterrupted()) return false;
136
137 if (readingBuffer.read()) {
138 return !readingBuffer.isEmpty();
139 } else if (readingBuffer.failed()) {
140 setErrorCode(readingBuffer.getErrorCode());
141 return false;
142 } else {
143 Waiter* waiter = stream.getWaiter();
144 waiter->wait();
145 if (waiter->failed()) {
146 setErrorCode(waiter->getErrorCode());
147 return false;
148 }
149 }
150 }
151}
152
153//------------------------------------------------------------------------------
154
155// Local Variables:
156// mode: C++
157// c-basic-offset: 4
158// indent-tabs-mode: nil
159// End:
Note: See TracBrowser for help on using the repository browser.