/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2018, Google Inc. * * byte_stream_buffer.cpp - ByteStreamBuffer tests */ #include <array> #include <iostream> #include "libcamera/internal/byte_stream_buffer.h" #include "test.h" using namespace std; using namespace libcamera; class ByteStreamBufferTest : public Test { protected: int run() { /* * gcc 11.1.0 incorrectly raises a maybe-uninitialized warning * when calling data.size() below (if the address sanitizer is * disabled). Silence it by initializing the array. */ std::array<uint8_t, 100> data = {}; unsigned int i; uint32_t value; int ret; /* * Write mode. */ ByteStreamBuffer wbuf(data.data(), data.size()); if (wbuf.base() != data.data() || wbuf.size() != data.size() || wbuf.offset() != 0 || wbuf.overflow()) { cerr << "Write buffer incorrectly constructed" << endl; return TestFail; } /* Test write. */ value = 0x12345678; ret = wbuf.write(&value); if (ret || wbuf.offset() != 4 || wbuf.overflow() || *reinterpret_cast<uint32_t *>(data.data()) != 0x12345678) { cerr << "Write failed on write buffer" << endl; return TestFail; } /* Test write carve out. */ ByteStreamBuffer wco = wbuf.carveOut(10); if (wco.base() != wbuf.base() + 4 || wco.size() != 10 || wco.offset() != 0 || wco.overflow() || wbuf.offset() != 14 || wbuf.overflow()) { cerr << "Carving out write buffer failed" << endl; return TestFail; } /* Test write on the carved out buffer. */ value = 0x87654321; ret = wco.write(&value); if (ret || wco.offset() != 4 || wco.overflow() || *reinterpret_cast<uint32_t *>(data.data() + 4) != 0x87654321) { cerr << "Write failed on carve out buffer" << endl; return TestFail; } if (wbuf.offset() != 14 || wbuf.overflow()) { cerr << "Write on carve out buffer modified write buffer" << endl; return TestFail; } /* Test read, this should fail. */ ret = wbuf.read(&value); if (!ret || wbuf.overflow()) { cerr << "Read should fail on write buffer" << endl; return TestFail; } /* Test overflow on carved out buffer. */ for (i = 0; i < 2; ++i) { ret = wco.write(&value); if (ret < 0) break; } if (i != 1 || !wco.overflow() || !wbuf.overflow()) { cerr << "Write on carve out buffer failed to overflow" << endl; return TestFail; } /* Test reinitialization of the buffer. */ wbuf = ByteStreamBuffer(data.data(), data.size()); if (wbuf.overflow() || wbuf.base() != data.data() || wbuf.offset() != 0) { cerr << "Write buffer reinitialization failed" << endl; return TestFail; } /* * Read mode. */ ByteStreamBuffer rbuf(const_cast<const uint8_t *>(data.data()), data.size()); if (rbuf.base() != data.data() || rbuf.size() != data.size() || rbuf.offset() != 0 || rbuf.overflow()) { cerr << "Read buffer incorrectly constructed" << endl; return TestFail; } /* Test read. */ value = 0; ret = rbuf.read(&value); if (ret || rbuf.offset() != 4 || rbuf.overflow() || value != 0x12345678) { cerr << "Write failed on write buffer" << endl; return TestFail; } /* Test read carve out. */ ByteStreamBuffer rco = rbuf.carveOut(10); if (rco.base() != rbuf.base() + 4 || rco.size() != 10 || rco.offset() != 0 || rco.overflow() || rbuf.offset() != 14 || rbuf.overflow()) { cerr << "Carving out read buffer failed" << endl; return TestFail; } /* Test read on the carved out buffer. */ value = 0; ret = rco.read(&value); if (ret || rco.offset() != 4 || rco.overflow() || value != 0x87654321) { cerr << "Read failed on carve out buffer" << endl; return TestFail; } if (rbuf.offset() != 14 || rbuf.overflow()) { cerr << "Read on carve out buffer modified read buffer" << endl; return TestFail; } /* Test write, this should fail. */ ret = rbuf.write(&value); if (!ret || rbuf.overflow()) { cerr << "Write should fail on read buffer" << endl; return TestFail; } /* Test overflow on carved out buffer. */ for (i = 0; i < 2; ++i) { ret = rco.read(&value); if (ret < 0) break; } if (i != 1 || !rco.overflow() || !rbuf.overflow()) { cerr << "Read on carve out buffer failed to overflow" << endl; return TestFail; } /* Test reinitialization of the buffer. */ rbuf = ByteStreamBuffer(const_cast<const uint8_t *>(data.data()), data.size()); if (rbuf.overflow() || rbuf.base() != data.data() || rbuf.offset() != 0) { cerr << "Read buffer reinitialization failed" << endl; return TestFail; } return TestPass; } }; TEST_REGISTER(ByteStreamBufferTest)