~ubuntu-branches/ubuntu/wily/afnix/wily

« back to all changes in this revision

Viewing changes to src/mod/net/shl/TcpSocket.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2011-03-16 21:31:18 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110316213118-gk4k3ez3e5d2huna
Tags: 2.0.0-1
* QA upload.
* New upstream release
* Debian source format is 3.0 (quilt)
* Fix debhelper-but-no-misc-depends
* Fix ancient-standards-version
* Fix package-contains-linda-override
* debhelper compatibility is 7
* Fix dh-clean-k-is-deprecated

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
// - the copyright holder be liable for any  direct, indirect, incidental or -
12
12
// - special damages arising in any way out of the use of this software.     -
13
13
// ---------------------------------------------------------------------------
14
 
// - copyright (c) 1999-2007 amaury darsch                                   -
 
14
// - copyright (c) 1999-2011 amaury darsch                                   -
15
15
// ---------------------------------------------------------------------------
16
16
 
17
17
#include "Ascii.hpp"
60
60
    return "TcpSocket";
61
61
  }
62
62
 
 
63
  // return true if the eos flag is set
 
64
 
 
65
  bool TcpSocket::iseos (void) const {
 
66
    wrlock ();
 
67
    try {
 
68
      if (d_sbuf.length () != 0) {
 
69
        unlock ();
 
70
        return false;
 
71
      }
 
72
      // check if we can read one character
 
73
      bool status = c_rdwait (d_sid, 0);
 
74
      if (status == false) {
 
75
        unlock ();
 
76
        return false;
 
77
      }
 
78
      // read in the character - might be the eos
 
79
      char c = nilc;
 
80
      if (c_read (d_sid, &c, 1) <= 0) {
 
81
        unlock ();
 
82
        return true;
 
83
      }
 
84
      d_sbuf.pushback (c);
 
85
      unlock ();
 
86
      return false;
 
87
    } catch (...) {
 
88
      unlock ();
 
89
      throw;
 
90
    }
 
91
  }
 
92
 
 
93
  // check if we can read one character
 
94
 
 
95
  bool TcpSocket::valid (void) const {
 
96
    wrlock ();
 
97
    try {
 
98
      if (d_sbuf.length () != 0) {
 
99
        unlock ();
 
100
        return true;
 
101
      }
 
102
      // check if we can read one character
 
103
      bool status = c_rdwait (d_sid, d_tout);
 
104
      if (status == false) {
 
105
        unlock ();
 
106
        return false;
 
107
      }
 
108
      // read in the character - might be the eos
 
109
      char c = nilc;
 
110
      if (c_read (d_sid, &c, 1) <= 0) {
 
111
        unlock ();
 
112
        return false;
 
113
      }
 
114
      d_sbuf.pushback (c);
 
115
      unlock ();
 
116
      return true;
 
117
    } catch (...) {
 
118
      unlock ();
 
119
      throw;
 
120
    }
 
121
  }
 
122
 
63
123
  // read one character from the socket
64
124
 
