freepdfeditor/spike/F_rust_ffi_probe/cpp_driver.cpp

48 lines
1.8 KiB
C++

// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2025 ai-ad4 and the FreePDFEditor contributors
//
// spike/F_rust_ffi_probe — ADR-0005 build-friction probe. Measures the cost of
// adding a Rust leaf decoder to the tree: a tiny `flate`-style decoder stub
// (echoes a byte buffer) compiled as a `cdylib`/`staticlib` behind a C ABI,
// linked into a C++ driver. The point is the build friction and FFI shape,
// not real decompression.
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
// The C ABI the Rust crate exposes. Declared here (not from a generated
// header) to show the minimal glue shape.
extern "C" {
// A bounded view, matching the §7.2 "std::span-like bounded views" rule.
// The Rust side gets a pointer + length and must not read past length.
int fpe_rust_decode(const unsigned char* in, std::size_t in_len,
unsigned char* out, std::size_t out_cap,
std::size_t* out_len);
}
int main(int argc, char** argv)
{
const std::size_t n = (argc >= 2) ? std::size_t(std::atoll(argv[1])) : 1024;
std::vector<unsigned char> input(n, 0x5A);
std::vector<unsigned char> output(n * 2, 0);
std::size_t out_len = 0;
int rc = fpe_rust_decode(input.data(), input.size(),
output.data(), output.size(), &out_len);
if (rc != 0) {
std::fprintf(stderr, "decode failed: %d\n", rc);
return 1;
}
// Verify the (stub) decoder echoed the input.
if (out_len != input.size() ||
std::memcmp(output.data(), input.data(), input.size()) != 0) {
std::fprintf(stderr, "decode output mismatch\n");
return 1;
}
std::printf("rust_ffi_probe: decoded %zu bytes via Rust C ABI, rc=%d\n",
out_len, rc);
return 0;
}