1 /* sane - Scanner Access Now Easy.
2 Copyright (C) 1997 David Mosberger-Tang
3 This file is part of the SANE package.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18 As a special exception, the authors of SANE give permission for
19 additional uses of the libraries contained in this release of SANE.
20
21 The exception is that, if you link a SANE library with other files
22 to produce an executable, this does not by itself cause the
23 resulting executable to be covered by the GNU General Public
24 License. Your use of that executable is in no way restricted on
25 account of linking the SANE library code into it.
26
27 This exception does not, however, invalidate any other reasons why
28 the executable file might be covered by the GNU General Public
29 License.
30
31 If you submit changes to SANE to the maintainers to be included in
32 a subsequent release, you agree by submitting the changes that
33 those changes may be distributed with this exception intact.
34
35 If you write modifications of your own for SANE, it is your choice
36 whether to permit this exception to apply to your modifications.
37 If you do not wish that, delete this exception notice. */
38
39 #include "../include/sane/config.h"
40
41 #include <errno.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include <sys/types.h>
46
47 #include "../include/sane/sane.h"
48 #include "../include/sane/sanei_wire.h"
49
50 #define BACKEND_NAME sanei_wire
51 #include "../include/sane/sanei_backend.h"
52
53 void
sanei_w_space(Wire * w,size_t howmuch)54 sanei_w_space (Wire * w, size_t howmuch)
55 {
56 size_t nbytes, left_over;
57 int fd = w->io.fd;
58 ssize_t nread, nwritten;
59
60 DBG (3, "sanei_w_space: %lu bytes for wire %d\n", (u_long) howmuch, fd);
61
62 if (howmuch > w->buffer.size)
63 DBG (2, "sanei_w_space: bigger than buffer (%lu bytes), "
64 "may be flush()\n", (u_long) w->buffer.size);
65
66 if (w->status != 0)
67 {
68 DBG (1, "sanei_w_space: wire is in invalid state %d\n",
69 w->status);
70 return;
71 }
72
73 if (w->buffer.curr + howmuch > w->buffer.end)
74 {
75 DBG (4, "sanei_w_space: free buffer size is %lu\n",
76 (u_long) (w->buffer.end - w->buffer.curr));
77 switch (w->direction)
78 {
79 case WIRE_ENCODE:
80 nbytes = w->buffer.curr - w->buffer.start;
81 w->buffer.curr = w->buffer.start;
82 DBG (4, "sanei_w_space: ENCODE: sending %lu bytes\n",
83 (u_long) nbytes);
84 while (nbytes > 0)
85 {
86 nwritten = (*w->io.write) (fd, w->buffer.curr, nbytes);
87 if (nwritten < 0)
88 {
89 DBG (1, "sanei_w_space: ENCODE: write failed (%d)\n", errno);
90 w->status = errno;
91 return;
92 }
93 w->buffer.curr += nwritten;
94 nbytes -= nwritten;
95 }
96 w->buffer.curr = w->buffer.start;
97 w->buffer.end = w->buffer.start + w->buffer.size;
98 DBG (4, "sanei_w_space: ENCODE: free buffer is now %lu\n",
99 (u_long) w->buffer.size);
100 break;
101
102 case WIRE_DECODE:
103 left_over = w->buffer.end - w->buffer.curr;
104
105 if ((signed) left_over < 0)
106 {
107 DBG (1, "sanei_w_space: DECODE: buffer underflow\n");
108 return;
109 }
110
111 if (left_over)
112 {
113 DBG (4, "sanei_w_space: DECODE: %lu bytes left in buffer\n",
114 (u_long) left_over);
115 memmove (w->buffer.start, w->buffer.curr, left_over);
116 }
117 w->buffer.curr = w->buffer.start;
118 w->buffer.end = w->buffer.start + left_over;
119
120 DBG (4, "sanei_w_space: DECODE: receiving data\n");
121 do
122 {
123 nread = (*w->io.read) (fd, w->buffer.end,
124 w->buffer.size - left_over);
125 if (nread <= 0)
126 {
127 DBG (2, "sanei_w_space: DECODE: no data received (%d)\n",
128 errno);
129 if (nread == 0)
130 errno = EINVAL;
131 w->status = errno;
132 return;
133 }
134 left_over += nread;
135 w->buffer.end += nread;
136 }
137 while (left_over < howmuch);
138 DBG (4, "sanei_w_space: DECODE: %lu bytes read\n",
139 (u_long) (w->buffer.end - w->buffer.start));
140 break;
141
142 case WIRE_FREE:
143 DBG (4, "sanei_w_space: FREE: doing nothing for free operation\n");
144 break;
145 }
146 }
147 DBG (4, "sanei_w_space: done\n");
148 }
149
150 void
sanei_w_void(Wire * w,void __sane_unused__ * v)151 sanei_w_void (Wire * w, void __sane_unused__ * v)
152 {
153 DBG (3, "sanei_w_void: wire %d (void debug output)\n", w->io.fd);
154 }
155
156 void
sanei_w_array(Wire * w,SANE_Word * len_ptr,void ** v,WireCodecFunc w_element,size_t element_size)157 sanei_w_array (Wire * w, SANE_Word * len_ptr, void **v,
158 WireCodecFunc w_element, size_t element_size)
159 {
160 SANE_Word len;
161 char *val;
162 int i;
163
164 DBG (3, "sanei_w_array: wire %d, elements of size %lu\n", w->io.fd,
165 (u_long) element_size);
166
167 if (w->direction == WIRE_FREE)
168 {
169 if (*len_ptr && *v)
170 {
171 DBG (4, "sanei_w_array: FREE: freeing array (%d elements)\n",
172 *len_ptr);
173 val = *v;
174 for (i = 0; i < *len_ptr; ++i)
175 {
176 (*w_element) (w, val);
177 val += element_size;
178 }
179 free (*v);
180 w->allocated_memory -= (*len_ptr * element_size);
181 }
182 else
183 DBG (1, "sanei_w_array: FREE: tried to free array but *len_ptr or *v "
184 "was NULL\n");
185
186 DBG (4, "sanei_w_array: FREE: done\n");
187 return;
188 }
189
190 if (w->direction == WIRE_ENCODE)
191 len = *len_ptr;
192 DBG (4, "sanei_w_array: send/receive array length\n");
193 sanei_w_word (w, &len);
194
195 if (w->status)
196 {
197 DBG (1, "sanei_w_array: bad status: %d\n", w->status);
198 return;
199 }
200 DBG (4, "sanei_w_array: array has %d elements\n", len);
201
202 if (w->direction == WIRE_DECODE)
203 {
204 *len_ptr = len;
205 if (len)
206 {
207 if (((unsigned int) len) > MAX_MEM
208 || ((unsigned int) len * element_size) > MAX_MEM
209 || (w->allocated_memory + len * element_size) > MAX_MEM)
210 {
211 DBG (0, "sanei_w_array: DECODE: maximum amount of allocated memory "
212 "exceeded (limit: %u, new allocation: %lu, total: %lu bytes)\n",
213 MAX_MEM, (unsigned long)(len * element_size),
214 (unsigned long)(MAX_MEM + len * element_size));
215 w->status = ENOMEM;
216 return;
217 }
218 *v = malloc (len * element_size);
219 if (*v == 0)
220 {
221 /* Malloc failed, so return an error. */
222 DBG (1, "sanei_w_array: DECODE: not enough free memory\n");
223 w->status = ENOMEM;
224 return;
225 }
226 memset (*v, 0, len * element_size);
227 w->allocated_memory += (len * element_size);
228 }
229 else
230 *v = 0;
231 }
232
233 val = *v;
234 DBG (4, "sanei_w_array: transferring array elements\n");
235 for (i = 0; i < len; ++i)
236 {
237 (*w_element) (w, val);
238 val += element_size;
239 if (w->status)
240 {
241 DBG (1, "sanei_w_array: bad status: %d\n", w->status);
242 return;
243 }
244 }
245 DBG (4, "sanei_w_array: done\n");
246 }
247
248 void
sanei_w_ptr(Wire * w,void ** v,WireCodecFunc w_value,size_t value_size)249 sanei_w_ptr (Wire * w, void **v, WireCodecFunc w_value, size_t value_size)
250 {
251 SANE_Word is_null;
252
253 DBG (3, "sanei_w_ptr: wire %d, value pointer at is %lu bytes\n", w->io.fd,
254 (u_long) value_size);
255
256 if (w->direction == WIRE_FREE)
257 {
258 if (*v && value_size)
259 {
260 DBG (4, "sanei_w_ptr: FREE: freeing value\n");
261 (*w_value) (w, *v);
262 free (*v);
263 w->allocated_memory -= value_size;
264 }
265 else
266 DBG (1, "sanei_w_ptr: FREE: tried to free value but *v or value_size "
267 "was NULL\n");
268
269 DBG (4, "sanei_w_ptr: FREE: done\n");
270 return;
271 }
272 if (w->direction == WIRE_ENCODE)
273 is_null = (*v == 0);
274
275 DBG (4, "sanei_w_ptr: send/receive is_null\n");
276 sanei_w_word (w, &is_null);
277 if (w->status)
278 {
279 DBG (1, "sanei_w_ptr: bad status: %d\n", w->status);
280 return;
281 }
282
283 if (!is_null)
284 {
285 if (w->direction == WIRE_DECODE)
286 {
287 DBG (4, "sanei_w_ptr: DECODE: receive data pointed at\n");
288 if (value_size > MAX_MEM)
289 {
290 DBG (0, "sanei_w_ptr: DECODE: maximum amount of allocated memory "
291 "exceeded (limit: %u, new allocation: %lu, total: %lu bytes)\n",
292 MAX_MEM, (unsigned long)value_size,
293 (unsigned long)(w->allocated_memory + value_size));
294 w->status = ENOMEM;
295 return;
296 }
297
298 *v = malloc (value_size);
299 if (*v == 0)
300 {
301 /* Malloc failed, so return an error. */
302 DBG (1, "sanei_w_ptr: DECODE: not enough free memory\n");
303 w->status = ENOMEM;
304 return;
305 }
306 w->allocated_memory += value_size;
307 memset (*v, 0, value_size);
308 }
309 (*w_value) (w, *v);
310 }
311 else if (w->direction == WIRE_DECODE)
312 *v = 0;
313
314 DBG (4, "sanei_w_ptr: done\n");
315 }
316
317 void
sanei_w_byte(Wire * w,SANE_Byte * v)318 sanei_w_byte (Wire * w, SANE_Byte * v)
319 {
320 DBG (3, "sanei_w_byte: wire %d\n", w->io.fd);
321 (*w->codec.w_byte) (w, v);
322 if (w->direction != WIRE_FREE)
323 DBG (4, "sanei_w_byte: value = %d\n", *v);
324 }
325
326 void
sanei_w_char(Wire * w,SANE_Char * v)327 sanei_w_char (Wire * w, SANE_Char * v)
328 {
329 DBG (3, "sanei_w_char: wire %d\n", w->io.fd);
330 (*w->codec.w_char) (w, v);
331 if (w->direction != WIRE_FREE)
332 DBG (4, "sanei_w_char: value = %d\n", *v);
333 }
334
335 void
sanei_w_word(Wire * w,SANE_Word * v)336 sanei_w_word (Wire * w, SANE_Word * v)
337 {
338 DBG (3, "sanei_w_word: wire %d\n", w->io.fd);
339 (*w->codec.w_word) (w, v);
340 if (w->direction != WIRE_FREE)
341 DBG (4, "sanei_w_word: value = %d\n", *v);
342 }
343
344 void
sanei_w_string(Wire * w,SANE_String * v)345 sanei_w_string (Wire * w, SANE_String * v)
346 {
347 DBG (3, "sanei_w_string: wire %d\n", w->io.fd);
348 (*w->codec.w_string) (w, v);
349 if (w->direction != WIRE_FREE && w->status == 0)
350 DBG (4, "sanei_w_string: value = %s\n", *v);
351 }
352
353 void
sanei_w_status(Wire * w,SANE_Status * v)354 sanei_w_status (Wire * w, SANE_Status * v)
355 {
356 SANE_Word word = *v;
357
358 DBG (3, "sanei_w_status: wire %d\n", w->io.fd);
359
360 sanei_w_word (w, &word);
361 if (w->direction == WIRE_DECODE)
362 *v = word;
363
364 if (w->direction != WIRE_FREE)
365 DBG (4, "sanei_w_status: value = %d\n", word);
366 }
367
368 void
sanei_w_bool(Wire * w,SANE_Bool * v)369 sanei_w_bool (Wire * w, SANE_Bool * v)
370 {
371 SANE_Word word = *v;
372
373 DBG (3, "sanei_w_bool: wire %d\n", w->io.fd);
374 sanei_w_word (w, &word);
375 if (w->direction == WIRE_DECODE)
376 *v = word;
377
378 if (w->direction != WIRE_FREE)
379 DBG (4, "sanei_w_bool: value = %s\n",
380 ((word == SANE_TRUE) ? ("true") : ("false")));
381 }
382
383 void
sanei_w_constraint_type(Wire * w,SANE_Constraint_Type * v)384 sanei_w_constraint_type (Wire * w, SANE_Constraint_Type * v)
385 {
386 SANE_Word word = *v;
387
388 DBG (3, "sanei_w_constraint_type: wire %d\n", w->io.fd);
389
390 sanei_w_word (w, &word);
391 if (w->direction == WIRE_DECODE)
392 *v = word;
393
394 if (w->direction != WIRE_FREE)
395 DBG (4, "sanei_w_constraint_type: value = %d\n", word);
396 }
397
398 void
sanei_w_value_type(Wire * w,SANE_Value_Type * v)399 sanei_w_value_type (Wire * w, SANE_Value_Type * v)
400 {
401 SANE_Word word = *v;
402
403 DBG (3, "sanei_w_value_type: wire %d\n", w->io.fd);
404
405 sanei_w_word (w, &word);
406 if (w->direction == WIRE_DECODE)
407 *v = word;
408 if (w->direction != WIRE_FREE)
409 DBG (4, "sanei_w_value_type: value = %d\n", word);
410 }
411
412 void
sanei_w_unit(Wire * w,SANE_Unit * v)413 sanei_w_unit (Wire * w, SANE_Unit * v)
414 {
415 SANE_Word word = *v;
416
417 DBG (3, "sanei_w_unit: wire %d\n", w->io.fd);
418 sanei_w_word (w, &word);
419 if (w->direction == WIRE_DECODE)
420 *v = word;
421
422 if (w->direction != WIRE_FREE)
423 DBG (4, "sanei_w_unit: value = %d\n", word);
424 /* gosh... all the sane_w_something should be a macro or something */
425 }
426
427 void
sanei_w_action(Wire * w,SANE_Action * v)428 sanei_w_action (Wire * w, SANE_Action * v)
429 {
430 SANE_Word word = *v;
431
432 DBG (3, "sanei_w_action: wire %d\n", w->io.fd);
433
434 sanei_w_word (w, &word);
435 if (w->direction == WIRE_DECODE)
436 *v = word;
437
438 if (w->direction != WIRE_FREE)
439 DBG (4, "sanei_w_action: value = %d\n", word);
440 }
441
442 void
sanei_w_frame(Wire * w,SANE_Frame * v)443 sanei_w_frame (Wire * w, SANE_Frame * v)
444 {
445 SANE_Word word = *v;
446
447 DBG (3, "sanei_w_frame: wire %d\n", w->io.fd);
448
449 sanei_w_word (w, &word);
450 if (w->direction == WIRE_DECODE)
451 *v = word;
452
453 if (w->direction != WIRE_FREE)
454 DBG (4, "sanei_w_frame: value = %d\n", word);
455 }
456
457 void
sanei_w_range(Wire * w,SANE_Range * v)458 sanei_w_range (Wire * w, SANE_Range * v)
459 {
460 DBG (3, "sanei_w_range: wire %d\n", w->io.fd);
461 sanei_w_word (w, &v->min);
462 sanei_w_word (w, &v->max);
463 sanei_w_word (w, &v->quant);
464 if (w->direction != WIRE_FREE)
465 DBG (4, "sanei_w_range: min/max/step = %f/%f/%f\n",
466 SANE_UNFIX (v->min), SANE_UNFIX (v->max), SANE_UNFIX (v->quant));
467 }
468
469 void
sanei_w_device(Wire * w,SANE_Device * v)470 sanei_w_device (Wire * w, SANE_Device * v)
471 {
472 DBG (3, "sanei_w_device: wire %d\n", w->io.fd);
473 sanei_w_string (w, (SANE_String *) & v->name);
474 sanei_w_string (w, (SANE_String *) & v->vendor);
475 sanei_w_string (w, (SANE_String *) & v->model);
476 sanei_w_string (w, (SANE_String *) & v->type);
477 if (w->direction != WIRE_FREE)
478 DBG (4, "sanei_w_device: %s %s from %s (%s)\n", v->name, v->model,
479 v->vendor, v->type);
480 }
481
482 void
sanei_w_device_ptr(Wire * w,SANE_Device ** v)483 sanei_w_device_ptr (Wire * w, SANE_Device ** v)
484 {
485 DBG (3, "sanei_w_device_ptr: wire %d\n", w->io.fd);
486 sanei_w_ptr (w, (void **) v, (WireCodecFunc) sanei_w_device, sizeof (**v));
487 if (w->direction != WIRE_FREE)
488 DBG (4, "sanei_w_device_ptr: device struct at %p\n", (void*) *v);
489 }
490
491 void
sanei_w_option_descriptor(Wire * w,SANE_Option_Descriptor * v)492 sanei_w_option_descriptor (Wire * w, SANE_Option_Descriptor * v)
493 {
494 SANE_Word len;
495
496 DBG (3, "sanei_w_option_descriptor: wire %d\n", w->io.fd);
497
498 sanei_w_string (w, (SANE_String *) & v->name);
499 sanei_w_string (w, (SANE_String *) & v->title);
500 sanei_w_string (w, (SANE_String *) & v->desc);
501 sanei_w_value_type (w, &v->type);
502 sanei_w_unit (w, &v->unit);
503 sanei_w_word (w, &v->size);
504 sanei_w_word (w, &v->cap);
505 sanei_w_constraint_type (w, &v->constraint_type);
506
507 if (w->direction != WIRE_FREE)
508 DBG (4, "sanei_w_option_descriptor: option %s\n", v->name);
509
510 switch (v->constraint_type)
511 {
512 case SANE_CONSTRAINT_NONE:
513 break;
514
515 case SANE_CONSTRAINT_RANGE:
516 sanei_w_ptr (w, (void **) &v->constraint.range,
517 (WireCodecFunc) sanei_w_range, sizeof (SANE_Range));
518 break;
519
520 case SANE_CONSTRAINT_WORD_LIST:
521 if (w->direction != WIRE_DECODE)
522 len = v->constraint.word_list[0] + 1;
523 sanei_w_array (w, &len, (void **) &v->constraint.word_list,
524 w->codec.w_word, sizeof (SANE_Word));
525 break;
526
527 case SANE_CONSTRAINT_STRING_LIST:
528 if (w->direction != WIRE_DECODE)
529 {
530 for (len = 0; v->constraint.string_list[len]; ++len);
531 ++len; /* send NULL string, too */
532 }
533 sanei_w_array (w, &len, (void **) &v->constraint.string_list,
534 w->codec.w_string, sizeof (SANE_String));
535 break;
536 }
537 DBG (4, "sanei_w_option_descriptor: done\n");
538 }
539
540 void
sanei_w_option_descriptor_ptr(Wire * w,SANE_Option_Descriptor ** v)541 sanei_w_option_descriptor_ptr (Wire * w, SANE_Option_Descriptor ** v)
542 {
543 DBG (3, "sanei_w_option_descriptor_ptr: wire %d\n", w->io.fd);
544 sanei_w_ptr (w, (void **) v,
545 (WireCodecFunc) sanei_w_option_descriptor, sizeof (**v));
546 DBG (4, "sanei_w_option_descriptor_ptr: done\n");
547 }
548
549 void
sanei_w_parameters(Wire * w,SANE_Parameters * v)550 sanei_w_parameters (Wire * w, SANE_Parameters * v)
551 {
552 DBG (3, "sanei_w_parameters: wire %d\n", w->io.fd);
553 sanei_w_frame (w, &v->format);
554 sanei_w_bool (w, &v->last_frame);
555 sanei_w_word (w, &v->bytes_per_line);
556 sanei_w_word (w, &v->pixels_per_line);
557 sanei_w_word (w, &v->lines);
558 sanei_w_word (w, &v->depth);
559 if (w->direction != WIRE_FREE)
560 DBG (4,
561 "sanei_w_parameters: format/last/bpl/ppl/lines/depth = "
562 "%d/%d/%d/%d/%d/%d\n", v->format, v->last_frame, v->bytes_per_line,
563 v->pixels_per_line, v->lines, v->depth);
564 }
565
566 static void
flush(Wire * w)567 flush (Wire * w)
568 {
569 DBG (3, "flush: wire %d\n", w->io.fd);
570 if (w->direction == WIRE_ENCODE)
571 sanei_w_space (w, w->buffer.size + 1);
572 else if (w->direction == WIRE_DECODE)
573 w->buffer.curr = w->buffer.end = w->buffer.start;
574 if (w->status != 0)
575 DBG (2, "flush: error status %d\n", w->status);
576 DBG (4, "flush: wire flushed\n");
577 }
578
579 void
sanei_w_set_dir(Wire * w,WireDirection dir)580 sanei_w_set_dir (Wire * w, WireDirection dir)
581 {
582 DBG (3, "sanei_w_set_dir: wire %d, old direction WIRE_%s\n", w->io.fd,
583 w->direction == WIRE_ENCODE ? "ENCODE" :
584 (w->direction == WIRE_DECODE ? "DECODE" : "FREE"));
585 if (w->direction == WIRE_DECODE && w->buffer.curr != w->buffer.end)
586 DBG (1, "sanei_w_set_dir: WARNING: will delete %lu bytes from buffer\n",
587 (u_long) (w->buffer.end - w->buffer.curr));
588 flush (w);
589 w->direction = dir;
590 DBG (4, "sanei_w_set_dir: direction changed\n");
591 flush (w);
592 DBG (3, "sanei_w_set_dir: wire %d, new direction WIRE_%s\n", w->io.fd,
593 dir == WIRE_ENCODE ? "ENCODE" :
594 (dir == WIRE_DECODE ? "DECODE" : "FREE"));
595 }
596
597 void
sanei_w_call(Wire * w,SANE_Word procnum,WireCodecFunc w_arg,void * arg,WireCodecFunc w_reply,void * reply)598 sanei_w_call (Wire * w,
599 SANE_Word procnum,
600 WireCodecFunc w_arg, void *arg,
601 WireCodecFunc w_reply, void *reply)
602 {
603
604 DBG (3, "sanei_w_call: wire %d (old status %d)\n", w->io.fd, w->status);
605 w->status = 0;
606 sanei_w_set_dir (w, WIRE_ENCODE);
607
608 DBG (4, "sanei_w_call: sending request (procedure number: %d)\n", procnum);
609 sanei_w_word (w, &procnum);
610 (*w_arg) (w, arg);
611
612 if (w->status == 0)
613 {
614 DBG (4, "sanei_w_call: receiving reply\n");
615 sanei_w_set_dir (w, WIRE_DECODE);
616 (*w_reply) (w, reply);
617 }
618
619 if (w->status != 0)
620 DBG (2, "sanei_w_call: error status %d\n", w->status);
621 DBG (4, "sanei_w_call: done\n");
622 }
623
624 void
sanei_w_reply(Wire * w,WireCodecFunc w_reply,void * reply)625 sanei_w_reply (Wire * w, WireCodecFunc w_reply, void *reply)
626 {
627 DBG (3, "sanei_w_reply: wire %d (old status %d)\n", w->io.fd, w->status);
628 w->status = 0;
629 sanei_w_set_dir (w, WIRE_ENCODE);
630 (*w_reply) (w, reply);
631 flush (w);
632 if (w->status != 0)
633 DBG (2, "sanei_w_reply: error status %d\n", w->status);
634 DBG (4, "sanei_w_reply: done\n");
635 }
636
637 void
sanei_w_free(Wire * w,WireCodecFunc w_reply,void * reply)638 sanei_w_free (Wire * w, WireCodecFunc w_reply, void *reply)
639 {
640 WireDirection saved_dir = w->direction;
641
642 DBG (3, "sanei_w_free: wire %d\n", w->io.fd);
643
644 w->direction = WIRE_FREE;
645 (*w_reply) (w, reply);
646 w->direction = saved_dir;
647
648 if (w->status != 0)
649 DBG (2, "sanei_w_free: error status %d\n", w->status);
650 DBG (4, "sanei_w_free: done\n");
651 }
652
653 void
sanei_w_init(Wire * w,void (* codec_init_func)(Wire *))654 sanei_w_init (Wire * w, void (*codec_init_func) (Wire *))
655 {
656 DBG_INIT ();
657
658 DBG (3, "sanei_w_init: initializing\n");
659 w->status = 0;
660 w->direction = WIRE_ENCODE;
661 w->buffer.size = 8192;
662 w->buffer.start = malloc (w->buffer.size);
663
664 if (w->buffer.start == 0)
665 {
666 /* Malloc failed, so return an error. */
667 w->status = ENOMEM;
668 DBG (1, "sanei_w_init: not enough free memory\n");
669 }
670
671 w->buffer.curr = w->buffer.start;
672 w->buffer.end = w->buffer.start + w->buffer.size;
673 if (codec_init_func != 0)
674 {
675 DBG (4, "sanei_w_init: initializing codec\n");
676 (*codec_init_func) (w);
677 }
678 w->allocated_memory = 0;
679 DBG (4, "sanei_w_init: done\n");
680 }
681
682 void
sanei_w_exit(Wire * w)683 sanei_w_exit (Wire * w)
684 {
685 DBG (3, "sanei_w_exit: wire %d\n", w->io.fd);
686 if (w->buffer.start)
687 {
688 DBG (4, "sanei_w_exit: freeing buffer\n");
689 free (w->buffer.start);
690 }
691 w->buffer.start = 0;
692 w->buffer.size = 0;
693 DBG (4, "sanei_w_exit: done\n");
694 }
695