Subversion Repositories Kolibri OS

Rev

Rev 1906 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1906 Rev 3065
1
/*
1
/*
2
 * Copyright (c) 1990, 2007 The Regents of the University of California.
2
 * Copyright (c) 1990, 2007 The Regents of the University of California.
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms are permitted
5
 * Redistribution and use in source and binary forms are permitted
6
 * provided that the above copyright notice and this paragraph are
6
 * provided that the above copyright notice and this paragraph are
7
 * duplicated in all such forms and that any documentation,
7
 * duplicated in all such forms and that any documentation,
8
 * advertising materials, and other materials related to such
8
 * advertising materials, and other materials related to such
9
 * distribution and use acknowledge that the software was developed
9
 * distribution and use acknowledge that the software was developed
10
 * by the University of California, Berkeley.  The name of the
10
 * by the University of California, Berkeley.  The name of the
11
 * University may not be used to endorse or promote products derived
11
 * University may not be used to endorse or promote products derived
12
 * from this software without specific prior written permission.
12
 * from this software without specific prior written permission.
13
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
13
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
14
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
 */
16
 */
17
 
17
 
18
/*
18
/*
19
FUNCTION
19
FUNCTION
20
<>---read array elements from a file
20
<>---read array elements from a file
21
 
21
 
22
INDEX
22
INDEX
23
	fread
23
	fread
24
INDEX
24
INDEX
25
	_fread_r
25
	_fread_r
26
 
26
 
27
ANSI_SYNOPSIS
27
ANSI_SYNOPSIS
28
	#include 
28
	#include 
29
	size_t fread(void *<[buf]>, size_t <[size]>, size_t <[count]>,
29
	size_t fread(void *<[buf]>, size_t <[size]>, size_t <[count]>,
30
		     FILE *<[fp]>);
30
		     FILE *<[fp]>);
31
 
31
 
32
	#include 
32
	#include 
33
	size_t _fread_r(struct _reent *<[ptr]>, void *<[buf]>,
33
	size_t _fread_r(struct _reent *<[ptr]>, void *<[buf]>,
34
	                size_t <[size]>, size_t <[count]>, FILE *<[fp]>);
34
	                size_t <[size]>, size_t <[count]>, FILE *<[fp]>);
35
 
35
 
36
TRAD_SYNOPSIS
36
TRAD_SYNOPSIS
37
	#include 
37
	#include 
38
	size_t fread(<[buf]>, <[size]>, <[count]>, <[fp]>)
38
	size_t fread(<[buf]>, <[size]>, <[count]>, <[fp]>)
39
	char *<[buf]>;
39
	char *<[buf]>;
40
	size_t <[size]>;
40
	size_t <[size]>;
41
	size_t <[count]>;
41
	size_t <[count]>;
42
	FILE *<[fp]>;
42
	FILE *<[fp]>;
43
 
43
 
44
	#include 
44
	#include 
45
	size_t _fread_r(<[ptr]>, <[buf]>, <[size]>, <[count]>, <[fp]>)
45
	size_t _fread_r(<[ptr]>, <[buf]>, <[size]>, <[count]>, <[fp]>)
46
	struct _reent *<[ptr]>;
46
	struct _reent *<[ptr]>;
47
	char *<[buf]>;
47
	char *<[buf]>;
48
	size_t <[size]>;
48
	size_t <[size]>;
49
	size_t <[count]>;
49
	size_t <[count]>;
50
	FILE *<[fp]>;
50
	FILE *<[fp]>;
51
 
51
 
52
DESCRIPTION
52
DESCRIPTION
53
<> attempts to copy, from the file or stream identified by
53
<> attempts to copy, from the file or stream identified by
54
<[fp]>, <[count]> elements (each of size <[size]>) into memory,
54
<[fp]>, <[count]> elements (each of size <[size]>) into memory,
55
starting at <[buf]>.   <> may copy fewer elements than
55
starting at <[buf]>.   <> may copy fewer elements than
56
<[count]> if an error, or end of file, intervenes.
56
<[count]> if an error, or end of file, intervenes.
57
 
57
 
58
<> also advances the file position indicator (if any) for
58
<> also advances the file position indicator (if any) for
59
<[fp]> by the number of @emph{characters} actually read.
59
<[fp]> by the number of @emph{characters} actually read.
60
 
60
 
61
<<_fread_r>> is simply the reentrant version of <> that
61
<<_fread_r>> is simply the reentrant version of <> that
62
takes an additional reentrant structure pointer argument: <[ptr]>.
62
takes an additional reentrant structure pointer argument: <[ptr]>.
63
 
63
 
64
RETURNS
64
RETURNS
65
The result of <> is the number of elements it succeeded in
65
The result of <> is the number of elements it succeeded in
66
reading.
66
reading.
67
 
67
 
68
PORTABILITY
68
PORTABILITY
69
ANSI C requires <>.
69
ANSI C requires <>.
70
 
70
 
71
Supporting OS subroutines required: <>, <>, <>,
71
Supporting OS subroutines required: <>, <>, <>,
72
<>, <>, <>, <>.
72
<>, <>, <>, <>.
73
*/
73
*/
74
 
