diff options
Diffstat (limited to 'o3d/import/cross/memory_stream_test.cc')
-rw-r--r-- | o3d/import/cross/memory_stream_test.cc | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/o3d/import/cross/memory_stream_test.cc b/o3d/import/cross/memory_stream_test.cc new file mode 100644 index 0000000..a02fcca --- /dev/null +++ b/o3d/import/cross/memory_stream_test.cc @@ -0,0 +1,320 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// Tests functionality of the MemoryReadStream and MemoryWriteStream +// classes + +#include "core/cross/client.h" +#include "tests/common/win/testing_common.h" +#include "core/cross/error.h" +#include "import/cross/memory_buffer.h" +#include "import/cross/memory_stream.h" +#include "core/cross/types.h" + +#if !defined(IS_LITTLE_ENDIAN) && !defined(IS_BIG_ENDIAN) +#error "IS_LITTLE_ENDIAN or IS_BIG_ENDIAN must be defined!" +#endif + +namespace o3d { + +static char *kTestString = + "Tests functionality of the MemoryReadStream and MemoryWriteStream classes"; + +// Test fixture for MemoryReadStream and MemoryWriteStream. +class MemoryStreamTest : public testing::Test { +}; + +// Test reading from a buffer using MemoryReadStream +TEST_F(MemoryStreamTest, Read) { + int i; + + // Put a test string in a memory buffer + const int kStringLength = strlen(kTestString); + MemoryBuffer<uint8> buffer(kStringLength); + + for (i = 0; i < kStringLength; ++i) { + buffer[i] = kTestString[i]; + } + + // Now, create a read stream on that buffer and verify that it reads + // correctly... + MemoryReadStream read_stream(buffer, buffer.GetLength()); + + EXPECT_EQ(buffer.GetLength(), read_stream.GetTotalStreamLength()); + EXPECT_EQ(kStringLength, read_stream.GetTotalStreamLength()); + + // Read one byte at a time and verify + uint8 c; + for (i = 0; i < kStringLength; ++i) { + c = read_stream.ReadByte(); + EXPECT_EQ(c, kTestString[i]); + } + // Read an extra byte and verify it's zero + c = read_stream.ReadByte(); + EXPECT_EQ(c, 0); + + // Now, create a 2nd read stream + MemoryReadStream read_stream2(buffer, buffer.GetLength()); + // Get direct memory access and check the pointer is correct + const uint8 *p = read_stream2.GetDirectMemoryPointer(); + EXPECT_EQ(const_cast<uint8*>(p), static_cast<uint8*>(buffer)); + + // Test the Read() method + + // First read 5 bytes + MemoryBuffer<uint8> read_buffer(kStringLength); + int bytes_read = read_stream2.Read(read_buffer, 5); + + // Verify bytes read, stream position and remaining byte count + EXPECT_EQ(5, bytes_read); + EXPECT_EQ(5, read_stream2.GetStreamPosition()); + EXPECT_EQ(kStringLength - 5, read_stream2.GetRemainingByteCount()); + + // Next read the remaining bytes + bytes_read = read_stream2.Read(read_buffer + 5, kStringLength - 5); + EXPECT_EQ(kStringLength - 5, bytes_read); + + // Make sure we read the correct data + EXPECT_EQ(0, memcmp(read_buffer, buffer, kStringLength)); + + // Try to read some more, even though we're at stream end + bytes_read = read_stream2.Read(read_buffer, 1000); + EXPECT_EQ(0, bytes_read); // make sure no bytes were read + + // Now, create a 3rd read stream + MemoryReadStream read_stream3(buffer, buffer.GetLength()); + + // Let's test the Skip() method + read_stream3.Skip(6); // skip over the first 6 bytes + + // Read three bytes in a row and verify + uint8 c1 = read_stream3.ReadByte(); + uint8 c2 = read_stream3.ReadByte(); + uint8 c3 = read_stream3.ReadByte(); + EXPECT_EQ('f', c1); + EXPECT_EQ('u', c2); + EXPECT_EQ('n', c3); +} + +// Test Writing to a buffer using MemoryWriteStream +TEST_F(MemoryStreamTest, Write) { + // Create a write stream without assigning it to memory yet + MemoryWriteStream empty_stream; + + // Verfify length is zero + EXPECT_EQ(0, empty_stream.GetTotalStreamLength()); + + // Now, assign it to the string (OK, we can't really write to + // this memory, but we're just checking the API here + const int kStringLength = strlen(kTestString); + empty_stream.Assign(reinterpret_cast<uint8*>(kTestString), kStringLength); + + // Sanity check on length, position, remaining + EXPECT_EQ(kStringLength, empty_stream.GetTotalStreamLength()); + EXPECT_EQ(0, empty_stream.GetStreamPosition()); + EXPECT_EQ(kStringLength, empty_stream.GetRemainingByteCount()); + + // Create a write stream on a buffer we can write to + MemoryBuffer<uint8> buffer(kStringLength); + MemoryWriteStream write_stream(buffer, buffer.GetLength()); + EXPECT_EQ(buffer.GetLength(), kStringLength); + + // Write 5 bytes + uint8 *p = reinterpret_cast<uint8*>(kTestString); + int bytes_written = write_stream.Write(p, 5); + EXPECT_EQ(5, bytes_written); + EXPECT_EQ(5, write_stream.GetStreamPosition()); + EXPECT_EQ(kStringLength - 5, write_stream.GetRemainingByteCount()); + + // Write the remaining bytes in the string + bytes_written = write_stream.Write(p + 5, kStringLength - 5); + EXPECT_EQ(kStringLength - 5, bytes_written); + EXPECT_EQ(kStringLength, write_stream.GetStreamPosition()); + EXPECT_EQ(0, write_stream.GetRemainingByteCount()); + + // Verify we wrote the correct data + EXPECT_EQ(0, memcmp(buffer, kTestString, kStringLength)); + + // Try to write some more even though the buffer is full + bytes_written = write_stream.Write(p, kStringLength); + EXPECT_EQ(0, bytes_written); +} + +// Basic sanity check for endian writing/reading +TEST_F(MemoryStreamTest, EndianSanity16) { + // Sanity check int16 + MemoryBuffer<int16> buffer16(2); + int16 *p = buffer16; + uint8 *p8 = reinterpret_cast<uint8*>(p); + MemoryWriteStream write_stream(p8, sizeof(int16) * 2); + + int16 value = 0x1234; + write_stream.WriteLittleEndianInt16(value); + write_stream.WriteBigEndianInt16(value); + + // Verify that the bytes are in the correct order + uint8 low_byte = value & 0xff; + uint8 high_byte = value >> 8; + + // validate little-endian + EXPECT_EQ(low_byte, p8[0]); + EXPECT_EQ(high_byte, p8[1]); + + // validate big-endian + EXPECT_EQ(high_byte, p8[2]); + EXPECT_EQ(low_byte, p8[3]); +} + +// Basic sanity check for endian writing/reading +TEST_F(MemoryStreamTest, EndianSanity32) { + // Sanity check int32 + MemoryBuffer<int32> buffer32(2); + int32 *p = buffer32; + uint8 *p8 = reinterpret_cast<uint8*>(p); + MemoryWriteStream write_stream(p8, sizeof(int32) * 2); + + int32 value = 0x12345678; + write_stream.WriteLittleEndianInt32(value); + write_stream.WriteBigEndianInt32(value); + + // Verify that the bytes are in the correct order + uint8 byte1 = value & 0xff; + uint8 byte2 = (value >> 8) & 0xff; + uint8 byte3 = (value >> 16) & 0xff; + uint8 byte4 = (value >> 24) & 0xff; + + // validate little-endian + EXPECT_EQ(byte1, p8[0]); + EXPECT_EQ(byte2, p8[1]); + EXPECT_EQ(byte3, p8[2]); + EXPECT_EQ(byte4, p8[3]); + + // validate big-endian + EXPECT_EQ(byte4, p8[4]); + EXPECT_EQ(byte3, p8[5]); + EXPECT_EQ(byte2, p8[6]); + EXPECT_EQ(byte1, p8[7]); +} + +// Basic sanity check for endian writing/reading +TEST_F(MemoryStreamTest, EndianSanityFloat32) { + // Sanity check int32 + MemoryBuffer<float> buffer32(2); + float *p = buffer32; + uint8 *p8 = reinterpret_cast<uint8*>(p); + MemoryWriteStream write_stream(p8, sizeof(int32) * 2); + + float value = 3.14159; + write_stream.WriteLittleEndianFloat32(value); + write_stream.WriteBigEndianFloat32(value); + + // Verify that the bytes are in the correct order + int32 ivalue = *reinterpret_cast<int32*>(&value); // interpret float as int32 + uint8 byte1 = ivalue & 0xff; + uint8 byte2 = (ivalue >> 8) & 0xff; + uint8 byte3 = (ivalue >> 16) & 0xff; + uint8 byte4 = (ivalue >> 24) & 0xff; + + // validate little-endian + EXPECT_EQ(byte1, p8[0]); + EXPECT_EQ(byte2, p8[1]); + EXPECT_EQ(byte3, p8[2]); + EXPECT_EQ(byte4, p8[3]); + + // validate big-endian + EXPECT_EQ(byte4, p8[4]); + EXPECT_EQ(byte3, p8[5]); + EXPECT_EQ(byte2, p8[6]); + EXPECT_EQ(byte1, p8[7]); +} + +// Write then read int16, int32, and float32 little/big endian values +TEST_F(MemoryStreamTest, Endian) { + const int16 kValue1 = 13243; + const int32 kValue2 = 2393043; + const float kValue3 = -0.039483; + const int16 kValue4 = -3984; + const float kValue5 = 1234.5678; + const uint8 kValue6 = 5; // write a single byte to make things interesting + const int32 kValue7 = -3920393; + + size_t total_size = sizeof(kValue1) + + sizeof(kValue2) + + sizeof(kValue3) + + sizeof(kValue4) + + sizeof(kValue5) + + sizeof(kValue6) + + sizeof(kValue7); + + MemoryBuffer<uint8> buffer(total_size); + + // write the values to the buffer + uint8 *p8 = buffer; + MemoryWriteStream write_stream(p8, total_size); + + write_stream.WriteLittleEndianInt16(kValue1); + write_stream.WriteBigEndianInt32(kValue2); + write_stream.WriteLittleEndianFloat32(kValue3); + write_stream.WriteBigEndianInt16(kValue4); + write_stream.WriteBigEndianFloat32(kValue5); + write_stream.Write(&kValue6, 1); + write_stream.WriteLittleEndianInt32(kValue7); + + // now read them back in and verify + int16 read_value1; + int32 read_value2; + float read_value3; + int16 read_value4; + float read_value5; + uint8 read_value6; + int32 read_value7; + MemoryReadStream read_stream(p8, total_size); + + read_value1 = read_stream.ReadLittleEndianInt16(); + read_value2 = read_stream.ReadBigEndianInt32(); + read_value3 = read_stream.ReadLittleEndianFloat32(); + read_value4 = read_stream.ReadBigEndianInt16(); + read_value5 = read_stream.ReadBigEndianFloat32(); + read_stream.Read(&read_value6, 1); + read_value7 = read_stream.ReadLittleEndianInt32(); + + // Validate + EXPECT_EQ(read_value1, kValue1); + EXPECT_EQ(read_value2, kValue2); + EXPECT_EQ(read_value3, kValue3); + EXPECT_EQ(read_value4, kValue4); + EXPECT_EQ(read_value5, kValue5); + EXPECT_EQ(read_value6, kValue6); + EXPECT_EQ(read_value7, kValue7); +} + +} // namespace o3d |