Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/sfio/sfgetr.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#include "sfhdr.h"
23
24
/* Read a record delineated by a character.
25
** The record length can be accessed via sfvalue(f).
26
**
27
** Written by Kiem-Phong Vo
28
*/
29
30
#if __STD_C
31
char* sfgetr(Sfio_t *f, int rc, int type)
32
#else
33
char* sfgetr(f,rc,type)
34
Sfio_t* f; /* stream to read from */
35
int rc; /* record separator */
36
int type;
37
#endif
38
{
39
ssize_t n, un;
40
uchar *s, *ends, *us;
41
int found;
42
Sfrsrv_t* rsrv;
43
SFMTXDECL(f); /* declare a local stream variable for multithreading */
44
45
SFMTXENTER(f, NIL(char*));
46
47
if(rc < 0 || (f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0) )
48
SFMTXRETURN(f, NIL(char*));
49
SFLOCK(f,0);
50
51
/* buffer to be returned */
52
rsrv = NIL(Sfrsrv_t*);
53
us = NIL(uchar*);
54
un = 0;
55
found = 0;
56
57
/* compatibility mode */
58
type = type < 0 ? SF_LASTR : type == 1 ? SF_STRING : type;
59
60
if(type&SF_LASTR) /* return the broken record */
61
{ if((f->flags&SF_STRING) && (un = f->endb - f->next))
62
{ us = f->next;
63
f->next = f->endb;
64
found = 1;
65
}
66
else if((rsrv = f->rsrv) && (un = -rsrv->slen) > 0)
67
{ us = rsrv->data;
68
found = 1;
69
}
70
goto done;
71
}
72
73
while(!found)
74
{ /* fill buffer if necessary */
75
if((n = (ends = f->endb) - (s = f->next)) <= 0)
76
{ /* for unseekable devices, peek-read 1 record */
77
f->getr = rc;
78
f->mode |= SF_RC;
79
80
/* fill buffer the conventional way */
81
if(SFRPEEK(f,s,n) <= 0)
82
{ us = NIL(uchar*);
83
goto done;
84
}
85
else
86
{ ends = s+n;
87
if(f->mode&SF_RC)
88
{ s = ends[-1] == rc ? ends-1 : ends;
89
goto do_copy;
90
}
91
}
92
}
93
94
#if _lib_memchr
95
if(!(s = (uchar*)memchr((char*)s,rc,n)))
96
s = ends;
97
#else
98
while(*s != rc)
99
if((s += 1) == ends)
100
break;
101
#endif
102
do_copy:
103
if(s < ends) /* found separator */
104
{ s += 1; /* include the separator */
105
found = 1;
106
107
if(!us &&
108
(!(type&SF_STRING) || !(f->flags&SF_STRING) ||
109
((f->flags&SF_STRING) && (f->bits&SF_BOTH) ) ) )
110
{ /* returning data in buffer */
111
us = f->next;
112
un = s - f->next;
113
f->next = s;
114
goto done;
115
}
116
}
117
118
/* amount to be read */
119
n = s - f->next;
120
121
if(!found && (_Sfmaxr > 0 && un+n+1 >= _Sfmaxr || (f->flags&SF_STRING))) /* already exceed limit */
122
{ us = NIL(uchar*);
123
goto done;
124
}
125
126
/* get internal buffer */
127
if(!rsrv || rsrv->size < un+n+1)
128
{ if(rsrv)
129
rsrv->slen = un;
130
if((rsrv = _sfrsrv(f,un+n+1)) != NIL(Sfrsrv_t*))
131
us = rsrv->data;
132
else
133
{ us = NIL(uchar*);
134
goto done;
135
}
136
}
137
138
/* now copy data */
139
s = us+un;
140
un += n;
141
ends = f->next;
142
f->next += n;
143
MEMCPY(s,ends,n);
144
}
145
146
done:
147
_Sfi = f->val = un;
148
f->getr = 0;
149
if(found && rc != 0 && (type&SF_STRING) )
150
{ us[un-1] = '\0';
151
if(us >= f->data && us < f->endb)
152
{ f->getr = rc;
153
f->mode |= SF_GETR;
154
}
155
}
156
157
/* prepare for a call to get the broken record */
158
if(rsrv)
159
rsrv->slen = found ? 0 : -un;
160
161
SFOPEN(f,0);
162
163
if(us && (type&SF_LOCKR) )
164
{ f->mode |= SF_PEEK|SF_GETR;
165
f->endr = f->data;
166
}
167
168
SFMTXRETURN(f, (char*)us);
169
}
170
171