diff --git a/src/kits/support/BufferedDataIO.cpp b/src/kits/support/BufferedDataIO.cpp index 7fb3c8f017..1978004d90 100644 --- a/src/kits/support/BufferedDataIO.cpp +++ b/src/kits/support/BufferedDataIO.cpp @@ -95,10 +95,10 @@ BBufferedDataIO::Flush() } else if (bytesWritten >= 0) { fSize -= bytesWritten; fPosition += bytesWritten; - return B_ERROR; + return B_PARTIAL_WRITE; } - return bytesWritten; + return B_OK; } @@ -172,6 +172,15 @@ BBufferedDataIO::Write(const void* buffer, size_t size) TRACE("%p::Write(size %lu)\n", this, size); + if (size > fBufferSize || fBuffer == NULL) { + // request is larger than our buffer, just fill it directly + status_t status = Flush(); + if (status != B_OK) + return status; + + return fStream.Write(buffer, size); + } + if (!fDirty) { // Throw away a read-only buffer if necessary TRACE("%p: throw away previous buffer.\n", this); @@ -180,39 +189,21 @@ BBufferedDataIO::Write(const void* buffer, size_t size) } size_t bytesWritten = 0; - - if (size > fBufferSize || fBuffer == NULL) { - // request is larger than our buffer, just fill it directly - bytesWritten = fSize; - - status_t status = Flush(); - if (status != B_OK) - return status; - - ssize_t streamWritten = fStream.Write(buffer, size); - if (streamWritten >= 0) - return bytesWritten + streamWritten; - - return streamWritten; - } - - bytesWritten = min_c(size, fBufferSize - fSize - fPosition); - TRACE("%p: write %" B_PRIuSIZE " bytes to the buffer.\n", this, - bytesWritten); - memcpy(fBuffer + fPosition + fSize, buffer, bytesWritten); - fSize += bytesWritten; - size -= bytesWritten; - - if (size > 0) { - status_t status = Flush(); - if (status != B_OK) - return status; - - memcpy(fBuffer, (uint8*)buffer + bytesWritten, size); - fPosition = 0; - fSize = size; + while (size > 0) { + size_t toCopy = min_c(size, fBufferSize - (fPosition + fSize)); + TRACE("%p: write %" B_PRIuSIZE " bytes to the buffer.\n", this, + toCopy); + memcpy(fBuffer + (fPosition + fSize), buffer, toCopy); + fSize += toCopy; + bytesWritten += toCopy; + size -= toCopy; fDirty = true; - bytesWritten += size; + + if ((fPosition + fSize) == fBufferSize) { + status_t status = Flush(); + if (status != B_OK) + return bytesWritten; + } } return bytesWritten; diff --git a/src/tests/kits/storage/DataIOTest.cpp b/src/tests/kits/storage/DataIOTest.cpp new file mode 100644 index 0000000000..ae8a63ecb3 --- /dev/null +++ b/src/tests/kits/storage/DataIOTest.cpp @@ -0,0 +1,46 @@ +// DataIOTest.cpp + +#include +#include + +#include + +#include "DataIOTest.h" + + +CppUnit::Test* +DataIOTest::Suite() { + CppUnit::TestSuite *suite = new CppUnit::TestSuite(); + typedef CppUnit::TestCaller TC; + + suite->addTest(new TC("BResourceString::BufferedDataIO Test", + &DataIOTest::BufferedDataIOTest)); + + return suite; +} + + +void +DataIOTest::BufferedDataIOTest() +{ + // very basic test + NextSubTest(); + { + BMallocIO mallocIO; + CPPUNIT_ASSERT(mallocIO.SetSize(1024) == B_OK); + + BBufferedDataIO bufferedDataIO(mallocIO, 8, false); + CPPUNIT_ASSERT(bufferedDataIO.InitCheck() == B_OK); + + CPPUNIT_ASSERT(bufferedDataIO.Write("test ", 5) == 5); + CPPUNIT_ASSERT(bufferedDataIO.Write("test ", 5) == 5); + CPPUNIT_ASSERT(bufferedDataIO.Write("test ", 5) == 5); + + CPPUNIT_ASSERT(bufferedDataIO.Flush() == B_OK); + + CPPUNIT_ASSERT(bufferedDataIO.Write("longer-test", 12) == 12); + + CPPUNIT_ASSERT(mallocIO.Position() == 27); + CPPUNIT_ASSERT(memcmp(mallocIO.Buffer(), "test test test longer-test", 27) == 0); + } +} diff --git a/src/tests/kits/storage/DataIOTest.h b/src/tests/kits/storage/DataIOTest.h new file mode 100644 index 0000000000..235baec492 --- /dev/null +++ b/src/tests/kits/storage/DataIOTest.h @@ -0,0 +1,23 @@ +// DataIOTest.h + +#ifndef __sk_data_io_test_h__ +#define __sk_data_io_test_h__ + +#include +#include + +#include +#include + +#include "BasicTest.h" + +class DataIOTest : public BasicTest +{ +public: + static CppUnit::Test* Suite(); + + void BufferedDataIOTest(); +}; + + +#endif // __sk_data_io_test_h__ diff --git a/src/tests/kits/storage/Jamfile b/src/tests/kits/storage/Jamfile index b2d0d09fc1..59a146f5e6 100644 --- a/src/tests/kits/storage/Jamfile +++ b/src/tests/kits/storage/Jamfile @@ -8,6 +8,7 @@ UnitTestLib libstoragetest.so : StorageKitTestAddon.cpp AppFileInfoTest.cpp BasicTest.cpp + DataIOTest.cpp DirectoryTest.cpp EntryTest.cpp FindDirectoryTest.cpp diff --git a/src/tests/kits/storage/StorageKitTestAddon.cpp b/src/tests/kits/storage/StorageKitTestAddon.cpp index 17f9417707..4cc8bbe0e3 100644 --- a/src/tests/kits/storage/StorageKitTestAddon.cpp +++ b/src/tests/kits/storage/StorageKitTestAddon.cpp @@ -4,6 +4,7 @@ // ##### Include headers for your tests here ##### #include "AppFileInfoTest.h" #include "DirectoryTest.h" +#include "DataIOTest.h" #include "EntryTest.h" #include "FileTest.h" #include "FindDirectoryTest.h" @@ -24,6 +25,7 @@ BTestSuite* getTestSuite() { // ##### Add test suites here ##### suite->addTest("BAppFileInfo", AppFileInfoTest::Suite()); suite->addTest("BDirectory", DirectoryTest::Suite()); + suite->addTest("BDataIO", DataIOTest::Suite()); suite->addTest("BEntry", EntryTest::Suite()); suite->addTest("BFile", FileTest::Suite()); #if 0