Graphviz 14.1.3~dev.20260207.0611
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 "config.h"
12
13#include "../tcl-compat.h"
14#include <assert.h>
15#include <cgraph/rdr.h>
16#include <limits.h>
17#include <stddef.h>
18#include "tcldot.h"
19
20/*
21 * myiodisc_afread - same api as read for libcgraph
22 *
23 * gets one line at a time from a Tcl_Channel and places it in a user buffer
24 * up to a maximum of n characters
25 *
26 * returns pointer to obtained line in user buffer, or
27 * returns NULL when last line read from memory buffer
28 *
29 * This is probably innefficient because it introduces
30 * one more stage of line buffering during reads (at least)
31 * but it is needed so that we can take full advantage
32 * of the Tcl_Channel mechanism.
33 */
34int myiodisc_afread(void* channel, char *ubuf, int n)
35{
36 assert(n >= 0);
37
38 static Tcl_DString dstr;
39 static Tcl_Size strpos;
40 Tcl_Size nput;
41
42 if (!n) { /* a call with n==0 (from aglexinit) resets */
43 *ubuf = '\0';
44 strpos = 0;
45 return 0;
46 }
47
48 /*
49 * the user buffer might not be big enough to hold the line.
50 */
51 if (strpos) {
52 nput = Tcl_DStringLength(&dstr) - strpos;
53 if (nput > n) {
54 /* chunk between first and last */
55 memcpy(ubuf, strpos + Tcl_DStringValue(&dstr), (size_t)n);
56 strpos += n;
57 nput = n;
58 ubuf[n] = '\0';
59 } else {
60 /* last chunk */
61 memcpy(ubuf, strpos + Tcl_DStringValue(&dstr), (size_t)nput);
62 strpos = 0;
63 }
64 } else {
65 Tcl_DStringFree(&dstr);
66 Tcl_DStringInit(&dstr);
67 if (Tcl_Gets((Tcl_Channel) channel, &dstr) < 0) {
68 /* probably EOF, but could be other read errors */
69 *ubuf = '\0';
70 return 0;
71 }
72 /* linend char(s) were stripped off by Tcl_Gets,
73 * append a canonical linenend. */
74 Tcl_DStringAppend(&dstr, "\n", 1);
75 if (Tcl_DStringLength(&dstr) > n) {
76 /* first chunk */
77 nput = n;
78 memcpy(ubuf, Tcl_DStringValue(&dstr), (size_t)n);
79 strpos = n;
80 } else {
81 /* single chunk */
82 nput = Tcl_DStringLength(&dstr);
83 memcpy(ubuf, Tcl_DStringValue(&dstr), (size_t)nput);
84 }
85 }
86 return (int)nput;
87}
88
89
90/* exact copy from cgraph/io.c - but that one is static */
91int myiodisc_memiofread(void *chan, char *buf, int bufsize)
92{
93 const char *ptr;
94 char *optr;
95 char c;
96 rdr_t *s;
97
98 if (bufsize == 0) return 0;
99 s = chan;
100 if (s->cur >= s->len)
101 return 0;
102 size_t l = 0;
103 ptr = s->data + s->cur;
104 optr = buf;
105 do {
106 *optr++ = c = *ptr++;
107 l++;
108 } while (c && c != '\n' && l < INT_MAX && (int)l < bufsize);
109 s->cur += l;
110 return (int)l;
111}
Definition rdr.h:10
#define Tcl_Size
Definition tcl-compat.h:33
int myiodisc_memiofread(void *chan, char *buf, int bufsize)
Definition tcldot-io.c:91
int myiodisc_afread(void *channel, char *ubuf, int n)
Definition tcldot-io.c:34
Definition grammar.c:90