65
125
  char TcpSocket::read (void) {
66
126
    wrlock ();
67
127
    try {
68
128
      // check if we can read a character
69
 
      if (valid (-1) == false) return eofc;
 
129
      if (valid () == false) {
 
130
        unlock ();
 
131
        return eosc;
 
132
      }
70
133
      // check the pushback buffer first
71
 
      if (d_buffer.length () != 0) {
72
 
        long result = d_buffer.read ();
 
134
      if (d_sbuf.empty () == false) {
 
135
        char result = d_sbuf.read ();
73
136
        unlock ();
74
137
        return result;
75
138
      }
76
 
      // read the next character
 
139
      // read the next character in case valid
 
140
      // does not push a character (safety code only)
77
141
      char c = nilc;
78
142
      long count = 0;
79
143
      if ((count = c_read (d_sid, &c, 1)) < 0) {
80
144
        throw Exception ("read-error", c_errmsg (count));
81
145
      }
82
 
      // check for eof
83
 
      if (count == 0) return eofc;
 
146
      // check for eos
 
147
      if (count == 0) c = eosc;
84
148
      unlock ();
85
149
      return c;
86
150
    } catch (...) {
89
153
    }
90
154
  }
91
155
 
 
156
  // copy the tcp socket into a buffer
 
157
 
 
158
  long TcpSocket::copy (char* rbuf, const long size) {
 
159
    // check argument first
 
160
    if ((rbuf == nilp) || (size <= 0)) return 0;
 
161
    // lock and fill
 
162
    wrlock ();
 
163
    try {
 
164
      // initialize result
 
165
      long result = 0;
 
166
      // check the pushback buffer first
 
167
      for (long i = 0; i < size; i++) {
 
168
        if (d_sbuf.empty () == true) break;
 
169
        rbuf[i] = d_sbuf.read ();
 
170
        result++;
 
171
      }
 
172
      if (result == size) {
 
173
        unlock ();
 
174
        return result;
 
175
      }
 
176
      // check if we can read one character
 
177
      bool status = c_rdwait (d_sid, d_tout);
 
178
      if (status == false) {
 
179
        unlock ();
 
180
        return result;
 
181
      }
 
182
      // read by block
 
183
      long count = 0;
 
184
      if ((count = c_read (d_sid, &rbuf[result], size-result)) < 0) {
 
185
        throw Exception ("read-error", c_errmsg (count));
 
186
      }
 
187
      result+= count;
 
188
      unlock ();
 
189
      return result;
 
190
    } catch (...) {
 
191
      unlock ();
 
192
      throw;
 
193
    }
 
194
  }
 
195
 
92
196
  // write one character to the socket
93
197
  
94
 
  void TcpSocket::write (const char value) {
95
 
    wrlock ();
96
 
    long count = c_write (d_sid, &value, 1);
97
 
    unlock ();
98
 
    if (count < 0) throw Exception ("write-error", c_errmsg (count));
99
 
  }
100
 
 
101
 
  // write a character string to the socket
102
 
 
103
 
  void TcpSocket::write (const char* value) {
104
 
    long size = Ascii::strlen (value);
105
 
    if (size == 0) return;
106
 
    wrlock ();
107
 
    long count = c_write (d_sid, value, size);
108
 
    unlock ();
109
 
    if (count < 0) throw Exception ("write-error", c_errmsg (count));
110
 
  }
111
 
 
112
 
  // return true if the eof flag is set
113
 
 
114
 
  bool TcpSocket::iseof (void) const {
115
 
    wrlock ();
116
 
    try {
117
 
      if (d_buffer.length () != 0) {
118
 
        unlock ();
119
 
        return false;
120
 
      }
121
 
      // check if we can read one character
122
 
      bool status = c_rdwait (d_sid, 0);
123
 
      if (status == false) {
124
 
        unlock ();
125
 
        return false;
126
 
      }
127
 
      // read in the character - might be the eof
128
 
      char c = nilc;
129
 
      if (c_read (d_sid, &c, 1) <= 0) {
130
 
        unlock ();
131
 
        return true;
132
 
      }
133
 
      d_buffer.pushback (c);
134
 
      unlock ();
135
 
      return false;
136
 
    } catch (...) {
137
 
      unlock ();
138
 
      throw;
139
 
    }
140
 
  }
141
 
 
142
 
  // check if we can read one character
143
 
 
144
 
  bool TcpSocket::valid (const long tout) const {
145
 
    wrlock ();
146
 
    try {
147
 
      if (d_buffer.length () != 0) {
148
 
        unlock ();
149
 
        return true;
150
 
      }
151
 
      // check if we can read one character
152
 
      bool status = c_rdwait (d_sid, tout);
153
 
      if (status == false) {
154
 
        unlock ();
155
 
        return false;
156
 
      }
157
 
      // read in the character - might be the eof
158
 
      char c = nilc;
159
 
      if (c_read (d_sid, &c, 1) <= 0) {
160
 
        unlock ();
161
 
        return false;
162
 
      }
163
 
      d_buffer.pushback (c);
164
 
      unlock ();
165
 
      return true;
 
198
  long TcpSocket::write (const char value) {
 
199
    wrlock ();
 
200
    try {
 
201
      long result = c_write (d_sid, &value, 1);
 
202
      if (result < 0) throw Exception ("write-error", c_errmsg (result));
 
203
      unlock ();
 
204
      return result;
 
205
    } catch (...) {
 
206
      unlock ();
 
207
      throw;
 
208
    }
 
209
  }
 
210
 
 
211
  // write a data buffer to the socket
 
212
 
 
213
  long TcpSocket::write (const char* data) {
 
214
    // lock and write
 
215
    wrlock ();
 
216
    try {
 
217
      // check for size first
 
218
      long size = Ascii::strlen (data);
 
219
      if (size == 0) {
 
220
        unlock ();
 
221
        return 0;
 
222
      }
 
223
      long result = c_write (d_sid, data, size);
 
224
      if (result < 0) throw Exception ("write-error", c_errmsg (result));
 
225
      unlock ();
 
226
      return result;
 
227
    } catch (...) {
 
228
      unlock ();
 
229
      throw;
 
230
    }
 
231
  }
 
232
 
 
233
  // write a character array to the socket
 
234
 
 
235
  long TcpSocket::write (const char* rbuf, const long size) {
 
236
    // check argument first
 
237
    if ((rbuf == nilp) || (size <= 0)) return 0;
 
238
    // lock and write
 
239
    wrlock ();
 
240
    try {
 
241
      long result = 0;
 
242
      while (result != size) {
 
243
        long count = c_write (d_sid, &rbuf[result], size-result);
 
244
        if (count < 0) throw Exception ("write-error", c_errmsg (result));
 
245
        if (count == 0) break;
 
246
        result += count;
 
247
      }
 
248
      unlock ();
 
249
      return result;
166
250
    } catch (...) {
167
251
      unlock ();
168
252
      throw;
178
262
        throw Exception ("tcp-error", "tcp socket already created");
179
263
      }
180
264
      d_sid = c_ipsocktcp (addr.p_addr);
181
 
      if (d_sid < 0) throw Exception ("tcp-error", c_errmsg (d_sid));
 
265
      if (d_sid < 0) {
 
266
        throw Exception ("tcp-error", c_errmsg (d_sid));
 
267
      }
 
268
      unlock ();
182
269
    } catch (...) {
183
270
      unlock ();
184
271
      throw;
187
274
 
188
275
  bool TcpSocket::listen (const long backlog) const {
189
276
    rdlock ();
190
 
    bool result = c_iplisten (d_sid, backlog);
191
 
    unlock ();
192
 
    return result;
 
277
    try {
 
278
      bool result = c_iplisten (d_sid, backlog);
 
279
      unlock ();
 
280
      return result;
 
281
    } catch (...) {
 
282
      unlock ();
 
283
      throw;
 
284
    }
193
285
  }
194
286
 
195
287
  // accept a connection from this tcp socket
196
288
 
197
289
  TcpSocket* TcpSocket::accept (void) const {
198
290
    rdlock ();
199
 
    int sid = c_ipaccept (d_sid);
200
 
    if (sid < 0) {
201
 
      unlock ();
202
 
      throw Exception ("accept-error", c_errmsg (sid));
 
291
    try {
 
292
      int sid = c_ipaccept (d_sid);
 
293
      if (sid < 0) throw Exception ("accept-error", c_errmsg (sid));
 
294
      TcpSocket* result = new TcpSocket (sid);
 
295
      unlock ();
 
296
      return result;
 
297
    } catch (...) {
 
298
      unlock ();
 
299
      throw;
203
300
    }
204
 
    TcpSocket* result = new TcpSocket (sid);
205
 
    unlock ();
206
 
    return result;
207
301
  }
208
302
 
209
303
  // -------------------------------------------------------------------------
248
342
    // dispatch 1 argument
249
343
    if (argc == 1) {
250
344
      if (quark == QUARK_LISTEN) {
251
 
        long backlog = argv->getint (0);
 
345
        long backlog = argv->getlong (0);
252
346
        return new Boolean (listen (backlog));
253
347
      }
254
348
    }