#include "io/gpr/IprbReader.hpp" #include "io/gpr/IprHeader.hpp" #include #include #include namespace { std::string writeTmp(const std::vector& v) { std::string p = std::tmpnam(nullptr); std::ofstream f(p, std::ios::binary); f.write(reinterpret_cast(v.data()), static_cast(v.size()*sizeof(int16_t))); return p; } } using namespace geopro::io::gpr; TEST(IprbReader, ReadsInt16AndLayout) { std::vector raw{0,1,2, 10,11,12, 20,21,22, 30,31,32}; // 4 道×3 采样 auto path = writeTmp(raw); IprHeader h{}; h.samples = 3; h.lastTrace = 3; // traces = 4 auto b = readIprb(path, h); EXPECT_EQ(b.samples, 3); EXPECT_EQ(b.traces, 4); EXPECT_EQ(b.data.size(), 12u); EXPECT_EQ(b.data[1*3 + 2], 12); // 第1道第2采样 std::remove(path.c_str()); } TEST(IprbReader, ThrowsOnSizeMismatch) { std::vector raw{0,1,2,3,4}; // 5 个,非 samples 整数倍 → 抛 auto path = writeTmp(raw); IprHeader h{}; h.samples = 3; h.lastTrace = 3; // 5*2=10, 10%6!=0 EXPECT_THROW(readIprb(path, h), std::runtime_error); std::remove(path.c_str()); } // 真实数据规律:LAST TRACE=N 但文件恰含 N 道(非 N+1)。 // 文件大小为权威 → traces 应等于文件实含道数 N,而非 N+1。 TEST(IprbReader, FileSizeIsAuthoritativeNotLastTracePlusOne) { // 4 道×3 采样 = 12 个 int16,文件恰含 4 道。 std::vector raw{0,1,2, 10,11,12, 20,21,22, 30,31,32}; auto path = writeTmp(raw); IprHeader h{}; h.samples = 3; h.lastTrace = 4; // 假设 +1 会得 5 道(错) auto b = readIprb(path, h); EXPECT_EQ(b.traces, 4); // 以文件大小为准 → 4,复刻真实数据 traces==lastTrace 规律 EXPECT_EQ(b.data.size(), 12u); std::remove(path.c_str()); } TEST(IprbReader, ThrowsOnMissingFile) { IprHeader h{}; h.samples = 3; h.lastTrace = 3; EXPECT_THROW(readIprb("____no_such_file____.iprb", h), std::runtime_error); } TEST(IprbReader, RangeReadMatchesFullSlice) { // 造 samples=3, traces=5 的文件(15 个 int16,值=trace*10+s) std::vector raw; for(int t=0;t<5;t++)for(int s=0;s<3;s++) raw.push_back((int16_t)(t*10+s)); auto path = writeTmp(raw); IprHeader h{}; h.samples=3; h.lastTrace=4; // 总道数=5(由文件大小推) auto full = readIprb(path, h); auto seg = readIprbRange(path, h, 1, 4); // 读道 [1,4)=3 道 EXPECT_EQ(seg.traces, 3); EXPECT_EQ(seg.samples, 3); ASSERT_EQ(seg.data.size(), 9u); for (int t=0;t<3;t++) for(int s=0;s<3;s++) EXPECT_EQ(seg.data[t*3+s], full.data[(t+1)*3+s]); // 段==全读对应段 std::remove(path.c_str()); } TEST(IprbReader, RangeOutOfBoundsThrows) { std::vector raw(15,0); auto path=writeTmp(raw); IprHeader h{}; h.samples=3; h.lastTrace=4; EXPECT_THROW(readIprbRange(path,h,3,99), std::runtime_error); // t1>5 EXPECT_THROW(readIprbRange(path,h,4,2), std::runtime_error); // t0>t1 std::remove(path.c_str()); }