We need to change code in writeSamples. Let’s start with a couple tests!
wav/6/WavReaderTest.cpp | |
| #include "CppUTest/TestHarness.h" |
| #include "WavReader.h" |
| #include <iostream> |
| #include <string> |
| #include <sstream> |
| |
| using namespace std; |
| |
| TEST_GROUP(WavReader_WriteSamples) |
| { |
| WavReader reader{"",""}; |
| ostringstream out; |
| }; |
| |
| TEST(WavReader_WriteSamples, WritesSingleSample) { |
| char data[] { "abcd" }; |
| uint32_t bytesPerSample { 1 }; |
| uint32_t startingSample { 0 }; |
| uint32_t samplesToWrite { 1 }; |
| reader.writeSamples(&out, data, startingSample, samplesToWrite, bytesPerSample); |
| CHECK_EQUAL("a", out.str()); |
| } |
| |
| TEST(WavReader_WriteSamples, WritesMultibyteSampleFromMiddle) { |
| char data[] { "0123456789ABCDEFG" }; |
| uint32_t bytesPerSample { 2 }; |
| uint32_t startingSample { 4 }; |
| uint32_t samplesToWrite { 3 }; |
| |
| reader.writeSamples(&out, data, startingSample, samplesToWrite, bytesPerSample); |
| CHECK_EQUAL("89ABCD", out.str()); |
| } |
The direct tests against writeSamples help us understand the looping behavior in isolation. They’re not great, though. The test WritesMultibyteSampleFromMiddle requires careful reading and a little bit of math. How would you make it more directly expressive?
Rather than slow down our tests by using actual files, we use fast, in-memory string objects of type std::ostringstream. Doing so requires changing the interface of writeSamples to take std::ostream objects, the common type from which both std::ofstream and std::ostringstream derive. More specifically, we alter the interface to take a pointer to an std::ostream. Production code can pass the address of a file stream; tests can pass the address of a string stream. We change the dereferencing of the writeSamples local variable out to use pointer semantics.
wav/6/WavReader.cpp | |
| writeSamples(&out, data, startingSample, samplesToWrite, bytesPerSample); |
wav/6/WavReader.cpp | |
* | void WavReader::writeSamples(ostream* out, char* data, |
| uint32_t startingSample, |
| uint32_t samplesToWrite, |
| uint32_t bytesPerSample) { |
| rLog(channel, "writing %i samples", samplesToWrite); |
| |
| for (auto sample = startingSample; |
| sample < startingSample + samplesToWrite; |
| sample++) { |
| auto byteOffsetForSample = sample * bytesPerSample; |
| for (uint32_t byte{0}; byte < bytesPerSample; byte++) |
* | out->put(data[byteOffsetForSample + byte]); |
| } |
| } |
18.220.245.233