@@ -339,71 +339,78 @@ size_t FSNode::getSize() const
339339// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
340340size_t FSNode::read (ByteBuffer& buffer, size_t size) const
341341{
342- size_t sizeRead = 0 ;
343-
344342 // File must actually exist
345343 if (!(exists () && isReadable ()))
346344 throw std::runtime_error (" File not found/readable" );
347345
348346 // First let the private subclass attempt to open the file
349347 if (_realNode)
350- if (sizeRead = _realNode->read (buffer, size); sizeRead > 0 )
348+ {
349+ const size_t sizeRead = _realNode->read (buffer, size);
350+ if (sizeRead > 0 )
351351 return sizeRead;
352+ }
352353
353354 // Otherwise, the default behaviour is to read from a normal C++ ifstream
354355 std::ifstream in (getPath (), std::ios::binary);
355- if (in)
356- {
357- in.seekg (0 , std::ios::end);
358- sizeRead = static_cast <size_t >(in.tellg ());
359- in.seekg (0 , std::ios::beg);
356+ if (!in)
357+ throw std::runtime_error (" File open/read error" );
360358
361- if (sizeRead == 0 )
362- throw std::runtime_error (" Zero-byte file" );
363- else if (size > 0 ) // If a requested size to read is provided, honour it
364- sizeRead = std::min (sizeRead, size);
359+ in.seekg (0 , std::ios::end);
360+ const std::streampos fileSize = in.tellg ();
361+ if (fileSize <= 0 )
362+ throw std::runtime_error (" Zero-byte file" );
363+ in.seekg (0 , std::ios::beg);
365364
366- buffer = std::make_unique<uInt8[]>(sizeRead);
367- in.read (reinterpret_cast <char *>(buffer.get ()), sizeRead);
368- }
369- else
370- throw std::runtime_error (" File open/read error" );
365+ // If a requested size to read is provided (size > 0), honour it
366+ const size_t sizeRead = (size > 0 )
367+ ? std::min (static_cast <size_t >(fileSize), size)
368+ : static_cast <size_t >(fileSize);
369+
370+ buffer = std::make_unique<uInt8[]>(sizeRead);
371+ in.read (reinterpret_cast <char *>(buffer.get ()),
372+ static_cast <std::streamsize>(sizeRead));
371373
372- return sizeRead;
374+ if (!in)
375+ throw std::runtime_error (" File read error" );
376+
377+ return static_cast <size_t >(in.gcount ());
373378}
374379
375380// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
376381size_t FSNode::read (std::stringstream& buffer) const
377382{
378- size_t sizeRead = 0 ;
379-
380383 // File must actually exist
381384 if (!(exists () && isReadable ()))
382385 throw std::runtime_error (" File not found/readable" );
383386
384387 // First let the private subclass attempt to open the file
385388 if (_realNode)
386- if (sizeRead = _realNode->read (buffer); sizeRead > 0 )
389+ {
390+ const size_t sizeRead = _realNode->read (buffer);
391+ if (sizeRead > 0 )
387392 return sizeRead;
393+ }
388394
389395 // Otherwise, the default behaviour is to read from a normal C++ ifstream
390396 // and convert to a stringstream
391397 std::ifstream in (getPath ());
392- if (in)
393- {
394- in.seekg (0 , std::ios::end);
395- sizeRead = static_cast <size_t >(in.tellg ());
396- in.seekg (0 , std::ios::beg);
398+ if (!in)
399+ throw std::runtime_error (" File open/read error" );
397400
398- if (sizeRead == 0 )
399- throw std::runtime_error (" Zero-byte file" );
401+ // Get file size
402+ in.seekg (0 , std::ios::end);
403+ const std::streampos fileSize = in.tellg ();
404+ if (fileSize <= 0 )
405+ throw std::runtime_error (" Zero-byte file" );
406+ in.seekg (0 , std::ios::beg);
400407
401- buffer << in. rdbuf ();
402- }
403- else
404- throw std::runtime_error (" File open/ read error" );
408+ // Read into buffer and verify
409+ buffer << in. rdbuf ();
410+ if (!in)
411+ throw std::runtime_error (" File read error" );
405412
406- return sizeRead ;
413+ return static_cast < size_t >(fileSize) ;
407414}
408415
409416// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -420,13 +427,15 @@ size_t FSNode::write(const ByteBuffer& buffer, size_t size) const
420427 std::ofstream out (getPath (), std::ios::binary);
421428 if (out)
422429 {
423- out.write (reinterpret_cast <const char *>(buffer.get ()), size);
424-
425- out.seekp (0 , std::ios::end);
426- sizeWritten = static_cast <size_t >(out.tellp ());
430+ out.write (reinterpret_cast <const char *>(buffer.get ()),
431+ static_cast <std::streamsize>(size));
432+ if (out)
433+ sizeWritten = size;
434+ else
435+ throw std::runtime_error (" File write error" );
427436 }
428437 else
429- throw std::runtime_error (" File open/write error" );
438+ throw std::runtime_error (" File open error" );
430439
431440 return sizeWritten;
432441}
@@ -445,10 +454,9 @@ size_t FSNode::write(const std::ostringstream& buffer) const
445454 std::ofstream out (getPath ());
446455 if (out)
447456 {
448- out << buffer.rdbuf ();
449-
450- out.seekp (0 , std::ios::end);
451- sizeWritten = static_cast <size_t >(out.tellp ());
457+ const auto view = buffer.view ();
458+ out.write (view.data (), static_cast <std::streamsize>(view.size ()));
459+ sizeWritten = view.size ();
452460 }
453461 else
454462 throw std::runtime_error (" File open/write error" );
0 commit comments