2014-05-13 18:00:26 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-03-28 13:30:15 +01:00
|
|
|
#include "rtc_base/memory/fifo_buffer.h"
|
2019-07-05 19:08:33 +02:00
|
|
|
|
2018-11-28 16:47:49 +01:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include "test/gtest.h"
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
namespace rtc {
|
|
|
|
|
|
|
|
|
|
TEST(FifoBufferTest, TestAll) {
|
2022-05-20 09:12:57 +02:00
|
|
|
rtc::AutoThread main_thread;
|
2014-05-13 18:00:26 +00:00
|
|
|
const size_t kSize = 16;
|
2022-11-16 08:18:35 +00:00
|
|
|
const uint8_t in[kSize * 2 + 1] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
|
|
|
|
|
uint8_t out[kSize * 2];
|
2014-05-13 18:00:26 +00:00
|
|
|
void* p;
|
|
|
|
|
const void* q;
|
|
|
|
|
size_t bytes;
|
|
|
|
|
FifoBuffer buf(kSize);
|
|
|
|
|
|
|
|
|
|
// Test assumptions about base state
|
2018-10-31 10:19:50 +01:00
|
|
|
EXPECT_EQ(SS_OPEN, buf.GetState());
|
2022-11-16 08:18:35 +00:00
|
|
|
int error;
|
|
|
|
|
EXPECT_EQ(SR_BLOCK, buf.Read(rtc::MakeArrayView(out, kSize), bytes, error));
|
2018-10-31 10:19:50 +01:00
|
|
|
EXPECT_TRUE(nullptr != buf.GetWriteBuffer(&bytes));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize, bytes);
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.ConsumeWriteBuffer(0);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Try a full write
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS, buf.Write(rtc::MakeArrayView(in, kSize), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize, bytes);
|
|
|
|
|
|
|
|
|
|
// Try a write that should block
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_BLOCK, buf.Write(rtc::MakeArrayView(in, kSize), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Try a full read
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS, buf.Read(rtc::MakeArrayView(out, kSize), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(in, out, kSize));
|
|
|
|
|
|
|
|
|
|
// Try a read that should block
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_BLOCK, buf.Read(rtc::MakeArrayView(out, kSize), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Try a too-big write
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Write(rtc::MakeArrayView(in, kSize * 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(bytes, kSize);
|
|
|
|
|
|
|
|
|
|
// Try a too-big read
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Read(rtc::MakeArrayView(out, kSize * 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(in, out, kSize));
|
|
|
|
|
|
|
|
|
|
// Try some small writes and reads
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Write(rtc::MakeArrayView(in, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Read(rtc::MakeArrayView(out, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(in, out, kSize / 2));
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Write(rtc::MakeArrayView(in, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Write(rtc::MakeArrayView(in, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Read(rtc::MakeArrayView(out, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(in, out, kSize / 2));
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Read(rtc::MakeArrayView(out, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(in, out, kSize / 2));
|
|
|
|
|
|
|
|
|
|
// Try wraparound reads and writes in the following pattern
|
|
|
|
|
// WWWWWWWWWWWW.... 0123456789AB....
|
|
|
|
|
// RRRRRRRRXXXX.... ........89AB....
|
|
|
|
|
// WWWW....XXXXWWWW 4567....89AB0123
|
|
|
|
|
// XXXX....RRRRXXXX 4567........0123
|
|
|
|
|
// XXXXWWWWWWWWXXXX 4567012345670123
|
|
|
|
|
// RRRRXXXXXXXXRRRR ....01234567....
|
|
|
|
|
// ....RRRRRRRR.... ................
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Write(rtc::MakeArrayView(in, kSize * 3 / 4), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize * 3 / 4, bytes);
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Read(rtc::MakeArrayView(out, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(in, out, kSize / 2));
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Write(rtc::MakeArrayView(in, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Read(rtc::MakeArrayView(out, kSize / 4), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 4, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4));
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Write(rtc::MakeArrayView(in, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Read(rtc::MakeArrayView(out, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(in, out, kSize / 2));
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Read(rtc::MakeArrayView(out, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(in, out, kSize / 2));
|
|
|
|
|
|
|
|
|
|
// Use GetWriteBuffer to reset the read_position for the next tests
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.GetWriteBuffer(&bytes);
|
|
|
|
|
buf.ConsumeWriteBuffer(0);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Try using GetReadData to do a full read
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS, buf.Write(rtc::MakeArrayView(in, kSize), bytes, error));
|
2018-10-31 10:19:50 +01:00
|
|
|
q = buf.GetReadData(&bytes);
|
2017-02-27 14:06:41 -08:00
|
|
|
EXPECT_TRUE(nullptr != q);
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(q, in, kSize));
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.ConsumeReadData(kSize);
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_BLOCK, buf.Read(rtc::MakeArrayView(out, kSize), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Try using GetReadData to do some small reads
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS, buf.Write(rtc::MakeArrayView(in, kSize), bytes, error));
|
2018-10-31 10:19:50 +01:00
|
|
|
q = buf.GetReadData(&bytes);
|
2017-02-27 14:06:41 -08:00
|
|
|
EXPECT_TRUE(nullptr != q);
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(q, in, kSize / 2));
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.ConsumeReadData(kSize / 2);
|
|
|
|
|
q = buf.GetReadData(&bytes);
|
2017-02-27 14:06:41 -08:00
|
|
|
EXPECT_TRUE(nullptr != q);
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(q, in + kSize / 2, kSize / 2));
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.ConsumeReadData(kSize / 2);
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_BLOCK, buf.Read(rtc::MakeArrayView(out, kSize), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Try using GetReadData in a wraparound case
|
|
|
|
|
// WWWWWWWWWWWWWWWW 0123456789ABCDEF
|
|
|
|
|
// RRRRRRRRRRRRXXXX ............CDEF
|
|
|
|
|
// WWWWWWWW....XXXX 01234567....CDEF
|
|
|
|
|
// ............RRRR 01234567........
|
|
|
|
|
// RRRRRRRR........ ................
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS, buf.Write(rtc::MakeArrayView(in, kSize), bytes, error));
|
|
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Read(rtc::MakeArrayView(out, kSize * 3 / 4), bytes, error));
|
|
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Write(rtc::MakeArrayView(in, kSize / 2), bytes, error));
|
2018-10-31 10:19:50 +01:00
|
|
|
q = buf.GetReadData(&bytes);
|
2017-02-27 14:06:41 -08:00
|
|
|
EXPECT_TRUE(nullptr != q);
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 4, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(q, in + kSize * 3 / 4, kSize / 4));
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.ConsumeReadData(kSize / 4);
|
|
|
|
|
q = buf.GetReadData(&bytes);
|
2017-02-27 14:06:41 -08:00
|
|
|
EXPECT_TRUE(nullptr != q);
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(q, in, kSize / 2));
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.ConsumeReadData(kSize / 2);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Use GetWriteBuffer to reset the read_position for the next tests
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.GetWriteBuffer(&bytes);
|
|
|
|
|
buf.ConsumeWriteBuffer(0);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Try using GetWriteBuffer to do a full write
|
2018-10-31 10:19:50 +01:00
|
|
|
p = buf.GetWriteBuffer(&bytes);
|
2017-02-27 14:06:41 -08:00
|
|
|
EXPECT_TRUE(nullptr != p);
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize, bytes);
|
|
|
|
|
memcpy(p, in, kSize);
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.ConsumeWriteBuffer(kSize);
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS, buf.Read(rtc::MakeArrayView(out, kSize), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(in, out, kSize));
|
|
|
|
|
|
|
|
|
|
// Try using GetWriteBuffer to do some small writes
|
2018-10-31 10:19:50 +01:00
|
|
|
p = buf.GetWriteBuffer(&bytes);
|
2017-02-27 14:06:41 -08:00
|
|
|
EXPECT_TRUE(nullptr != p);
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize, bytes);
|
|
|
|
|
memcpy(p, in, kSize / 2);
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.ConsumeWriteBuffer(kSize / 2);
|
|
|
|
|
p = buf.GetWriteBuffer(&bytes);
|
2017-02-27 14:06:41 -08:00
|
|
|
EXPECT_TRUE(nullptr != p);
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
|
|
|
|
memcpy(p, in + kSize / 2, kSize / 2);
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.ConsumeWriteBuffer(kSize / 2);
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS, buf.Read(rtc::MakeArrayView(out, kSize), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(in, out, kSize));
|
|
|
|
|
|
|
|
|
|
// Try using GetWriteBuffer in a wraparound case
|
|
|
|
|
// WWWWWWWWWWWW.... 0123456789AB....
|
|
|
|
|
// RRRRRRRRXXXX.... ........89AB....
|
|
|
|
|
// ........XXXXWWWW ........89AB0123
|
|
|
|
|
// WWWW....XXXXXXXX 4567....89AB0123
|
|
|
|
|
// RRRR....RRRRRRRR ................
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Write(rtc::MakeArrayView(in, kSize * 3 / 4), bytes, error));
|
|
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Read(rtc::MakeArrayView(out, kSize / 2), bytes, error));
|
2018-10-31 10:19:50 +01:00
|
|
|
p = buf.GetWriteBuffer(&bytes);
|
2017-02-27 14:06:41 -08:00
|
|
|
EXPECT_TRUE(nullptr != p);
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 4, bytes);
|
|
|
|
|
memcpy(p, in, kSize / 4);
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.ConsumeWriteBuffer(kSize / 4);
|
|
|
|
|
p = buf.GetWriteBuffer(&bytes);
|
2017-02-27 14:06:41 -08:00
|
|
|
EXPECT_TRUE(nullptr != p);
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize / 2, bytes);
|
|
|
|
|
memcpy(p, in + kSize / 4, kSize / 4);
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.ConsumeWriteBuffer(kSize / 4);
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Read(rtc::MakeArrayView(out, kSize * 3 / 4), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(kSize * 3 / 4, bytes);
|
|
|
|
|
EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4));
|
|
|
|
|
EXPECT_EQ(0, memcmp(in, out + kSize / 4, kSize / 4));
|
|
|
|
|
|
|
|
|
|
// Check that the stream is now empty
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_BLOCK, buf.Read(rtc::MakeArrayView(out, kSize), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Write to the stream, close it, read the remaining bytes
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Write(rtc::MakeArrayView(in, kSize / 2), bytes, error));
|
2018-10-31 10:19:50 +01:00
|
|
|
buf.Close();
|
|
|
|
|
EXPECT_EQ(SS_CLOSED, buf.GetState());
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_EOS, buf.Write(rtc::MakeArrayView(in, kSize / 2), bytes, error));
|
|
|
|
|
EXPECT_EQ(SR_SUCCESS,
|
|
|
|
|
buf.Read(rtc::MakeArrayView(out, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(0, memcmp(in, out, kSize / 2));
|
2022-11-16 08:18:35 +00:00
|
|
|
EXPECT_EQ(SR_EOS, buf.Read(rtc::MakeArrayView(out, kSize / 2), bytes, error));
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(FifoBufferTest, FullBufferCheck) {
|
2022-05-20 09:12:57 +02:00
|
|
|
rtc::AutoThread main_thread;
|
2014-05-13 18:00:26 +00:00
|
|
|
FifoBuffer buff(10);
|
|
|
|
|
buff.ConsumeWriteBuffer(10);
|
|
|
|
|
|
|
|
|
|
size_t free;
|
2017-02-27 14:06:41 -08:00
|
|
|
EXPECT_TRUE(buff.GetWriteBuffer(&free) != nullptr);
|
2014-05-13 18:00:26 +00:00
|
|
|
EXPECT_EQ(0U, free);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace rtc
|