source: git/MP/MP/MP_TbTransp.c @ c729f2

fieker-DuValspielwiese
Last change on this file since c729f2 was 341696, checked in by Hans Schönemann <hannes@…>, 15 years ago
Adding Id property to all files git-svn-id: file:///usr/local/Singular/svn/trunk@12231 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 18.9 KB
Line 
1/****************************************************************
2 *                                                                 
3 *                                                                 
4 *                    MP version 1.1.2:  Multi Protocol
5 *                    Kent State University, Kent, OH
6 *                 Authors:  S. Gray, N. Kajler, P. Wang
7 *          (C) 1993, 1994, 1995, 1996, 1997 All Rights Reserved
8 *
9 *                                 NOTICE
10 *
11 *  Permission to use, copy, modify, and distribute this software and
12 *  its documentation for non-commercial purposes and without fee is
13 *  hereby granted provided that the above copyright notice appear in all
14 *  copies and that both the copyright notice and this permission notice
15 *  appear in supporting documentation.
16 * 
17 *  Neither Kent State University nor the Authors make any representations
18 *  about the suitability of this software for any purpose.  The MP Library
19 *  is distributed in the hope that it will be useful, but is provided  "as
20 *  is" and without any warranty of any kind and without even the implied 
21 *  warranty of merchantability or fitness for a particular purpose.
22 *
23 *    IMPORTANT ADDITION: as of September 2006, MP is also licenced under GPL
24 *
25 *   IMPLEMENTATION FILE:  MP_TbTransp.c
26 *
27 *      Public interface routines to the "tb" transport tbice.
28 *      These include read, write, open, close, and init routines.
29 *      There are some support routines as well.
30 *
31 *  Change Log:
32 *       1/25/96   sgray - formal creation of TB device
33 *       2/12/96   sgray - added MP_TbPutMsg() and MP_TbGetMsg() routines.
34 *       3/3/96    sgray - moved call to mp_tb_init_transport() inside
35 *                         mp_tb_open_transport() and removed the init
36 *                         routine from the tb_ops struct.
37 *
38 *  Note to me:  consider modifying the mp_tb_write() routine to increase
39 *               the size of the MP send buffer using realloc().  I believe
40 *               the toolbus buffer continues to increase in size as needed.
41 *               Also, the documentation on this interface could/should
42 *               suggest that the initial buffer size be set to that of
43 *               ToolBus's initial buffer size.  ALSO, _ONLY_ MP_SEND_FRAG_MSG
44 *               and MP_RECV_FRAG_SENDER should be used.
45 *
46 ***************************************************************************/
47#ifndef lint
48static char vcid[] = "@(#) $Id$";
49#endif /* lint */
50
51#include "MP.h"
52
53#ifdef MP_HAVE_TB
54
55
56extern char fix_log_msg[]; 
57
58/* the device interface routines */
59
60long mp_tb_write();
61long mp_tb_read();
62MP_Boolean_t mp_tb_get_status();
63MP_Status_t mp_tb_flush();
64MP_Status_t mp_tb_init_transport();
65MP_Status_t mp_tb_open_connection();
66MP_Status_t mp_tb_close_connection();
67
68/*
69 * the device-specific transport operations structure that gets
70 * loaded into the transp_ops field to the transport structure
71 */
72
73static MP_TranspOps_t tb_ops = {
74  mp_tb_write,
75  mp_tb_read,
76  mp_tb_flush,
77  mp_tb_get_status,
78  mp_tb_open_connection,
79  mp_tb_close_connection,
80  mp_tb_close_connection
81};
82
83
84/*  Okay, the trouble here is that the routines that make calls to this read
85 * routine asking for len bytes really expect to get JUST len bytes copied
86 * to the location given in where.  When initially filling the buffer, len
87 * is just 4 bytes, but this code goes ahead and copies ALL the data to the
88 * address specified by where (which is just the address of a single long!).
89 * I suppose I need to add another level of buffering here.  Read in a single
90 * binary term, place it in the auxiliary buffer and return the number of
91 * bytes requested from this buffer.  Subsequent requests would come from
92 * the auxiliary buffer until it was tried out, after which a call must be
93 * made to strip off another binary term from read_term and store its data
94 * in the auxiliary buffer.  This is a lot of work!!
95 */
96static MP_Status_t get_tb_term(MP_Link_pt link)
97{
98    MP_TB_t  *tb_rec = (MP_TB_t *)(link->transp.private1);
99    term     *tmp = NULL;
100    int i;
101
102
103#ifdef MP_DEBUG
104    fprintf(stderr, "get_tb_term: entering, buf_len = %d, tbtbc = %d\n",
105            tb_rec->buf_len, tb_rec->tbtbc); 
106    fflush(stderr);
107#endif
108    if (tb_rec->read_term == NULL) {
109        MP_LogEvent(link, MP_ERROR_EVENT,
110                    "get_tb_term: link's read term is null");
111        return MP_SetError(link, MP_Failure);
112    }
113    IMP_MemFreeFnc(tb_rec->term_buf, tb_rec->buf_len);
114    if (!TBmatch(tb_rec->read_term, "f(%t,%b)", &tmp, &(tb_rec->term_buf),
115                 &(tb_rec->buf_len))) {
116        if (!TBmatch(tb_rec->read_term, "%b", &(tb_rec->term_buf), 
117                     &(tb_rec->buf_len))) {
118            MP_LogEvent(link, MP_ERROR_EVENT,
119                        "mp_tb_read: matches failed!");
120            return MP_SetError(link, MP_Failure);
121        }
122    }
123
124    /* printf("here is the buffer just extracted from a term: \n");
125       for (i = 0; i < (tb_rec->buf_len); i++) {
126       printf("%X ", tb_rec->term_buf[i]);
127       if (i % 10 == 0) printf("\n");
128       }
129       */
130    tb_rec->read_term = tmp;
131    tb_rec->next_byte = tb_rec->term_buf;
132    tb_rec->tbtbc = tb_rec->buf_len;
133
134#ifndef NO_LOGGING
135    if (link->logmask & MP_LOG_READ_EVENTS) {
136        sprintf(fix_log_msg, 
137                "tb_get_term: extracted %d bytes from link's read "
138                "ToolBus term",
139                tb_rec->buf_len);
140        MP_LogEvent(link, MP_READ_EVENT, fix_log_msg);
141    }
142#endif
143#ifdef MP_DEBUG
144    fprintf(stderr, "get_tb_term: exiting,"
145            " extracted %d bytes\n", tb_rec->buf_len); 
146    fflush(stderr);
147#endif
148 
149    return(MP_Success);
150}
151
152
153
154/* ROUTINES FOR THE Abstract Device Interface begin HERE */
155
156/*********************************************************
157 * mp_tb_write(link, where, len)
158 * return: 0 if success, -1 if failure.
159 * arguments: link - can be anything, even NULL.
160 *            where - pointer to data to be packed.
161 *            len - number of bytes to be packed.
162 *********************************************************/
163#ifdef __STDC__
164long mp_tb_write(MP_Link_pt link, char *where, unsigned long len)
165#else
166long mp_tb_write(link, where, len)
167    MP_Link_pt link;
168    char *where;
169    unsigned long len;
170#endif
171{
172    term *tmp = NULL;
173    MP_TB_t  *tb_rec = (MP_TB_t *)(link->transp.private1);
174    int i;
175
176#ifdef MP_DEBUG
177    fprintf(stderr, "mp_tb_write: entering, writing %d bytes\n", len); 
178    fprintf(stderr, "mp_tb_write: on entry write_term is 0x%X\n", 
179            tb_rec->write_term);  fflush(stderr);
180#endif
181            /*  printf("here is the buffer we are writing to a term: \n");
182                for (i = 0; i < len; i++) {
183                printf("%X ", where[i]);
184                if (i % 10 == 0) printf("\n");
185                }
186                */
187            if (tb_rec->write_term == NULL) {
188                tb_rec->write_term = TBmake("%b", link->out_base, len);
189            } else {
190                tmp = TBmake("f(%t,%b)", 
191                             tb_rec->write_term, link->out_base, len);
192                tb_rec->write_term = tmp;
193                tmp = NULL; 
194                /* so garbage collection doesn't get to write_term */
195            }
196
197#ifndef NO_LOGGING
198            if (link->logmask & MP_LOG_WRITE_EVENTS) {
199                sprintf(fix_log_msg, 
200                        "mp_tb_write: wrote %d bytes to link's "
201                        "write term", len);
202                MP_LogEvent(link, MP_WRITE_EVENT, fix_log_msg);
203            }
204#endif
205#ifdef MP_DEBUG
206            fprintf(stderr, "mp_tb_write: exiting \n"); 
207            fflush(stderr);
208#endif
209            return len;
210}
211
212
213
214/**************************************************************************
215 * mp_tb_read(link, where, len)
216 * return: number of bytes actually unpacked. -1 if failure.
217 * arguments: link - can be anything, even NULL.
218 *            where - pointer to memory location to store unpacked data.
219 *            len - number of bytes to be packed.
220 **************************************************************************/
221#ifdef __STDC__
222long mp_tb_read(MP_Link_pt link, char *where, unsigned long len)
223#else
224long mp_tb_read(link, where, len)
225    MP_Link_pt link;
226    char *where;
227    unsigned long len;
228#endif
229{
230    MP_TB_t  *tb_rec = (MP_TB_t *)(link->transp.private1);
231    unsigned long  nbytes = len, total = 0, current = 0;
232
233#ifdef MP_DEBUG
234    fprintf(stderr, "mp_tb_read: entering - want to read %d bytes\n", len); 
235    fflush(stderr);
236#endif
237
238    while (nbytes > 0) {
239        if (tb_rec->tbtbc == 0) 
240            if (!get_tb_term(link)) 
241                return 0;  /* indicates failure to caller */
242        current = (nbytes < tb_rec->tbtbc) ? nbytes : tb_rec->tbtbc;
243        memcpy(where, tb_rec->next_byte, current);
244        where += current;
245        tb_rec->next_byte += current;
246        tb_rec->tbtbc -= current;
247        nbytes -= current;
248        total += current;
249    }
250#ifndef NO_LOGGING
251    if (link->logmask & MP_LOG_READ_EVENTS) {
252        sprintf(fix_log_msg, 
253                "mp_tb_read: read %d bytes from link's term buffer", total);
254        MP_LogEvent(link, MP_READ_EVENT, fix_log_msg);
255    }
256#endif
257#ifdef MP_DEBUG
258    fprintf(stderr, "mp_tb_read: exiting - read %d bytes\n", total); 
259    fflush(stderr);
260#endif
261
262    return total;
263}
264
265 
266
267/***********************************************************************
268 * FUNCTION:  mp_tb_init_transport
269 * INPUT:     link - pointer to the link structure for this connection
270 * OUTPUT:    Success:  MP_Success and link structure initialized for the
271 *                      tb connection. 
272 *            Failure:  MP_Failure
273 * OPERATION: If there are no problems, allocate a tb structure and
274 *            attach it to the private pointer inside link.
275 ***********************************************************************/
276#ifdef __STDC__
277MP_Status_t mp_tb_init_transport(MP_Link_pt link)
278#else
279MP_Status_t mp_tb_init_transport(link)
280  MP_Link_pt link;
281#endif
282{
283#ifdef MP_DEBUG
284    fprintf(stderr, "mp_tb_init_transport: entering\n");
285    fflush(stderr);
286#endif
287
288    /* this routine is almost complete for you */
289
290    TEST_LINK_NULL(link);
291    link->transp.transp_dev = MP_TbTransportDev;
292    link->transp.transp_ops = &tb_ops;
293    link->transp.private1 = (char *)IMP_MemAllocFnc(sizeof(MP_TB_t));
294    TEST_MEM_ALLOC_ERROR(link, link->transp.private1);
295
296#ifdef MP_DEBUG
297    fprintf(stderr, "mp_tb_init_transport: exiting\n"); fflush(stderr);
298#endif
299    RETURN_OK(link);
300}
301
302
303
304/***********************************************************************
305 * FUNCTION:  mp_tb_close_connection
306 * INPUT:     link  - pointer to the link structure for this connection
307 * OUTPUT:    Success:  MP_Success
308 *                      Release the tb structure pointed to by private1.
309 *            Failure:  MP_Failure
310 * OPERATION:
311 ***********************************************************************/
312#ifdef __STDC__
313MP_Status_t mp_tb_close_connection(MP_Link_pt link)
314#else
315MP_Status_t mp_tb_close_connection(link)
316    MP_Link_pt link;
317#endif
318{
319    MP_TB_t  *tb_rec = (MP_TB_t *)(link->transp.private1);
320#ifdef MP_DEBUG
321    fprintf(stderr, "mp_tb_close_connection: entering\n");
322    fflush(stderr);
323#endif
324
325    TEST_LINK_NULL(link);
326    if (link->transp.private1 == NULL) 
327        return(MP_SetError(link, MP_NullTransport));
328    IMP_MemFreeFnc((*(MP_TB_t *)(link->transp.private1)).myhost, 
329                   MP_HOST_NAME_LEN);
330
331    TBunprotect(&(tb_rec->write_term));
332    TBunprotect(&(tb_rec->read_term));
333
334    IMP_MemFreeFnc((MP_TB_t *)(link->transp.private1), sizeof(MP_TB_t));
335    link->transp.private1 = NULL;
336
337#ifdef MP_DEBUG
338    fprintf(stderr, "mp_tb_close_connection: exiting\n");
339    fflush(stderr);
340#endif
341    RETURN_OK(link);
342}
343
344
345
346/***********************************************************************
347 * FUNCTION:  mp_tb_open_connection
348 * INPUT:     link - pointer to link structure for this connection
349 *            argc - number of arguments in argv
350 *            argv - arguments as strings
351 * OUTPUT:    Success:  MP_Success
352 *                      link established as a tb connection
353 *            Failure:  MP_Failure
354 * OPERATION: Determine the tb mode we are using and attempt to
355 *            establish a connection accordingly.  We could fail
356 *            for any of a number of reasons.  Bad hostname, bad
357 *            port number, missing arguments....
358 ***********************************************************************/
359#ifdef __STDC__
360MP_Status_t mp_tb_open_connection(MP_Link_pt link,
361                                  int        argc,
362                                  char     **argv)
363#else
364MP_Status_t mp_tb_open_connection(link, argc, argv)
365    MP_Link_pt link;
366    int        argc;
367    char     **argv;
368#endif
369{
370    MP_TB_t  *tb_rec = NULL;
371
372#ifdef MP_DEBUG
373    fprintf(stderr, "mp_tb_open_connection: entering\n");
374    fflush(stderr);
375#endif
376
377    TEST_LINK_NULL(link);
378    ERR_CHK(mp_tb_init_transport(link));
379    tb_rec = (MP_TB_t *)(link->transp.private1);
380    tb_rec->myhost = (char *) IMP_MemAllocFnc(MP_HOST_NAME_LEN);
381    TEST_MEM_ALLOC_ERROR(link, tb_rec->myhost);
382    if (gethostname(tb_rec->myhost, MP_HOST_NAME_LEN) == -1) {
383        IMP_MemFreeFnc(tb_rec->myhost, MP_HOST_NAME_LEN);
384        tb_rec->myhost = NULL;
385    }
386    tb_rec->write_term = NULL;
387    tb_rec->read_term = NULL;
388    TBprotect(&(tb_rec->write_term));
389    TBprotect(&(tb_rec->read_term));
390    tb_rec->term_buf = tb_rec->next_byte = NULL;
391    tb_rec->buf_len = tb_rec->tbtbc = 0;
392
393#ifdef MP_DEBUG
394    fprintf(stderr, "mp_tb_open_connection: exiting\n"); fflush(stderr);
395#endif
396    RETURN_OK(link);
397}
398
399MP_Status_t
400#ifdef __STDC__
401mp_tb_flush(MP_Link_pt link)
402#else
403mp_tb_flush(link)
404    MP_Link_pt link;
405#endif
406{   
407    TEST_LINK_NULL(link);
408#ifdef MP_DEBUG
409    printf("mp_tb_flush: entering and exiting for link %d\n", link->link_id);
410#endif
411    return MP_Success;
412}
413
414
415#ifdef __STDC__
416MP_Boolean_t mp_tb_get_status(MP_Link_pt link, MP_LinkStatus_t status_to_check)
417#else
418MP_Boolean_t mp_tb_get_status(link, status_to_check)
419    MP_Link_pt link;
420    MP_LinkStatus_t status_to_check;
421#endif
422{   
423
424    TEST_LINK_NULL(link);
425
426#ifdef MP_DEBUG
427    printf("mp_tb_get_status: entering for link %d\n", link->link_id);
428#endif
429
430    switch (status_to_check) {
431    case MP_LinkReadyReading:
432         
433        /* your code goes here */
434        break;
435    case MP_LinkReadyWriting:
436
437        /* your code goes here */
438        break;
439
440    default:
441        sprintf(fix_log_msg,"mp_tb_get_status: illegal option %d", 
442                status_to_check);
443        MP_LogEvent(link, MP_ERROR_EVENT, fix_log_msg);
444        return MP_FALSE;
445    }
446#ifdef MP_DEBUG
447    printf("mp_tb_get_status: exiting\n");
448#endif
449}
450
451/* Additional utility routines */
452
453
454/***********************************************************************
455 * FUNCTION:  MP_TbGetMsg
456 * INPUT:     link    - pointer to the link structure for this connection
457 *            tb_data - pointer to the data returned by ToolBus
458 *            len     - the number of bytes returned by ToolBus and
459 *                      pointed to by tb_data.
460 * OUTPUT:    Success:  MP_Success
461 *            Failure:  MP_Failure - only if the link is NULL or if
462 *                      MP_SkipMsg() fails (which isn't likely!).
463 * OPERATION: Simply copy the data from tb_data to the beginning of the
464 *            MP receive buffer and set all the link fields appropriately.
465 *            Note that we MUST call MP_SkipMsg() to set all the
466 ***********************************************************************/
467#ifdef __STDC__
468MP_Status_t MP_TbGetMsg (MP_Link_pt link, char *tb_data, unsigned long len)
469#else
470MP_Status_t MP_TbGetMsg(link, tb_data, len)
471    MP_Link_pt link;
472    char *tb_data;
473    unsigned long len;
474#endif
475{
476    TEST_LINK_NULL(link);
477    if (MP_SkipMsg(link) != MP_Success) {
478        fprintf(stderr,"MP_TbGetMsg: failed MP_SkipMsg()\n");
479        return MP_Failure;
480    }
481    memcpy(link->in_finger, tb_data, len);
482    link->last_frag = MP_TRUE;
483    *(link->in_base) = len;
484    link->fbtbc = len; 
485    link->sfblr = 0;
486    /*   (unsigned long)link->in_finger = (unsigned long) link->in_base + 4;*/
487    (unsigned long)link->in_boundry = (unsigned long) link->in_base + sizeof(long) + len;
488 
489    return MP_Success;
490}
491
492
493
494/***********************************************************************
495 * FUNCTION:  MP_TbPutMsg
496 * INPUT:     link    - pointer to the link structure for this connection
497 * OUTPUT:    Success:  return MP_Success as value of the function
498 *               tb_data - address of the pointer to the data to be sent by
499 *                         ToolBus - make this the beginning of the MP send
500 *                         buffer.
501 *               len     - the number of bytes to be sent by ToolBus and
502 *                         pointed to by *tb_data.
503 *            Failure:  MP_Failure - only if the link is NULL
504 * OPERATION: Simply set the data pointer to point to the beginning of
505 *            the MP send buffer and set all the link fields appropriately.
506 * NOTE:      We also RESET the out_finger pointer in preparation for
507 *            the writing the NEXT MP tree to the MP send buffer.  In
508 *            respects this is equivalent to using MP_EndMsg().  In the
509 *            future, I might want to make MP_EndMsg() link-specific AND
510 *            add an MP_ResetMsg() routine to be called by the sender
511 *            before each write of a NEW message to the link.
512 ***********************************************************************/
513#ifdef __STDC__
514MP_Status_t MP_TbPutMsg(MP_Link_pt link, char **tb_data, unsigned long *len)
515#else
516MP_TbPutMsg(link, tb_data, len)
517    MP_Status_t MP_Link_pt link;
518    char **tb_data;
519    unsigned long *len;
520#endif
521{
522    TEST_LINK_NULL(link);
523    *tb_data = (char *)(link->out_base + 4); 
524    *len = (((unsigned long)link->out_finger) - ((unsigned long)link->out_base) - 4);
525    (unsigned long)link->out_finger = (unsigned long)link->out_base + sizeof(unsigned long);
526 
527    return MP_Success;
528}
529
530
531
532
533#ifdef __STDC__
534MP_Status_t MP_SetTbTerm(MP_Link_pt link, term *t)
535#else
536MP_Status_t MP_SetTbTerm(link, t)
537    MP_Link_pt link;
538    term *t;
539#endif
540{   
541    term *tmp1, *tmp2 = NULL;
542    char *tb_data = NULL;
543    long  len = 0;
544    MP_TB_t  *tb_rec = (MP_TB_t *)(link->transp.private1);
545#ifdef MP_DEBUG
546    fprintf(stderr,"MP_SetTbTerm: entering, t = 0x%X, read_term = 0x%X\n", t,
547            tb_rec->read_term); 
548    fflush(stderr);
549#endif
550
551    while (TBmatch(t, "f(%t,%b)", &tmp1, &tb_data, &len)) {
552        if (tb_rec->read_term == NULL) 
553            tb_rec->read_term = TBmake("%b", tb_data, len);
554        else {
555            tmp2 = TBmake("f(%t,%b)", tb_rec->read_term, tb_data, len);
556            tb_rec->read_term = tmp2;
557        }
558        t = tmp1;
559    }
560
561    if (tb_rec->read_term == NULL) {
562        tb_rec->read_term = t;
563    } else {
564        if (!TBmatch(t, "%b", &tb_data, &len)) {
565            MP_LogEvent(link, MP_ERROR_EVENT, "MP_TbSetMsg: match failed");
566            return (MP_SetError(link, MP_Failure));
567        }
568        tmp2 = TBmake("f(%t,%b)", tb_rec->read_term, tb_data, len);
569        tb_rec->read_term = tmp2;
570    }
571#ifdef MP_DEBUG
572    fprintf(stderr,"MP_SetTbTerm: done reversal of list, exiting\n");
573    fflush(stderr);
574#endif
575
576    return MP_Success;
577}
578 
579#endif /* MP_HAVE_TB */
Note: See TracBrowser for help on using the repository browser.