Resize buffer if BytesRead is less than MaxSegmentSize

This commit is contained in:
Paul Reeves 2023-02-03 17:09:22 +01:00
parent 29c3265622
commit 450e9e7d34
1 changed files with 30 additions and 8 deletions

View File

@ -74,7 +74,7 @@
#include <windows.h>
#define SYSERROR() GetLastError()
#else
#include <errno.h>
#include <cerrno>
#define SYSERROR() errno
#endif
@ -180,6 +180,8 @@ FB_UDR_END_FUNCTION
* external name 'MyFirstUDRKit!MFKLoadBlobFromFile!Load file and save to Blob'
* engine udr;
***/
// NOTE This function would be better as a procedure as that would allow it
// to return the bytes written to the blob.
FB_UDR_BEGIN_FUNCTION (MFK_LoadBlobFromFile)
//BEGIN
FB_UDR_MESSAGE(InMessage,
@ -205,8 +207,9 @@ FB_UDR_EXECUTE_FUNCTION
std::ifstream FileReader;
FileReader.open( in->afilename.str , std::ifstream::binary );
FileReader.open( in->afilename.str , std::ifstream::binary | std::ifstream::in );
if (! FileReader.is_open()) {
// if (! FileReader.good()) {
out->ablobNull = FB_TRUE;
return;
}
@ -238,7 +241,7 @@ FB_UDR_EXECUTE_FUNCTION
// What do we do with the partially written blob? Is cancel enough?
blob->cancel( status );
}
// ****** IT IS VITAL TO SET THIS IF WRITING TO BLOB SUCCEEDED ********
// ****** IT IS VITAL TO SET THIS IF WRITING TO BLOB WAS SUCCESSFUL ******* //
out->ablobNull = FB_FALSE;
blob->close( status );
@ -298,22 +301,33 @@ FB_UDR_EXECUTE_FUNCTION
/*
* DOC NOTE - We do not test for existence of the file here!
* This should be done prior to calling this function.
*/
std::ofstream FileWriter ( in->afilename.str , std::ofstream::binary );
std::ofstream FileWriter ( in->afilename.str , std::ofstream::binary | std::ofstream::out );
if (! FileWriter.is_open()) {
// if (! FileWriter.good()) {
out->resultNull = FB_TRUE;
// Convert system error to a negative value and assign to result
out->result = ( SYSERROR() * -1 );
// important to set this to false here otherwise the error code will
// be hidden and NULL returned to the firebird engine. This is because
// the test for out->resultNull has precedence.
// important to set out->resultNull to false here otherwise the error
// code willbe hidden and NULL returned to the firebird engine. This
// is because the test for out->resultNull has precedence.
if ( out->result < 0 ) {
out->resultNull = FB_FALSE;
}
return;
}
// This might be useful but doesn't work because it requires libc++ and we compile with libstdc++ on linux
// else {
// std::filesystem::permissions ( in->afilename.str, std::filesystem::perms::owner_all | std::filesystem::perms::group_all,
// std::filesystem::perm_options::add );
// }
att.reset(context->getAttachment(status));
tra.reset(context->getTransaction(status));
@ -328,6 +342,7 @@ FB_UDR_EXECUTE_FUNCTION
std::vector<std::uint8_t> Buffer (MaxSegmentSize, 0);
unsigned BytesRead = 0;
unsigned BufferSize = 0;
for (bool Eof = false; !Eof; )
{
@ -336,6 +351,13 @@ FB_UDR_EXECUTE_FUNCTION
case IStatus::RESULT_OK:
case IStatus::RESULT_SEGMENT:
{
BufferSize = Buffer.size();
if ( BufferSize < BytesRead) {
BytesRead = BufferSize;
}
if ( BytesRead < MaxSegmentSize) {
Buffer.resize( BytesRead);
}
FileWriter.write( (char *) Buffer.data(), Buffer.size() );
out->result += BytesRead;
continue;