hybridgroup-serialport 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,103 @@
1
+ /* Ruby/SerialPort
2
+ * Guillaume Pierronnet <moumar@netcourrier.com>
3
+ * Alan Stern <stern@rowland.harvard.edu>
4
+ * Daniel E. Shipton <dshipton@redshiptechnologies.com>
5
+ * Tobin Richard <tobin.richard@gmail.com>
6
+ * Ryan C. Payne <rpayne-oss@bullittsystems.com>
7
+ *
8
+ * This code is hereby licensed for public consumption under either the
9
+ * GNU GPL v2 or greater.
10
+ *
11
+ * You should have received a copy of the GNU General Public License
12
+ * along with this program; if not, write to the Free Software
13
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14
+ *
15
+ * For documentation on serial programming, see the excellent:
16
+ * "Serial Programming Guide for POSIX Operating Systems"
17
+ * written Michael R. Sweet.
18
+ * http://www.easysw.com/~mike/serial/
19
+ */
20
+
21
+ #ifndef _RUBY_SERIAL_PORT_H_
22
+ #define _RUBY_SERIAL_PORT_H_
23
+
24
+ #define RUBY_SERIAL_PORT_VERSION "1.0.4"
25
+
26
+ #include <ruby.h> /* ruby inclusion */
27
+ #ifdef HAVE_RUBY_IO_H /* ruby io inclusion */
28
+ #include <ruby/io.h>
29
+ #else
30
+ #include <rubyio.h>
31
+ #endif
32
+
33
+ struct modem_params
34
+ {
35
+ int data_rate;
36
+ int data_bits;
37
+ int stop_bits;
38
+ int parity;
39
+ };
40
+
41
+ struct line_signals
42
+ {
43
+ int rts;
44
+ int dtr;
45
+ int cts;
46
+ int dsr;
47
+ int dcd;
48
+ int ri;
49
+ };
50
+
51
+ #define NONE 0
52
+ #define HARD 1
53
+ #define SOFT 2
54
+
55
+ #if defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW)
56
+ #define SPACE SPACEPARITY
57
+ #define MARK MARKPARITY
58
+ #define EVEN EVENPARITY
59
+ #define ODD ODDPARITY
60
+
61
+ #ifndef RB_SERIAL_EXPORT
62
+ #ifndef HAVE_RUBY_IO_H
63
+ #define RB_SERIAL_EXPORT __declspec(dllexport)
64
+ #else
65
+ #define RB_SERIAL_EXPORT
66
+ #endif
67
+ #endif
68
+
69
+ #else
70
+ #define SPACE 0
71
+ #define MARK 0
72
+ #define EVEN 1
73
+ #define ODD 2
74
+
75
+ #define RB_SERIAL_EXPORT
76
+ #endif
77
+
78
+ extern VALUE sBaud, sDataBits, sStopBits, sParity; /* strings */
79
+ extern VALUE sRts, sDtr, sCts, sDsr, sDcd, sRi;
80
+
81
+ /* Implementation specific functions. */
82
+ VALUE RB_SERIAL_EXPORT sp_create_impl(VALUE class, VALUE _port);
83
+ VALUE RB_SERIAL_EXPORT sp_set_modem_params_impl(int argc, VALUE *argv, VALUE self);
84
+ void RB_SERIAL_EXPORT get_modem_params_impl(VALUE self, struct modem_params *mp);
85
+ VALUE RB_SERIAL_EXPORT sp_set_flow_control_impl(VALUE self, VALUE val);
86
+ VALUE RB_SERIAL_EXPORT sp_get_flow_control_impl(VALUE self);
87
+ VALUE RB_SERIAL_EXPORT sp_set_read_timeout_impl(VALUE self, VALUE val);
88
+ VALUE RB_SERIAL_EXPORT sp_get_read_timeout_impl(VALUE self);
89
+ VALUE RB_SERIAL_EXPORT sp_set_write_timeout_impl(VALUE self, VALUE val);
90
+ VALUE RB_SERIAL_EXPORT sp_get_write_timeout_impl(VALUE self);
91
+ VALUE RB_SERIAL_EXPORT sp_break_impl(VALUE self, VALUE time);
92
+ void RB_SERIAL_EXPORT get_line_signals_helper_impl(VALUE obj, struct line_signals *ls);
93
+ VALUE RB_SERIAL_EXPORT set_signal_impl(VALUE obj, VALUE val, int sig);
94
+ VALUE RB_SERIAL_EXPORT sp_set_rts_impl(VALUE self, VALUE val);
95
+ VALUE RB_SERIAL_EXPORT sp_set_dtr_impl(VALUE self, VALUE val);
96
+ VALUE RB_SERIAL_EXPORT sp_get_rts_impl(VALUE self);
97
+ VALUE RB_SERIAL_EXPORT sp_get_dtr_impl(VALUE self);
98
+ VALUE RB_SERIAL_EXPORT sp_write_impl(VALUE self, VALUE str);
99
+ VALUE RB_SERIAL_EXPORT sp_read_impl(int argc, VALUE *argv, VALUE self);
100
+ void RB_SERIAL_EXPORT sp_close_impl(VALUE self);
101
+ void RB_SERIAL_EXPORT sp_set_initial_byte_offset_impl(VALUE self, VALUE offset);
102
+
103
+ #endif
@@ -0,0 +1,652 @@
1
+ /* Ruby/SerialPort
2
+ * Guillaume Pierronnet <moumar@netcourrier.com>
3
+ * Alan Stern <stern@rowland.harvard.edu>
4
+ * Daniel E. Shipton <dshipton@redshiptechnologies.com>
5
+ * Hector G. Parra <hector@hectorparra.com>
6
+ *
7
+ * This code is hereby licensed for public consumption under either the
8
+ * GNU GPL v2 or greater.
9
+ *
10
+ * You should have received a copy of the GNU General Public License
11
+ * along with this program; if not, write to the Free Software
12
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
13
+ *
14
+ * For documentation on serial programming, see the excellent:
15
+ * "Serial Programming Guide for POSIX Operating Systems"
16
+ * written Michael R. Sweet.
17
+ * http://www.easysw.com/~mike/serial/
18
+ */
19
+
20
+ #include "serialport.h"
21
+
22
+ #if defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW)
23
+
24
+ #include <stdio.h> /* Standard input/output definitions */
25
+ #include <io.h> /* Low-level I/O definitions */
26
+ #include <fcntl.h> /* File control definitions */
27
+ #include <windows.h> /* Windows standard function definitions */
28
+
29
+
30
+ static char sGetCommState[] = "GetCommState";
31
+ static char sSetCommState[] = "SetCommState";
32
+ static char sGetCommTimeouts[] = "GetCommTimeouts";
33
+ static char sSetCommTimeouts[] = "SetCommTimeouts";
34
+
35
+
36
+ static HANDLE get_handle_helper(obj)
37
+ VALUE obj;
38
+ {
39
+ return rb_iv_get(obj,"@@fh");
40
+ }
41
+
42
+ /* hack to work around the fact that Ruby doesn't use GetLastError? */
43
+ static void _rb_win32_fail(const char *function_call) {
44
+ rb_raise(
45
+ rb_eRuntimeError,
46
+ "%s failed: GetLastError returns %d",
47
+ function_call, GetLastError( )
48
+ );
49
+ }
50
+
51
+ VALUE RB_SERIAL_EXPORT sp_create_impl(class, _port)
52
+ VALUE class, _port;
53
+ {
54
+ int fd;
55
+ HANDLE fh;
56
+ int num_port;
57
+ char *str_port;
58
+ char port[260]; /* Windows XP MAX_PATH. See http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx */
59
+
60
+ DCB dcb;
61
+
62
+ NEWOBJ(sp, struct RObject);
63
+ rb_secure(4);
64
+ OBJSETUP(sp, class, T_OBJECT);
65
+
66
+ switch(TYPE(_port))
67
+ {
68
+ case T_FIXNUM:
69
+ num_port = FIX2INT(_port);
70
+ if (num_port < 0)
71
+ {
72
+ rb_raise(rb_eArgError, "illegal port number");
73
+ }
74
+ snprintf(port, sizeof(port) - 1, "\\\\.\\COM%d", num_port + 1); /* '0' is actually COM1, etc. */
75
+ port[sizeof(port) - 1] = 0;
76
+ break;
77
+
78
+ case T_STRING:
79
+ Check_SafeStr(_port);
80
+ str_port = RSTRING_PTR(_port);
81
+ if (str_port[0] != '\\') /* Check for Win32 Device Namespace prefix "\\.\" */
82
+ {
83
+ snprintf(port, sizeof(port) - 1, "\\\\.\\%s", str_port);
84
+ port[sizeof(port) - 1] = 0;
85
+ }
86
+ else
87
+ {
88
+ snprintf(port, sizeof(port) - 1, "%s", str_port);
89
+ port[sizeof(port) - 1] = 0;
90
+ }
91
+ break;
92
+
93
+ default:
94
+ rb_raise(rb_eTypeError, "wrong argument type");
95
+ break;
96
+ }
97
+
98
+ fh = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
99
+ rb_iv_set(sp,"@@fh",fh);
100
+
101
+ if (fh == INVALID_HANDLE_VALUE){
102
+ CloseHandle(fh);
103
+ rb_sys_fail(port);
104
+ }
105
+
106
+ if (SetupComm(fh, 1024, 1024) == 0)
107
+ {
108
+ CloseHandle(fh);
109
+ rb_raise(rb_eArgError, "not a serial port");
110
+ }
111
+
112
+ dcb.DCBlength = sizeof(dcb);
113
+ if (GetCommState(fh, &dcb) == 0)
114
+ {
115
+ CloseHandle(fh);
116
+ _rb_win32_fail(sGetCommState);
117
+ }
118
+ dcb.fBinary = TRUE;
119
+ dcb.fParity = FALSE;
120
+ dcb.fOutxDsrFlow = FALSE;
121
+ dcb.fDtrControl = DTR_CONTROL_ENABLE;
122
+ dcb.fDsrSensitivity = FALSE;
123
+ dcb.fTXContinueOnXoff = FALSE;
124
+ dcb.fErrorChar = FALSE;
125
+ dcb.fNull = FALSE;
126
+ dcb.fAbortOnError = FALSE;
127
+ dcb.XonChar = 17;
128
+ dcb.XoffChar = 19;
129
+ if (SetCommState(fh, &dcb) == 0)
130
+ {
131
+ CloseHandle(fh);
132
+ _rb_win32_fail(sSetCommState);
133
+ }
134
+
135
+ errno = 0;
136
+ return (VALUE) sp;
137
+ }
138
+
139
+ VALUE RB_SERIAL_EXPORT sp_set_modem_params_impl(argc, argv, self)
140
+ int argc;
141
+ VALUE *argv, self;
142
+ {
143
+ HANDLE fh;
144
+ DCB dcb;
145
+ VALUE _data_rate, _data_bits, _parity, _stop_bits;
146
+ int use_hash = 0;
147
+ int data_rate, data_bits, parity;
148
+
149
+ if (argc == 0)
150
+ {
151
+ return self;
152
+ }
153
+ if (argc == 1 && T_HASH == TYPE(argv[0]))
154
+ {
155
+ use_hash = 1;
156
+ _data_rate = rb_hash_aref(argv[0], sBaud);
157
+ _data_bits = rb_hash_aref(argv[0], sDataBits);
158
+ _stop_bits = rb_hash_aref(argv[0], sStopBits);
159
+ _parity = rb_hash_aref(argv[0], sParity);
160
+ }
161
+
162
+ fh = get_handle_helper(self);
163
+ dcb.DCBlength = sizeof(dcb);
164
+ if (GetCommState(fh, &dcb) == 0)
165
+ {
166
+ _rb_win32_fail(sGetCommState);
167
+ }
168
+
169
+ if (!use_hash)
170
+ {
171
+ _data_rate = argv[0];
172
+ }
173
+
174
+ if (NIL_P(_data_rate))
175
+ {
176
+ goto SkipDataRate;
177
+ }
178
+
179
+ Check_Type(_data_rate, T_FIXNUM);
180
+
181
+ data_rate = FIX2INT(_data_rate);
182
+ dcb.BaudRate = data_rate;
183
+
184
+ SkipDataRate:
185
+
186
+ if (!use_hash)
187
+ {
188
+ _data_bits = (argc >= 2 ? argv[1] : INT2FIX(8));
189
+ }
190
+
191
+ if (NIL_P(_data_bits))
192
+ {
193
+ goto SkipDataBits;
194
+ }
195
+
196
+ Check_Type(_data_bits, T_FIXNUM);
197
+
198
+ data_bits = FIX2INT(_data_bits);
199
+ if (4 <= data_bits && data_bits <= 8)
200
+ {
201
+ dcb.ByteSize = data_bits;
202
+ }
203
+ else
204
+ {
205
+ rb_raise(rb_eArgError, "unknown character size");
206
+ }
207
+
208
+ SkipDataBits:
209
+
210
+ if (!use_hash)
211
+ {
212
+ _stop_bits = (argc >= 3 ? argv[2] : INT2FIX(1));
213
+ }
214
+
215
+ if (NIL_P(_stop_bits))
216
+ {
217
+ goto SkipStopBits;
218
+ }
219
+
220
+ Check_Type(_stop_bits, T_FIXNUM);
221
+
222
+ switch (FIX2INT(_stop_bits))
223
+ {
224
+ case 1:
225
+ dcb.StopBits = ONESTOPBIT;
226
+ break;
227
+ case 2:
228
+ dcb.StopBits = TWOSTOPBITS;
229
+ break;
230
+ default:
231
+ rb_raise(rb_eArgError, "unknown number of stop bits");
232
+ break;
233
+ }
234
+
235
+ SkipStopBits:
236
+
237
+ if (!use_hash)
238
+ {
239
+ _parity = (argc >= 4 ? argv[3] : (dcb.ByteSize == 8 ?
240
+ INT2FIX(NOPARITY) : INT2FIX(EVENPARITY)));
241
+ }
242
+
243
+ if (NIL_P(_parity))
244
+ {
245
+ goto SkipParity;
246
+ }
247
+
248
+ Check_Type(_parity, T_FIXNUM);
249
+
250
+ parity = FIX2INT(_parity);
251
+ switch (parity)
252
+ {
253
+ case EVENPARITY:
254
+ case ODDPARITY:
255
+ case MARKPARITY:
256
+ case SPACEPARITY:
257
+ case NOPARITY:
258
+ dcb.Parity = parity;
259
+ break;
260
+
261
+ default:
262
+ rb_raise(rb_eArgError, "unknown parity");
263
+ break;
264
+ }
265
+
266
+ SkipParity:
267
+
268
+ if (SetCommState(fh, &dcb) == 0)
269
+ {
270
+ _rb_win32_fail(sSetCommState);
271
+ }
272
+
273
+ return argv[0];
274
+ }
275
+
276
+ void RB_SERIAL_EXPORT get_modem_params_impl(self, mp)
277
+ VALUE self;
278
+ struct modem_params *mp;
279
+ {
280
+ HANDLE fh;
281
+ DCB dcb;
282
+
283
+ fh = get_handle_helper(self);
284
+ dcb.DCBlength = sizeof(dcb);
285
+ if (GetCommState(fh, &dcb) == 0)
286
+ {
287
+ _rb_win32_fail(sGetCommState);
288
+ }
289
+
290
+ mp->data_rate = dcb.BaudRate;
291
+ mp->data_bits = dcb.ByteSize;
292
+ mp->stop_bits = (dcb.StopBits == ONESTOPBIT ? 1 : 2);
293
+ mp->parity = dcb.Parity;
294
+ }
295
+
296
+ VALUE RB_SERIAL_EXPORT sp_set_flow_control_impl(self, val)
297
+ VALUE self, val;
298
+ {
299
+ HANDLE fh;
300
+ int flowc;
301
+ DCB dcb;
302
+
303
+ Check_Type(val, T_FIXNUM);
304
+
305
+ fh = get_handle_helper(self);
306
+ dcb.DCBlength = sizeof(dcb);
307
+ if (GetCommState(fh, &dcb) == 0)
308
+ {
309
+ _rb_win32_fail(sGetCommState);
310
+ }
311
+
312
+ flowc = FIX2INT(val);
313
+ if (flowc & HARD)
314
+ {
315
+ dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
316
+ dcb.fOutxCtsFlow = TRUE;
317
+ }
318
+ else
319
+ {
320
+ dcb.fRtsControl = RTS_CONTROL_ENABLE;
321
+ dcb.fOutxCtsFlow = FALSE;
322
+ }
323
+
324
+ if (flowc & SOFT)
325
+ {
326
+ dcb.fOutX = dcb.fInX = TRUE;
327
+ }
328
+ else
329
+ {
330
+ dcb.fOutX = dcb.fInX = FALSE;
331
+ }
332
+
333
+ if (SetCommState(fh, &dcb) == 0)
334
+ {
335
+ _rb_win32_fail(sSetCommState);
336
+ }
337
+
338
+ return val;
339
+ }
340
+
341
+ VALUE RB_SERIAL_EXPORT sp_get_flow_control_impl(self)
342
+ VALUE self;
343
+ {
344
+ HANDLE fh;
345
+ int ret;
346
+ DCB dcb;
347
+
348
+ fh = get_handle_helper(self);
349
+ dcb.DCBlength = sizeof(dcb);
350
+ if (GetCommState(fh, &dcb) == 0)
351
+ {
352
+ _rb_win32_fail(sGetCommState);
353
+ }
354
+
355
+ ret = 0;
356
+ if (dcb.fOutxCtsFlow)
357
+ {
358
+ ret += HARD;
359
+ }
360
+
361
+ if (dcb.fOutX)
362
+ {
363
+ ret += SOFT;
364
+ }
365
+
366
+ return INT2FIX(ret);
367
+ }
368
+
369
+ VALUE RB_SERIAL_EXPORT sp_set_read_timeout_impl(self, val)
370
+ VALUE self, val;
371
+ {
372
+ int timeout;
373
+ HANDLE fh;
374
+ COMMTIMEOUTS ctout;
375
+
376
+ Check_Type(val, T_FIXNUM);
377
+ timeout = FIX2INT(val);
378
+
379
+ fh = get_handle_helper(self);
380
+ if (GetCommTimeouts(fh, &ctout) == 0)
381
+ {
382
+ _rb_win32_fail(sGetCommTimeouts);
383
+ }
384
+
385
+ if (timeout < 0)
386
+ {
387
+ ctout.ReadIntervalTimeout = MAXDWORD;
388
+ ctout.ReadTotalTimeoutMultiplier = 0;
389
+ ctout.ReadTotalTimeoutConstant = 0;
390
+ }
391
+ else if (timeout == 0)
392
+ {
393
+ ctout.ReadIntervalTimeout = MAXDWORD;
394
+ ctout.ReadTotalTimeoutMultiplier = MAXDWORD;
395
+ ctout.ReadTotalTimeoutConstant = MAXDWORD - 1;
396
+ }
397
+ else
398
+ {
399
+ ctout.ReadIntervalTimeout = timeout;
400
+ ctout.ReadTotalTimeoutMultiplier = 0;
401
+ ctout.ReadTotalTimeoutConstant = timeout;
402
+ }
403
+
404
+ if (SetCommTimeouts(fh, &ctout) == 0)
405
+ {
406
+ _rb_win32_fail(sSetCommTimeouts);
407
+ }
408
+
409
+ return val;
410
+ }
411
+
412
+ VALUE RB_SERIAL_EXPORT sp_get_read_timeout_impl(self)
413
+ VALUE self;
414
+ {
415
+ HANDLE fh;
416
+ COMMTIMEOUTS ctout;
417
+
418
+ fh = get_handle_helper(self);
419
+ if (GetCommTimeouts(fh, &ctout) == 0)
420
+ {
421
+ _rb_win32_fail(sGetCommTimeouts);
422
+ }
423
+
424
+ switch (ctout.ReadTotalTimeoutConstant)
425
+ {
426
+ case 0:
427
+ return INT2FIX(-1);
428
+ case MAXDWORD:
429
+ return INT2FIX(0);
430
+ }
431
+
432
+ return INT2FIX(ctout.ReadTotalTimeoutConstant);
433
+ }
434
+
435
+ VALUE RB_SERIAL_EXPORT sp_set_write_timeout_impl(self, val)
436
+ VALUE self, val;
437
+ {
438
+ int timeout;
439
+ HANDLE fh;
440
+ COMMTIMEOUTS ctout;
441
+
442
+ Check_Type(val, T_FIXNUM);
443
+ timeout = FIX2INT(val);
444
+
445
+ fh = get_handle_helper(self);
446
+ if (GetCommTimeouts(fh, &ctout) == 0)
447
+ {
448
+ _rb_win32_fail(sGetCommTimeouts);
449
+ }
450
+
451
+ if (timeout <= 0)
452
+ {
453
+ ctout.WriteTotalTimeoutMultiplier = 0;
454
+ ctout.WriteTotalTimeoutConstant = 0;
455
+ }
456
+ else
457
+ {
458
+ ctout.WriteTotalTimeoutMultiplier = timeout;
459
+ ctout.WriteTotalTimeoutConstant = 0;
460
+ }
461
+
462
+ if (SetCommTimeouts(fh, &ctout) == 0)
463
+ {
464
+ _rb_win32_fail(sSetCommTimeouts);
465
+ }
466
+
467
+ return val;
468
+ }
469
+
470
+ VALUE RB_SERIAL_EXPORT sp_get_write_timeout_impl(self)
471
+ VALUE self;
472
+ {
473
+ HANDLE fh;
474
+ COMMTIMEOUTS ctout;
475
+
476
+ fh = get_handle_helper(self);
477
+ if (GetCommTimeouts(fh, &ctout) == 0)
478
+ {
479
+ _rb_win32_fail(sGetCommTimeouts);
480
+ }
481
+
482
+ return INT2FIX(ctout.WriteTotalTimeoutMultiplier);
483
+ }
484
+
485
+ static void delay_ms(time)
486
+ int time;
487
+ {
488
+ HANDLE ev;
489
+
490
+ ev = CreateEvent(NULL, FALSE, FALSE, NULL);
491
+ if (!ev)
492
+ {
493
+ _rb_win32_fail("CreateEvent");
494
+ }
495
+
496
+ if (WaitForSingleObject(ev, time) == WAIT_FAILED)
497
+ {
498
+ _rb_win32_fail("WaitForSingleObject");
499
+ }
500
+
501
+ CloseHandle(ev);
502
+ }
503
+
504
+ VALUE RB_SERIAL_EXPORT sp_break_impl(self, time)
505
+ VALUE self, time;
506
+ {
507
+ HANDLE fh;
508
+
509
+ Check_Type(time, T_FIXNUM);
510
+
511
+ fh = get_handle_helper(self);
512
+ if (SetCommBreak(fh) == 0)
513
+ {
514
+ _rb_win32_fail("SetCommBreak");
515
+ }
516
+
517
+ delay_ms(FIX2INT(time) * 100);
518
+ ClearCommBreak(fh);
519
+
520
+ return Qnil;
521
+ }
522
+
523
+ void RB_SERIAL_EXPORT get_line_signals_helper_impl(obj, ls)
524
+ VALUE obj;
525
+ struct line_signals *ls;
526
+ {
527
+ HANDLE fh;
528
+ unsigned long status; /* DWORD */
529
+
530
+ fh = get_handle_helper(obj);
531
+ if (GetCommModemStatus(fh, &status) == 0)
532
+ {
533
+ _rb_win32_fail("GetCommModemStatus");
534
+ }
535
+
536
+ ls->cts = (status & MS_CTS_ON ? 1 : 0);
537
+ ls->dsr = (status & MS_DSR_ON ? 1 : 0);
538
+ ls->dcd = (status & MS_RLSD_ON ? 1 : 0);
539
+ ls->ri = (status & MS_RING_ON ? 1 : 0);
540
+ }
541
+
542
+ static VALUE set_signal(obj, val, sigoff, sigon)
543
+ VALUE obj,val;
544
+ int sigoff, sigon;
545
+ {
546
+ HANDLE fh;
547
+ int set, sig;
548
+
549
+ Check_Type(val, T_FIXNUM);
550
+ fh = get_handle_helper(obj);
551
+
552
+ set = FIX2INT(val);
553
+ if (set == 0)
554
+ {
555
+ sig = sigoff;
556
+ }
557
+ else if (set == 1)
558
+ {
559
+ sig = sigon;
560
+ }
561
+ else
562
+ {
563
+ rb_raise(rb_eArgError, "invalid value");
564
+ }
565
+
566
+ if (EscapeCommFunction(fh, sig) == 0)
567
+ {
568
+ _rb_win32_fail("EscapeCommFunction");
569
+ }
570
+
571
+ return val;
572
+ }
573
+
574
+ VALUE RB_SERIAL_EXPORT sp_set_rts_impl(self, val)
575
+ VALUE self, val;
576
+ {
577
+ return set_signal(self, val, CLRRTS, SETRTS);
578
+ }
579
+
580
+ VALUE RB_SERIAL_EXPORT sp_set_dtr_impl(self, val)
581
+ VALUE self, val;
582
+ {
583
+ return set_signal(self, val, CLRDTR, SETDTR);
584
+ }
585
+
586
+ VALUE RB_SERIAL_EXPORT sp_get_rts_impl(self)
587
+ VALUE self;
588
+ {
589
+ rb_notimplement();
590
+ return self;
591
+ }
592
+
593
+ VALUE RB_SERIAL_EXPORT sp_get_dtr_impl(self)
594
+ VALUE self;
595
+ {
596
+ rb_notimplement();
597
+ return self;
598
+ }
599
+
600
+ VALUE RB_SERIAL_EXPORT sp_write_impl(self, str)
601
+ VALUE self, str;
602
+ {
603
+ char *c_str = RSTRING_PTR(str);
604
+ int len = RSTRING_LEN(str);
605
+ DWORD n = 0;
606
+ if(FALSE == WriteFile(rb_iv_get(self,"@@fh"), c_str, len, &n, NULL)){
607
+ _rb_win32_fail("WriteFile");
608
+ }
609
+ rb_iv_set(self,"@@byte_offset", rb_iv_get(self,"@@initial_byte_offset"));
610
+ return n;
611
+ }
612
+
613
+ VALUE RB_SERIAL_EXPORT sp_read_impl(argc, argv, self)
614
+ int argc;
615
+ VALUE *argv, self;
616
+ {
617
+ long bytes = 1024;
618
+
619
+ if (argc > 1){
620
+ rb_raise(rb_eArgError, "Wrong number of arguments in read()");
621
+ }
622
+ else if (argc == 1){
623
+ bytes = FIX2LONG(argv[0]);
624
+ }
625
+
626
+ char ReadBuffer[bytes];
627
+ DWORD n = 0;
628
+ DWORD w;
629
+ w = SetFilePointer(rb_iv_get(self,"@@fh"), FIX2LONG(rb_iv_get(self,"@@byte_offset")), NULL, FILE_BEGIN);
630
+ if (w == INVALID_SET_FILE_POINTER){
631
+ _rb_win32_fail("SetFilePointer");
632
+ }
633
+ if (FALSE == ReadFile(rb_iv_get(self,"@@fh"), ReadBuffer, bytes, &n, NULL)){
634
+ _rb_win32_fail("ReadFile");
635
+ }
636
+ rb_iv_set(self,"@@byte_offset", rb_iv_get(self, "@@byte_offset") + bytes);
637
+ return rb_str_new(ReadBuffer, bytes);
638
+ }
639
+
640
+ void RB_SERIAL_EXPORT sp_close_impl(self)
641
+ VALUE self;
642
+ {
643
+ CloseHandle(rb_iv_get(self,"@@fh"));
644
+ }
645
+
646
+ void RB_SERIAL_EXPORT sp_set_initial_offset_impl(self, offset)
647
+ VALUE self, offset;
648
+ {
649
+ rb_iv_set(self,"@@initial_byte_offset", FIX2INT(offset));
650
+ }
651
+
652
+ #endif /* defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW) */