blob: 6862271f8e434d76b5e396f342b1fe1cec2d9b34 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use cxx::{let_cxx_string, CxxVector};
#[cxx::bridge(namespace = "validation_parser_bridge")]
mod ffi {
extern "C++" {
include!("mojo/public/cpp/bindings/tests/validation_test_input_parser.h");
/// Calls ParseValidationTestInput, declared the above header.
/// `input` is the validation file contents to be parsed; the other
/// arguments are out-parameters and will be cleared/written to.
/// See the C++ function definition for more details.
#[namespace = "mojo::test"]
unsafe fn ParseValidationTestInput(
input: &CxxString,
data: *mut CxxVector<u8>,
num_handles: *mut usize,
error_message: *mut CxxString,
) -> bool;
}
}
pub struct ValidationTestData {
pub data: Box<[u8]>,
pub num_handles: usize,
}
/// Parse the validation text format into binary data; also returns
/// the number of handles in the message. On failure, returns an error message.
pub fn parse(contents: &str) -> Result<ValidationTestData, String> {
// Binds a variable `input` of type Pin<&mut CxxString>
let_cxx_string!(input = contents);
let data = CxxVector::new();
let mut num_handles: usize = 0;
let_cxx_string!(error_message = "");
// SAFETY: We're using CXX types, which are designed to be compatible with
// C++. The pointers are coming from references, so they are never null.
let success = unsafe {
ffi::ParseValidationTestInput(
&input,
data.as_mut_ptr(),
&mut num_handles as *mut _,
// SAFETY: The C++ code won't move the data here, and we drop it
// at the end of this function, so we won't violate any pinning
// invariants.
std::pin::Pin::into_inner_unchecked(error_message.as_mut()) as *mut _,
)
};
if success {
let data: Box<[u8]> = Box::from(data.as_slice());
Ok(ValidationTestData { data, num_handles })
} else {
Err(error_message.to_string())
}
}