@@ -200,7 +200,7 @@ FileIOResult File::read_unlocked(void *data, size_t len) {
200200 }
201201}
202202
203- FileIOResult File::read_unlocked_fbf (uint8_t *data, size_t len) {
203+ FileIOResult File::copy_data_from_buf (uint8_t *data, size_t len) {
204204 cpp::span<uint8_t > bufref (static_cast <uint8_t *>(buf), bufsize);
205205 cpp::span<uint8_t > dataref (static_cast <uint8_t *>(data), len);
206206
@@ -220,12 +220,22 @@ FileIOResult File::read_unlocked_fbf(uint8_t *data, size_t len) {
220220 for (size_t i = 0 ; i < available_data; ++i)
221221 dataref[i] = bufref[i + pos];
222222 read_limit = pos = 0 ; // Reset the pointers.
223+
224+ return available_data;
225+ }
226+
227+ FileIOResult File::read_unlocked_fbf (uint8_t *data, size_t len) {
228+ // Read data from the buffer first.
229+ size_t available_data = copy_data_from_buf (data, len);
230+ if (available_data == len)
231+ return available_data;
232+
223233 // Update the dataref to reflect that fact that we have already
224234 // copied |available_data| into |data|.
225- dataref = cpp::span<uint8_t >(dataref.data () + available_data,
226- dataref.size () - available_data);
227-
228235 size_t to_fetch = len - available_data;
236+ cpp::span<uint8_t > dataref (static_cast <uint8_t *>(data) + available_data,
237+ to_fetch);
238+
229239 if (to_fetch > bufsize) {
230240 auto result = platform_read (this , dataref.data (), to_fetch);
231241 size_t fetched_size = result.value ;
@@ -245,7 +255,7 @@ FileIOResult File::read_unlocked_fbf(uint8_t *data, size_t len) {
245255 read_limit += fetched_size;
246256 size_t transfer_size = fetched_size >= to_fetch ? to_fetch : fetched_size;
247257 for (size_t i = 0 ; i < transfer_size; ++i)
248- dataref[i] = bufref [i];
258+ dataref[i] = buf [i];
249259 pos += transfer_size;
250260 if (result.has_error () || fetched_size < to_fetch) {
251261 if (!result.has_error ())
@@ -257,15 +267,23 @@ FileIOResult File::read_unlocked_fbf(uint8_t *data, size_t len) {
257267}
258268
259269FileIOResult File::read_unlocked_nbf (uint8_t *data, size_t len) {
260- auto result = platform_read (this , data, len);
270+ // Check whether there is a character in the ungetc buffer.
271+ size_t available_data = copy_data_from_buf (data, len);
272+ if (available_data == len)
273+ return available_data;
274+
275+ // Directly copy the data into |data|.
276+ cpp::span<uint8_t > dataref (static_cast <uint8_t *>(data) + available_data,
277+ len - available_data);
278+ auto result = platform_read (this , dataref.data (), dataref.size ());
261279
262- if (result.has_error () || result < len ) {
280+ if (result.has_error () || result < dataref. size () ) {
263281 if (!result.has_error ())
264282 eof = true ;
265283 else
266284 err = true ;
267285 }
268- return result;
286+ return { result + available_data, result. has_error ()} ;
269287}
270288
271289int File::ungetc_unlocked (int c) {
0 commit comments