| /* | |
| * 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, | |
| } | |
| } |