Graphviz 12.1.0~dev.20240716.0947
Loading...
Searching...
No Matches
tcldot-io.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <assert.h>
12#include <cgraph/rdr.h>
13#include <limits.h>
14#include <stddef.h>
15#include "tcldot.h"
16
17/*
18 * myiodisc_afread - same api as read for libcgraph
19 *
20 * gets one line at a time from a Tcl_Channel and places it in a user buffer
21 * up to a maximum of n characters
22 *
23 * returns pointer to obtained line in user buffer, or
24 * returns NULL when last line read from memory buffer
25 *
26 * This is probably innefficient because it introduces
27 * one more stage of line buffering during reads (at least)
28 * but it is needed so that we can take full advantage
29 * of the Tcl_Channel mechanism.
30 */
31int myiodisc_afread(void* channel, char *ubuf, int n)
32{
33 assert(n >= 0);
34
35 static Tcl_DString dstr;
36 static int strpos;
37 int nput;
38
39 if (!n) { /* a call with n==0 (from aglexinit) resets */
40 *ubuf = '\0';
41 strpos = 0;
42 return 0;
43 }
44
45 /*
46 * the user buffer might not be big enough to hold the line.
47 */
48 if (strpos) {
49 nput = Tcl_DStringLength(&dstr) - strpos;
50 if (nput > n) {
51 /* chunk between first and last */
52 memcpy(ubuf, strpos + Tcl_DStringValue(&dstr), (size_t)n);
53 strpos += n;
54 nput = n;
55 ubuf[n] = '\0';
56 } else {
57 /* last chunk */
58 memcpy(ubuf, strpos + Tcl_DStringValue(&dstr), (size_t)nput);
59 strpos = 0;
60 }
61 } else {
62 Tcl_DStringFree(&dstr);
63 Tcl_DStringInit(&dstr);
64 if (Tcl_Gets((Tcl_Channel) channel, &dstr) < 0) {
65 /* probably EOF, but could be other read errors */
66 *ubuf = '\0';
67 return 0;
68 }
69 /* linend char(s) were stripped off by Tcl_Gets,
70 * append a canonical linenend. */
71 Tcl_DStringAppend(&dstr, "\n", 1);
72 if (Tcl_DStringLength(&dstr) > n) {
73 /* first chunk */
74 nput = n;
75 memcpy(ubuf, Tcl_DStringValue(&dstr), (size_t)n);
76 strpos = n;
77 } else {
78 /* single chunk */
79 nput = Tcl_DStringLength(&dstr);
80 memcpy(ubuf, Tcl_DStringValue(&dstr), (size_t)nput);
81 }
82 }
83 return nput;
84}
85
86
87/* exact copy from cgraph/io.c - but that one is static */
88int myiodisc_memiofread(void *chan, char *buf, int bufsize)
89{
90 const char *ptr;
91 char *optr;
92 char c;
93 rdr_t *s;
94
95 if (bufsize == 0) return 0;
96 s = chan;
97 if (s->cur >= s->len)
98 return 0;
99 size_t l = 0;
100 ptr = s->data + s->cur;
101 optr = buf;
102 do {
103 *optr++ = c = *ptr++;
104 l++;
105 } while (c && c != '\n' && l < INT_MAX && (int)l < bufsize);
106 s->cur += l;
107 return (int)l;
108}
Definition rdr.h:10
int myiodisc_memiofread(void *chan, char *buf, int bufsize)
Definition tcldot-io.c:88
int myiodisc_afread(void *channel, char *ubuf, int n)
Definition tcldot-io.c:31
Definition grammar.c:93