74
 
75
#include <_ansi.h>
75
#include <_ansi.h>
76
#include 
76
#include 
77
#include 
77
#include 
78
#include 
78
#include 
79
#include "local.h"
79
#include "local.h"
80
 
80
 
81
#ifdef __SCLE
81
#ifdef __SCLE
82
static size_t
82
static size_t
83
_DEFUN(crlf_r, (ptr, fp, buf, count, eof),
83
_DEFUN(crlf_r, (ptr, fp, buf, count, eof),
84
       struct _reent * ptr _AND
84
       struct _reent * ptr _AND
85
       FILE * fp _AND
85
       FILE * fp _AND
86
       char * buf _AND
86
       char * buf _AND
87
       size_t count _AND
87
       size_t count _AND
88
       int eof)
88
       int eof)
89
{
89
{
90
  int r;
90
  int r;
91
  char *s, *d, *e;
91
  char *s, *d, *e;
92
 
92
 
93
  if (count == 0)
93
  if (count == 0)
94
    return 0;
94
    return 0;
95
 
95
 
96
  e = buf + count;
96
  e = buf + count;
97
  for (s=d=buf; s
97
  for (s=d=buf; s
98
    {
98
    {
99
      if (*s == '\r' && s[1] == '\n')
99
      if (*s == '\r' && s[1] == '\n')
100
        s++;
100
        s++;
101
      *d++ = *s;
101
      *d++ = *s;
102
    }
102
    }
103
  if (s < e)
103
  if (s < e)
104
    {
104
    {
105
      if (*s == '\r')
105
      if (*s == '\r')
106
        {
106
        {
107
          int c = __sgetc_raw_r (ptr, fp);
107
          int c = __sgetc_raw_r (ptr, fp);
108
          if (c == '\n')
108
          if (c == '\n')
109
            *s = '\n';
109
            *s = '\n';
110
          else
110
          else
111
            ungetc (c, fp);
111
            ungetc (c, fp);
112
        }
112
        }
113
      *d++ = *s++;
113
      *d++ = *s++;
114
    }
114
    }
115
 
115
 
116
 
116
 
117
  while (d < e)
117
  while (d < e)
118
    {
118
    {
119
      r = _getc_r (ptr, fp);
119
      r = _getc_r (ptr, fp);
120
      if (r == EOF)
120
      if (r == EOF)
121
        return count - (e-d);
121
        return count - (e-d);
122
      *d++ = r;
122
      *d++ = r;
123
    }
123
    }
124
 
124
 
125
  return count;
125
  return count;
126
  
126
  
127
}
127
}
128
 
128
 
129
#endif
129
#endif
130
 
130
 
131
size_t
131
size_t
132
_DEFUN(_fread_r, (ptr, buf, size, count, fp),
132
_DEFUN(_fread_r, (ptr, buf, size, count, fp),
133
       struct _reent * ptr _AND
133
       struct _reent * ptr _AND
134
       _PTR buf _AND
134
       _PTR buf _AND
135
       size_t size _AND
135
       size_t size _AND
136
       size_t count _AND
136
       size_t count _AND
137
       FILE * fp)
137
       FILE * fp)
138
{
138
{
139
  register size_t resid;
139
  register size_t resid;
140
  register char *p;
140
  register char *p;
141
  register int r;
141
  register int r;
142
  size_t total;
142
  size_t total;
143
 
143
 
144
  if ((resid = count * size) == 0)
144
  if ((resid = count * size) == 0)
145
    return 0;
145
    return 0;
146
 
146
 
147
  CHECK_INIT(ptr, fp);
147
  CHECK_INIT(ptr, fp);
148
 
-
 
149
  __sfp_lock_acquire ();
148
 
150
  _flockfile (fp);
149
  _flockfile (fp);
151
  ORIENT (fp, -1);
150
  ORIENT (fp, -1);
152
  if (fp->_r < 0)
151
  if (fp->_r < 0)
153
    fp->_r = 0;
152
    fp->_r = 0;
154
  total = resid;
153
  total = resid;
155
  p = buf;
154
  p = buf;
156
 
155
 
157
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
156
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
158
 
157
 
159
  /* Optimize unbuffered I/O.  */
158
  /* Optimize unbuffered I/O.  */
160
  if (fp->_flags & __SNBF)
159
  if (fp->_flags & __SNBF)
161
    {
160
    {
162
      /* First copy any available characters from ungetc buffer.  */
161
      /* First copy any available characters from ungetc buffer.  */
163
      int copy_size = resid > fp->_r ? fp->_r : resid;
162
      int copy_size = resid > fp->_r ? fp->_r : resid;
164
      _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) copy_size);
163
      _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) copy_size);
165
      fp->_p += copy_size;
164
      fp->_p += copy_size;
166
      fp->_r -= copy_size;
165
      fp->_r -= copy_size;
167
      p += copy_size;
166
      p += copy_size;
168
      resid -= copy_size;
167
      resid -= copy_size;
169
 
168
 
170
      /* If still more data needed, free any allocated ungetc buffer.  */
169
      /* If still more data needed, free any allocated ungetc buffer.  */
171
      if (HASUB (fp) && resid > 0)
170
      if (HASUB (fp) && resid > 0)
172
	FREEUB (ptr, fp);
171
	FREEUB (ptr, fp);
173
 
172
 
174
      /* Finally read directly into user's buffer if needed.  */
173
      /* Finally read directly into user's buffer if needed.  */
175
      while (resid > 0)
174
      while (resid > 0)
176
	{
175
	{
177
	  int rc = 0;
176
	  int rc = 0;
178
	  /* save fp buffering state */
177
	  /* save fp buffering state */
179
	  void *old_base = fp->_bf._base;
178
	  void *old_base = fp->_bf._base;
180
	  void * old_p = fp->_p;
179
	  void * old_p = fp->_p;
181
	  int old_size = fp->_bf._size;
180
	  int old_size = fp->_bf._size;
182
	  /* allow __refill to use user's buffer */
181
	  /* allow __refill to use user's buffer */
183
	  fp->_bf._base = (unsigned char *) p;
182
	  fp->_bf._base = (unsigned char *) p;
184
	  fp->_bf._size = resid;
183
	  fp->_bf._size = resid;
185
	  fp->_p = (unsigned char *) p;
184
	  fp->_p = (unsigned char *) p;
186
	  rc = __srefill_r (ptr, fp);
185
	  rc = __srefill_r (ptr, fp);
187
	  /* restore fp buffering back to original state */
186
	  /* restore fp buffering back to original state */
188
	  fp->_bf._base = old_base;
187
	  fp->_bf._base = old_base;
189
	  fp->_bf._size = old_size;
188
	  fp->_bf._size = old_size;
190
	  fp->_p = old_p;
189
	  fp->_p = old_p;
191
	  resid -= fp->_r;
190
	  resid -= fp->_r;
192
	  p += fp->_r;
191
	  p += fp->_r;
193
	  fp->_r = 0;
192
	  fp->_r = 0;
194
	  if (rc)
193
	  if (rc)
195
	    {
194
	    {
196
#ifdef __SCLE
195
#ifdef __SCLE
197
              if (fp->_flags & __SCLE)
196
              if (fp->_flags & __SCLE)
198
	        {
197
	        {
199
	          _funlockfile (fp);
198
	          _funlockfile (fp);
200
		  __sfp_lock_release ();
-
 
201
	          return crlf_r (ptr, fp, buf, total-resid, 1) / size;
199
	          return crlf_r (ptr, fp, buf, total-resid, 1) / size;
202
	        }
200
	        }
203
#endif
201
#endif
204
	      _funlockfile (fp);
202
	      _funlockfile (fp);
205
	      __sfp_lock_release ();
-
 
206
	      return (total - resid) / size;
203
	      return (total - resid) / size;
207
	    }
204
	    }
208
	}
205
	}
209
    }
206
    }
