20#include <boost/test/unit_test.hpp>
43static std::vector<uint8_t> loadBinary(
const std::string& aPath )
45 std::ifstream file( aPath, std::ios::binary );
48 throw std::runtime_error(
"Cannot open test fixture: " + aPath );
50 return { std::istreambuf_iterator<char>( file ), std::istreambuf_iterator<char>() };
54static std::vector<uint8_t> loadPublicFixture()
60static void putU32( std::vector<uint8_t>& aBytes,
size_t aOffset, uint32_t aValue )
62 aBytes.at( aOffset ) =
static_cast<uint8_t
>( aValue );
63 aBytes.at( aOffset + 1 ) =
static_cast<uint8_t
>( aValue >> 8 );
64 aBytes.at( aOffset + 2 ) =
static_cast<uint8_t
>( aValue >> 16 );
65 aBytes.at( aOffset + 3 ) =
static_cast<uint8_t
>( aValue >> 24 );
69static bool errorContains(
const IO_ERROR& aError,
const std::string& aNeedle1,
const std::string& aNeedle2 )
71 std::string message = aError.
What().ToStdString();
72 return message.find( aNeedle1 ) != std::string::npos && message.find( aNeedle2 ) != std::string::npos;
76static void checkPhysicalPartition(
const std::string& aPath )
79 sdb.
Load( loadBinary( aPath ) );
81 const auto& blocks = sdb.
Blocks();
82 BOOST_REQUIRE_MESSAGE( !blocks.empty(), aPath );
85 for(
size_t i = 1; i < blocks.size(); ++i )
99 std::vector<uint8_t> bytes = loadPublicFixture();
131 std::ifstream publicFile( publicRoot +
"manifest.json" );
132 nlohmann::json publicManifest;
133 publicFile >> publicManifest;
135 for(
const nlohmann::json& fixture : publicManifest.at(
"fixtures" ) )
136 checkPhysicalPartition( publicRoot + fixture.at(
"binary" ).get<std::string>() );
144 sdb.
Load( loadPublicFixture() );
145 const auto& blocks = sdb.
Blocks();
147 BOOST_REQUIRE_EQUAL( blocks.size(), 3 );
148 BOOST_CHECK( blocks[0].kind == SCH_SDB_BLOCK_KIND::FIXED_CONTROLLER );
154 BOOST_CHECK( blocks[1].kind == SCH_SDB_BLOCK_KIND::SHEET );
157 BOOST_CHECK( blocks[2].kind == SCH_SDB_BLOCK_KIND::FOOTER_AUX );
170 return aBlock.kind == SCH_SDB_BLOCK_KIND::CFB_CONTAINER_ITEM;
173 const auto& blocks = sdb.
Blocks();
174 std::vector<const PADS_SCH_BINARY::SCH_SDB_BLOCK*> items;
176 for(
const auto& block : blocks )
178 if( isContainerItem( block ) )
179 items.push_back( &block );
182 BOOST_REQUIRE_EQUAL( items.size(), 2 );
183 BOOST_REQUIRE_EQUAL( sdb.
OleItems().size(), 2 );
184 BOOST_CHECK( ( sdb.
OleItems()[0].extent == std::array<int32_t, 4>{ 30, 30, 350, 210 } ) );
191 BOOST_CHECK( ( sdb.
OleItems()[1].extent == std::array<int32_t, 4>{ 30, 30, 170, 84 } ) );
202 BOOST_REQUIRE_GE( bitmap.
data.size(), 2 );
209 BOOST_REQUIRE_GE( metafile.
data.size(), 4 );
216 BOOST_CHECK( rendered.IsOk() );
217 BOOST_CHECK_GT( rendered.GetWidth(), 0 );
218 BOOST_CHECK_GT( rendered.GetHeight(), 0 );
224 std::vector<uint8_t> bytes =
227 parsed.
Load( bytes );
228 BOOST_REQUIRE_EQUAL( parsed.
OleItems().size(), 2 );
229 size_t sheetOffset = parsed.
OleItems()[0].trailerOffset + 38 + 16 + 16;
230 putU32( bytes, sheetOffset, 1 );
233 auto hasOffset = [sheetOffset](
const IO_ERROR& e )
235 return errorContains( e,
"v0x000D", wxString::Format(
"0x%zX", sheetOffset ).
ToStdString() );
237 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR, hasOffset );
243 std::vector<uint8_t> bytes = loadPublicFixture();
247 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
250 return errorContains( e,
"v0x000D",
"0x1F" );
257 std::vector<uint8_t> bytes = loadPublicFixture();
261 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
264 return errorContains( e,
"v0x000D",
"0x1" );
271 std::vector<uint8_t> bytes = loadPublicFixture();
276 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
279 return errorContains( e,
"v0x1234",
"0x2" );
286 std::vector<uint8_t> bytes = loadPublicFixture();
290 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
293 return errorContains( e,
"v0x000D",
"0x4" );
300 std::vector<uint8_t> bytes = loadPublicFixture();
305 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
308 return errorContains( e,
"v0x000C",
"0x4" );
315 std::vector<uint8_t> bytes = loadPublicFixture();
316 size_t footer = bytes.size() - 42;
320 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
323 return errorContains( e,
"v0x000D", wxString::Format(
"0x%zX", footer ).ToStdString() );
330 std::vector<uint8_t> bytes = loadPublicFixture();
331 size_t pointerOffset = bytes.size() - 4;
332 putU32( bytes, pointerOffset,
static_cast<uint32_t
>( bytes.size() + 1 ) );
335 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
336 [pointerOffset](
const IO_ERROR& e )
338 return errorContains( e,
"v0x000D",
339 wxString::Format(
"0x%zX", pointerOffset ).ToStdString() );
346 std::vector<uint8_t> bytes = loadPublicFixture();
347 constexpr size_t usedBytesOffset = 0x20 + 12;
348 putU32( bytes, usedBytesOffset, 589 );
351 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
354 return errorContains( e,
"v0x000D",
"0x2C" );
361 std::vector<uint8_t> bytes = loadPublicFixture();
362 constexpr size_t descriptor = 0x20 + 9 * 28;
363 putU32( bytes, descriptor + 12, 1 );
366 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
369 return errorContains( e,
"v0x000D",
"0x128" );
376 std::vector<uint8_t> bytes = loadPublicFixture();
377 constexpr size_t descriptor = 0x20 + 1 * 28;
378 putU32( bytes, descriptor + 4, UINT32_MAX );
379 putU32( bytes, descriptor + 12, UINT32_MAX );
382 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
385 return errorContains( e,
"v0x000D",
"0x48" );
392 std::vector<uint8_t> bytes = loadPublicFixture();
393 constexpr size_t descriptor = 0x5439 + 20;
394 putU32( bytes, descriptor + 8, UINT32_MAX );
395 putU32( bytes, descriptor + 16, UINT32_MAX );
398 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
401 return errorContains( e,
"v0x000D",
"0x545D" );
408 std::vector<uint8_t> bytes = loadPublicFixture();
409 constexpr size_t countOffset = 0x20 + 3 * 28 + 8;
410 putU32( bytes, countOffset, UINT32_MAX );
413 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
416 return errorContains( e,
"v0x000D",
"0x7C" );
423 std::vector<uint8_t> bytes = loadPublicFixture();
424 constexpr size_t itemCountOffset = 0x9938;
425 putU32( bytes, itemCountOffset, UINT32_MAX );
428 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
431 return errorContains( e,
"v0x000D",
"0x9938" );
438 std::vector<uint8_t> bytes = loadPublicFixture();
439 size_t pointerOffset = bytes.size() - 4;
440 putU32( bytes, pointerOffset, 0x24F );
443 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
444 [pointerOffset](
const IO_ERROR& e )
446 return errorContains( e,
"v0x000D",
447 wxString::Format(
"0x%zX", pointerOffset ).ToStdString() );
454 std::vector<uint8_t> bytes = loadPublicFixture();
455 size_t pointerOffset = bytes.size() - 4;
456 putU32( bytes, pointerOffset, 0x250 );
459 BOOST_CHECK_EXCEPTION( sdb.
Load( std::move( bytes ) ),
IO_ERROR,
460 [pointerOffset](
const IO_ERROR& e )
462 return errorContains( e,
"v0x000D",
463 wxString::Format(
"0x%zX", pointerOffset ).ToStdString() );
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
const std::array< SCH_SDB_POOL, 20 > & Pools() const
const PADS_IO::BINARY_CURSOR & Cursor() const
void Load(std::vector< uint8_t > aBytes)
size_t FooterOffset() const
size_t PayloadOffset() const
const std::vector< uint8_t > & Bytes() const
const std::vector< SCH_SDB_BLOCK > & Blocks() const
const std::vector< SCH_SDB_OLE_ITEM > & OleItems() const
static bool IsSupportedVersion(uint16_t aVersion)
static bool HasFamilyMagic(const std::vector< uint8_t > &aBytes)
static std::string ToStdString(const wxString &aStr)
std::string GetEeschemaTestDataDir()
Get the configured location of Eeschema test data.
bool OleRenderWmf(const std::vector< uint8_t > &aWmf, int aMaxWidth, int aMaxHeight, wxImage &aImage, double aTargetAspect)
OLE_IMAGE_PAYLOAD ExtractOleImage(const uint8_t *aCfb, size_t aSize)
Prefer CONTENTS, then OlePres000, then the native stream.
std::vector< uint8_t > data
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(PublicV13Container)
BOOST_CHECK_EQUAL(result, "25.4")