diff --git a/src/MyFirstUDRKit.cpp b/src/MyFirstUDRKit.cpp index 3ea94e2..056dff3 100644 --- a/src/MyFirstUDRKit.cpp +++ b/src/MyFirstUDRKit.cpp @@ -74,7 +74,7 @@ #include #define SYSERROR() GetLastError() #else -#include +#include #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,21 +301,32 @@ 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)); @@ -328,6 +342,7 @@ FB_UDR_EXECUTE_FUNCTION std::vector 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;