210
  else
207
  else
211
#endif /* !PREFER_SIZE_OVER_SPEED && !__OPTIMIZE_SIZE__ */
208
#endif /* !PREFER_SIZE_OVER_SPEED && !__OPTIMIZE_SIZE__ */
212
    {
209
    {
213
      while (resid > (r = fp->_r))
210
      while (resid > (r = fp->_r))
214
	{
211
	{
215
	  _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) r);
212
	  _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) r);
216
	  fp->_p += r;
213
	  fp->_p += r;
217
	  /* fp->_r = 0 ... done in __srefill */
214
	  /* fp->_r = 0 ... done in __srefill */
218
	  p += r;
215
	  p += r;
219
	  resid -= r;
216
	  resid -= r;
220
	  if (__srefill_r (ptr, fp))
217
	  if (__srefill_r (ptr, fp))
221
	    {
218
	    {
222
	      /* no more input: return partial result */
219
	      /* no more input: return partial result */
223
#ifdef __SCLE
220
#ifdef __SCLE
224
	      if (fp->_flags & __SCLE)
221
	      if (fp->_flags & __SCLE)
225
		{
222
		{
226
		  _funlockfile (fp);
223
		  _funlockfile (fp);
227
		  __sfp_lock_release ();
-
 
228
		  return crlf_r (ptr, fp, buf, total-resid, 1) / size;
224
		  return crlf_r (ptr, fp, buf, total-resid, 1) / size;
229
		}
225
		}
230
#endif
226
#endif
231
	      _funlockfile (fp);
227
	      _funlockfile (fp);
232
	      __sfp_lock_release ();
-
 
233
	      return (total - resid) / size;
228
	      return (total - resid) / size;
234
	    }
229
	    }
