FreeBASIC  0.91.0
file_get.c
Go to the documentation of this file.
1 /* get # function */
2 
3 #include "fb.h"
4 
6  (
8  fb_off_t pos,
9  void *dst,
10  size_t length,
11  size_t *bytesread,
12  int adjust_rec_pos,
13  int is_unicode
14  )
15 {
16  int res;
17  size_t chars, read_chars;
18  char *pachData = (char *)dst;
19 
20  if( bytesread )
21  *bytesread = 0;
22 
23  if( !FB_HANDLE_USED(handle) )
25 
26  if( pos < 0 )
28 
29  FB_LOCK();
30 
32 
33  chars = length;
34 
35  /* seek to newpos */
36  if( pos > 0 )
37  res = fb_FileSeekEx( handle, pos );
38 
39  /* any data in the put-back buffer? */
40  if( handle->putback_size != 0 )
41  {
42  size_t bytes, len;
43  FB_WCHAR *wcp;
44  char *cp;
45 
46  bytes = chars;
47  if( handle->encod != FB_FILE_ENCOD_ASCII )
48  bytes *= sizeof( FB_WCHAR );
49 
50  bytes = (handle->putback_size >= bytes? bytes : handle->putback_size);
51 
52  if( !is_unicode )
53  {
54  if( handle->encod == FB_FILE_ENCOD_ASCII )
55  memcpy( pachData, handle->putback_buffer, bytes );
56  else
57  {
58  cp = pachData;
59  wcp = (FB_WCHAR *)handle->putback_buffer;
60  len = bytes;
61  while( len > 0 )
62  {
63  *cp++ = *wcp++;
64  len -= sizeof( FB_WCHAR );
65  }
66  }
67  }
68  else
69  {
70  if( handle->encod != FB_FILE_ENCOD_ASCII )
71  memcpy( pachData, handle->putback_buffer, bytes );
72  else
73  {
74  cp = pachData;
75  wcp = (FB_WCHAR *)handle->putback_buffer;
76  len = bytes;
77  while( len-- > 0 )
78  *wcp++ = *cp++;
79  }
80  }
81 
82  handle->putback_size -= bytes;
83  if( handle->putback_size != 0 )
84  {
85  memmove( handle->putback_buffer,
86  handle->putback_buffer + bytes,
87  handle->putback_size );
88  }
89 
90  pachData += bytes;
91 
92  if( handle->encod != FB_FILE_ENCOD_ASCII )
93  bytes /= sizeof( FB_WCHAR );
94 
95  read_chars = bytes;
96  chars -= bytes;
97  }
98  else
99  read_chars = 0;
100 
101  if ( (res == FB_RTERROR_OK) && (chars != 0) )
102  {
103  /* do read */
104  if( !is_unicode )
105  {
106  if( handle->hooks->pfnRead == NULL )
108  else
109  {
110  res = handle->hooks->pfnRead( handle, pachData, &chars );
111  read_chars += chars;
112  }
113  }
114  else
115  {
116  if( handle->hooks->pfnReadWstr == NULL )
118  else
119  {
120  res = handle->hooks->pfnReadWstr( handle, (FB_WCHAR *)pachData, &chars );
121  read_chars += chars;
122  }
123  }
124  }
125 
126  if( handle->mode == FB_FILE_MODE_RANDOM &&
127  res == FB_RTERROR_OK &&
128  adjust_rec_pos &&
129  handle->len != 0 &&
130  handle->hooks->pfnSeek != NULL )
131  {
132  /* if in random mode, reads must be of reclen.
133  * The device must also support the SEEK method and the length
134  * must be non-null */
135 
136  if( length != handle->len )
138 
139 
140  size_t skip_size = (handle->len -
141  ((!is_unicode? read_chars: read_chars*sizeof( FB_WCHAR )) % handle->len)) % handle->len;
142 
143  if( skip_size != 0 )
144  {
145  /* don't forget the put back buffer */
146  if( skip_size > handle->putback_size )
147  {
148  skip_size -= handle->putback_size;
149  handle->putback_size = 0;
150  }
151  else
152  {
153  handle->putback_size -= skip_size;
154  skip_size = 0;
155  }
156  }
157 
158  if (skip_size!=0)
159  {
160  /* devices that don't support seek should simulate it
161  with read or never allow to be opened for random access */
162  handle->hooks->pfnSeek( handle, skip_size, SEEK_CUR );
163  }
164  }
165 
166  if( bytesread )
167  *bytesread = read_chars;
168 
169  FB_UNLOCK();
170 
171  /* set the error code again - handle->hooks->pfnSeek() may have reset it */
172  return fb_ErrorSetNum( res );
173 }
174 
175 /*:::::*/
176 /* Can fb_FileGetData() be removed? it's not used by the rtlib
177  * nor is it referenced by fbc? Compatibility with old libs? [jeffm]
178  */
179 int fb_FileGetData( int fnum, fb_off_t pos, void *dst, size_t chars, int adjust_rec_pos )
180 {
181  return fb_FileGetDataEx( FB_FILE_TO_HANDLE(fnum),
182  pos,
183  dst,
184  chars,
185  NULL,
186  adjust_rec_pos,
187  FALSE );
188 }
189 
190 FBCALL int fb_FileGet( int fnum, int pos, void *dst, size_t chars )
191 {
192  return fb_FileGetDataEx( FB_FILE_TO_HANDLE(fnum),
193  pos,
194  dst,
195  chars,
196  NULL,
197  TRUE,
198  FALSE );
199 }
200 
201 FBCALL int fb_FileGetLarge( int fnum, long long pos, void *dst, size_t chars )
202 {
203  return fb_FileGetDataEx( FB_FILE_TO_HANDLE(fnum),
204  pos,
205  dst,
206  chars,
207  NULL,
208  TRUE,
209  FALSE );
210 }
211 
212 FBCALL int fb_FileGetIOB( int fnum, int pos, void *dst, size_t chars, size_t *bytesread )
213 {
214  return fb_FileGetDataEx( FB_FILE_TO_HANDLE(fnum),
215  pos,
216  dst,
217  chars,
218  bytesread,
219  TRUE,
220  FALSE );
221 }
222 
223 FBCALL int fb_FileGetLargeIOB( int fnum, long long pos, void *dst, size_t chars, size_t *bytesread )
224 {
225  return fb_FileGetDataEx( FB_FILE_TO_HANDLE(fnum),
226  pos,
227  dst,
228  chars,
229  bytesread,
230  TRUE,
231  FALSE );
232 }