This prevents ODR violations as there can no longer be 2 implementations of base64.h Bug: webrtc:430259982 Change-Id: I989ad6c05df6df93a2534474fc5168747ecf8f7b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/399600 Commit-Queue: Evan Shrubsole <eshr@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Cr-Commit-Position: refs/heads/main@{#45127}
69 lines
1.9 KiB
Rust
69 lines
1.9 KiB
Rust
/*
|
|
* Copyright (c) 2025 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
use base64::alphabet;
|
|
use base64::engine::general_purpose;
|
|
use base64::engine::DecodePaddingMode;
|
|
use base64::Engine;
|
|
use cxx::CxxString;
|
|
use std::pin::Pin;
|
|
|
|
#[cxx::bridge(namespace = "webrtc")]
|
|
mod ffi {
|
|
#[repr(u8)]
|
|
enum Base64DecodeSetting {
|
|
Strict,
|
|
Forgiving,
|
|
}
|
|
|
|
extern "Rust" {
|
|
fn rs_base64_encode(data: &[u8]) -> String;
|
|
fn rs_base64_decode(
|
|
data: &[u8],
|
|
options: Base64DecodeSetting,
|
|
output: Pin<&mut CxxString>,
|
|
) -> bool;
|
|
}
|
|
}
|
|
|
|
fn rs_base64_encode(data: &[u8]) -> String {
|
|
general_purpose::STANDARD.encode(data)
|
|
}
|
|
|
|
const FORGIVING_ENGINE: general_purpose::GeneralPurpose = general_purpose::GeneralPurpose::new(
|
|
&alphabet::STANDARD,
|
|
general_purpose::GeneralPurposeConfig::new()
|
|
.with_decode_padding_mode(DecodePaddingMode::Indifferent),
|
|
);
|
|
|
|
fn rs_base64_decode(
|
|
data: &[u8],
|
|
options: ffi::Base64DecodeSetting,
|
|
output: Pin<&mut CxxString>,
|
|
) -> bool {
|
|
let result = match options {
|
|
ffi::Base64DecodeSetting::Strict => general_purpose::STANDARD.decode(data),
|
|
ffi::Base64DecodeSetting::Forgiving => {
|
|
let data_without_whitespace: Vec<u8> =
|
|
data.iter().filter(|&c| !c.is_ascii_whitespace()).copied().collect();
|
|
FORGIVING_ENGINE.decode(data_without_whitespace)
|
|
}
|
|
_ => unreachable!(),
|
|
};
|
|
|
|
match result {
|
|
Ok(vec) => {
|
|
output.push_bytes(vec.as_slice());
|
|
true
|
|
}
|
|
Err(_) => false,
|
|
}
|
|
}
|