235
	}
230
	}
236
      _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, resid);
231
      _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, resid);
237
      fp->_r -= resid;
232
      fp->_r -= resid;
238
      fp->_p += resid;
233
      fp->_p += resid;
239
    }
234
    }
240
 
235
 
241
  /* Perform any CR/LF clean-up if necessary.  */
236
  /* Perform any CR/LF clean-up if necessary.  */
242
#ifdef __SCLE
237
#ifdef __SCLE
243
  if (fp->_flags & __SCLE)
238
  if (fp->_flags & __SCLE)
244
    {
239
    {
245
      _funlockfile (fp);
240
      _funlockfile (fp);
246
      __sfp_lock_release ();
-
 
247
      return crlf_r(ptr, fp, buf, total, 0) / size;
241
      return crlf_r(ptr, fp, buf, total, 0) / size;
248
    }
242
    }
249
#endif
243
#endif
250
  _funlockfile (fp);
244
  _funlockfile (fp);
251
  __sfp_lock_release ();
-
 
252
  return count;
245
  return count;
253
}
246
}
254
 
247
 
255
#ifndef _REENT_ONLY
248
#ifndef _REENT_ONLY
256
size_t
249
size_t
257
_DEFUN(fread, (buf, size, count, fp),
250
_DEFUN(fread, (buf, size, count, fp),
258
       _PTR buf _AND
251
       _PTR buf _AND
259
       size_t size _AND
252
       size_t size _AND
260
       size_t count _AND
253
       size_t count _AND
261
       FILE * fp)
254
       FILE * fp)
262
{
255
{
263
   return _fread_r (_REENT, buf, size, count, fp);
256
   return _fread_r (_REENT, buf, size, count, fp);
264
}
257
}
265
#endif
258
#endif