From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../rust/encoding_c_mem/.cargo-checksum.json | 1 + third_party/rust/encoding_c_mem/CONTRIBUTING.md | 33 + third_party/rust/encoding_c_mem/COPYRIGHT | 9 + third_party/rust/encoding_c_mem/Cargo.toml | 27 + third_party/rust/encoding_c_mem/LICENSE-APACHE | 202 +++++ third_party/rust/encoding_c_mem/LICENSE-MIT | 25 + third_party/rust/encoding_c_mem/README.md | 60 ++ third_party/rust/encoding_c_mem/build.rs | 7 + .../rust/encoding_c_mem/include/encoding_rs_mem.h | 704 ++++++++++++++++++ .../encoding_c_mem/include/encoding_rs_mem_cpp.h | 578 +++++++++++++++ third_party/rust/encoding_c_mem/src/lib.rs | 825 +++++++++++++++++++++ 11 files changed, 2471 insertions(+) create mode 100644 third_party/rust/encoding_c_mem/.cargo-checksum.json create mode 100644 third_party/rust/encoding_c_mem/CONTRIBUTING.md create mode 100644 third_party/rust/encoding_c_mem/COPYRIGHT create mode 100644 third_party/rust/encoding_c_mem/Cargo.toml create mode 100644 third_party/rust/encoding_c_mem/LICENSE-APACHE create mode 100644 third_party/rust/encoding_c_mem/LICENSE-MIT create mode 100644 third_party/rust/encoding_c_mem/README.md create mode 100644 third_party/rust/encoding_c_mem/build.rs create mode 100644 third_party/rust/encoding_c_mem/include/encoding_rs_mem.h create mode 100644 third_party/rust/encoding_c_mem/include/encoding_rs_mem_cpp.h create mode 100644 third_party/rust/encoding_c_mem/src/lib.rs (limited to 'third_party/rust/encoding_c_mem') diff --git a/third_party/rust/encoding_c_mem/.cargo-checksum.json b/third_party/rust/encoding_c_mem/.cargo-checksum.json new file mode 100644 index 0000000000..b2de1315ea --- /dev/null +++ b/third_party/rust/encoding_c_mem/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CONTRIBUTING.md":"d393951002340c3d98011f7b654e8133408f3f0e13b9f6470f4cb5d251e3afed","COPYRIGHT":"8667a5cdf817b0123721cc7d7ca73e97f05ac926203a13646a9e8a30c70c0989","Cargo.toml":"bc7ca08a7395d4839be804fff569d96a5cf0250be792e074af2f57c1ab1fd8d4","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"3fa4ca83dcc9237839b1bdeb2e6d16bdfb5ec0c5ce42b24694d8bbf0dcbef72c","README.md":"333b861c160f5328e9fb4bf506e8aaaf1a1eab8e93af3ce03998c3f6b57a2da2","build.rs":"013c85c18b035473d3a0900b833906304a8431882e5c22053684a69588adde98","include/encoding_rs_mem.h":"99f2c8d900bdb66ffd74772419a0e50d482d25f20db54a187c78d079fe483be0","include/encoding_rs_mem_cpp.h":"5a546590508d8e1cc78493d6e0a04cdb80a499d23ef192603a31aaf2e518ca3a","src/lib.rs":"7d5940a215cd93b231aafa61cc9cff474e808893a35d5236b99e7317697ac308"},"package":"3a80a16821fe8c7cab96e0c67b57cd7090e021e9615e6ce6ab0cf866c44ed1f0"} \ No newline at end of file diff --git a/third_party/rust/encoding_c_mem/CONTRIBUTING.md b/third_party/rust/encoding_c_mem/CONTRIBUTING.md new file mode 100644 index 0000000000..88322776f6 --- /dev/null +++ b/third_party/rust/encoding_c_mem/CONTRIBUTING.md @@ -0,0 +1,33 @@ +If you send a pull request / patch, please observe the following. + +## Licensing + +Since this crate is dual-licensed, +[section 5 of the Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0#contributions) +is considered to apply in the sense of Contributions being automatically +under the Apache License 2.0 or MIT dual license (see the `COPYRIGHT` file). +That is, by the act of offering a Contribution, you place your Contribution +under the Apache License 2.0 or MIT dual license stated in the `COPYRIGHT` +file. Please do not contribute if you aren't willing or allowed to license your +contributions in this manner. + +You are encouraged to dedicate test code that you contribute to the Public +Domain using the CC0 dedication. If you contribute test code that is not +dedicated to the Public Domain, please be sure not to put it in a part of +source code that the comments designate as being dedicated to the Public +Domain. + +## Copyright Notices + +If you require the addition of your copyright notice, it's up to you to edit in +your notice as part of your Contribution. Not adding a copyright notice is +taken as a waiver of copyright notice. + +## Compatibility with Stable Rust + +Please ensure that your Contribution compiles with the latest stable-channel +rustc. + +## rustfmt + +Please run `cargo fmt` before creating a pull. \ No newline at end of file diff --git a/third_party/rust/encoding_c_mem/COPYRIGHT b/third_party/rust/encoding_c_mem/COPYRIGHT new file mode 100644 index 0000000000..b4569d6701 --- /dev/null +++ b/third_party/rust/encoding_c_mem/COPYRIGHT @@ -0,0 +1,9 @@ +encoding_c_mem is copyright Mozilla Foundation. + +Licensed under the Apache License, Version 2.0 + or the MIT +license , +at your option. All files in the project carrying such +notice may not be copied, modified, or distributed except +according to those terms. diff --git a/third_party/rust/encoding_c_mem/Cargo.toml b/third_party/rust/encoding_c_mem/Cargo.toml new file mode 100644 index 0000000000..2284f40fd8 --- /dev/null +++ b/third_party/rust/encoding_c_mem/Cargo.toml @@ -0,0 +1,27 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "encoding_c_mem" +version = "0.2.6" +authors = ["Henri Sivonen "] +links = "encoding_c_mem" +description = "C API for encoding_rs::mem" +homepage = "https://docs.rs/encoding_c_mem/" +documentation = "https://docs.rs/encoding_c_mem/" +readme = "README.md" +keywords = ["ffi", "capi", "encoding", "unicode", "charset"] +license = "Apache-2.0 OR MIT" +repository = "https://github.com/hsivonen/encoding_c_mem" +[dependencies.encoding_rs] +version = "0.8.19" diff --git a/third_party/rust/encoding_c_mem/LICENSE-APACHE b/third_party/rust/encoding_c_mem/LICENSE-APACHE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/third_party/rust/encoding_c_mem/LICENSE-APACHE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/third_party/rust/encoding_c_mem/LICENSE-MIT b/third_party/rust/encoding_c_mem/LICENSE-MIT new file mode 100644 index 0000000000..3317c82e2f --- /dev/null +++ b/third_party/rust/encoding_c_mem/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright Mozilla Foundation + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/encoding_c_mem/README.md b/third_party/rust/encoding_c_mem/README.md new file mode 100644 index 0000000000..59c7abe607 --- /dev/null +++ b/third_party/rust/encoding_c_mem/README.md @@ -0,0 +1,60 @@ +# encoding_c_mem + +[![crates.io](https://meritbadge.herokuapp.com/encoding_c_mem)](https://crates.io/crates/encoding_c_mem) +[![docs.rs](https://docs.rs/encoding_c_mem/badge.svg)](https://docs.rs/encoding_c_mem/) +[![Apache 2 / MIT dual-licensed](https://img.shields.io/badge/license-Apache%202%20%2F%20MIT-blue.svg)](https://github.com/hsivonen/encoding_c_mem/blob/master/COPYRIGHT) + +encoding_c_mem is an FFI wrapper for the `mem` module of [encoding_rs](https://github.com/hsivonen/encoding_rs). + +## Licensing + +Please see the file named +[COPYRIGHT](https://github.com/hsivonen/encoding_c_mem/blob/master/COPYRIGHT). + +## No Unwinding Support! + +This crate is meant for use in binaries compiled with `panic = 'abort'`, which +is _required_ for correctness! Unwinding across FFI is Undefined Behavior, and +this crate does nothing to try to prevent unwinding across the FFI if +compiled with unwinding enabled. + +## Release Notes + +### 0.2.6 + +* Remove year from copyright notices. + +### 0.2.5 + +* Specify a `links` value in the Cargo manifest. +* Emit an `include_dir` variable from build script so that other build scripts + depending on this crate can rely on it. + +### 0.2.4 + +* Documentation-only fix. + +### 0.2.3 + +* Documentation-only fix. + +### 0.2.2 + +* Wrap `convert_utf8_to_utf16_without_replacement`, `utf8_latin1_up_to`, + and `str_latin1_up_to`. + +### 0.2.1 + +* Fix a typo in README. + +### 0.2.0 + +* Use `char` instead of `uint8_t` for 8-bit-unit text in C and C++. + +### 0.1.1 + +* Add include guard to the C header. + +### 0.1.0 + +* Initial release of encoding_c_mem. diff --git a/third_party/rust/encoding_c_mem/build.rs b/third_party/rust/encoding_c_mem/build.rs new file mode 100644 index 0000000000..962b7ae12b --- /dev/null +++ b/third_party/rust/encoding_c_mem/build.rs @@ -0,0 +1,7 @@ +fn main() { + println!("cargo:rerun-if-changed="); + + let cargo_manifest_dir = std::env::var_os("CARGO_MANIFEST_DIR").unwrap(); + let include_dir = std::path::PathBuf::from(cargo_manifest_dir).join("include"); + println!("cargo:include-dir={}", include_dir.display()); +} diff --git a/third_party/rust/encoding_c_mem/include/encoding_rs_mem.h b/third_party/rust/encoding_c_mem/include/encoding_rs_mem.h new file mode 100644 index 0000000000..2327a9dd0b --- /dev/null +++ b/third_party/rust/encoding_c_mem/include/encoding_rs_mem.h @@ -0,0 +1,704 @@ +// Copyright Mozilla Foundation. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#ifndef encoding_rs_mem_h_ +#define encoding_rs_mem_h_ + +#include +#include +#include + +/* + * _Note:_ "Latin1" in this header refers to the Unicode range from U+0000 to + * U+00FF, inclusive, and does not refer to the windows-1252 range. This + * in-memory encoding is sometimes used as a storage optimization of text + * when UTF-16 indexing and length semantics are exposed. + */ + +/** + * Classification of text as Latin1 (all code points are below U+0100), + * left-to-right with some non-Latin1 characters or as containing at least + * some right-to-left characters. + */ +typedef enum { + /** + * Every character is below U+0100. + */ + Latin1 = 0, + /** + * There is at least one character that's U+0100 or higher, but there + * are no right-to-left characters. + */ + LeftToRight = 1, + /** + * There is at least one right-to-left character. + */ + Bidi = 2, +} Latin1Bidi; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Checks whether a valid UTF-8 buffer contains code points + * that trigger right-to-left processing or is all-Latin1. + * + * Possibly more efficient than performing the checks separately. + * + * Returns `Latin1Bidi::Latin1` if `is_str_latin1()` would return `true`. + * Otherwise, returns `Latin1Bidi::Bidi` if `is_str_bidi()` would return + * `true`. Otherwise, returns `Latin1Bidi::LeftToRight`. + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block, + * if `buffer` is `NULL`, or if the memory designated by `buffer` and + * `buffer_len` does not contain valid UTF-8. (If `buffer_len` is `0`, `buffer` + * may be bogus but still has to be non-`NULL`.) + */ +Latin1Bidi encoding_mem_check_str_for_latin1_and_bidi(const char* buffer, + size_t len); + +/** + * Checks whether a potentially invalid UTF-16 buffer contains code points + * that trigger right-to-left processing or is all-Latin1. + * + * Possibly more efficient than performing the checks separately. + * + * Returns `Latin1Bidi::Latin1` if `is_utf16_latin1()` would return `true`. + * Otherwise, returns `Latin1Bidi::Bidi` if `is_utf16_bidi()` would return + * `true`. Otherwise, returns `Latin1Bidi::LeftToRight`. + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block + * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but + * still has to be non-`NULL` and aligned.) + */ +Latin1Bidi encoding_mem_check_utf16_for_latin1_and_bidi(const char16_t* buffer, + size_t len); + +/** + * Checks whether a potentially invalid UTF-8 buffer contains code points + * that trigger right-to-left processing or is all-Latin1. + * + * Possibly more efficient than performing the checks separately. + * + * Returns `Latin1Bidi::Latin1` if `is_utf8_latin1()` would return `true`. + * + * Otherwise, returns `Latin1Bidi::Bidi` if `is_utf8_bidi()` would return + * `true`. Otherwise, returns `Latin1Bidi::LeftToRight`. + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block + * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but + * still has to be non-`NULL`.) + */ +Latin1Bidi encoding_mem_check_utf8_for_latin1_and_bidi(const char* buffer, + size_t len); + +/** + * Converts bytes whose unsigned value is interpreted as Unicode code point + * (i.e. U+0000 to U+00FF, inclusive) to UTF-16. + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * The number of `char16_t`s written equals the length of the source buffer. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL` or if the two memory blocks overlap. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +void encoding_mem_convert_latin1_to_utf16(const char* src, size_t src_len, + char16_t* dst, size_t dst_len); + +/** + * Converts bytes whose unsigned value is interpreted as Unicode code point + * (i.e. U+0000 to U+00FF, inclusive) to UTF-8. + * + * The length of the destination buffer must be at least the length of the + * source buffer times two. + * + * Returns the number of bytes written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * + * # Safety + * + * Note that this function may write garbage beyond the number of bytes + * indicated by the return value. + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL` or if the two memory blocks overlap. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +size_t encoding_mem_convert_latin1_to_utf8(const char* src, size_t src_len, + char* dst, size_t dst_len); + +/** + * Converts bytes whose unsigned value is interpreted as Unicode code point + * (i.e. U+0000 to U+00FF, inclusive) to UTF-8 with potentially insufficient + * output space. + * + * Writes the number of code units read into `*src_len` and the number of + * bytes written into `*dst_len`. + * + * If the output isn't large enough, not all input is consumed. + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL` or if the two memory blocks overlap. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +void encoding_mem_convert_latin1_to_utf8_partial(const char* src, + size_t* src_len, char* dst, + size_t* dst_len); + +/** + * Converts valid UTF-8 to valid UTF-16. + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * Returns the number of `char16_t`s written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL`, if the two memory blocks overlap, of if the + * buffer designated by `src` and `src_len` does not contain valid UTF-8. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +size_t encoding_mem_convert_str_to_utf16(const char* src, size_t src_len, + char16_t* dst, size_t dst_len); + +/** + * If the input is valid UTF-16 representing only Unicode code points from + * U+0000 to U+00FF, inclusive, converts the input into output that + * represents the value of each code point as the unsigned byte value of + * each output byte. + * + * If the input does not fulfill the condition stated above, does something + * that is memory-safe without any promises about any properties of the + * output and will probably assert in debug builds in future versions. + * In particular, callers shouldn't assume the output to be the same across + * crate versions or CPU architectures and should not assume that non-ASCII + * input can't map to ASCII output. + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * The number of bytes written equals the length of the source buffer. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * (Probably in future versions if debug assertions are enabled (and not + * fuzzing) and the input is not in the range U+0000 to U+00FF, inclusive.) + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL` or if the two memory blocks overlap. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +void encoding_mem_convert_utf16_to_latin1_lossy(const char16_t* src, + size_t src_len, char* dst, + size_t dst_len); + +/** + * Converts potentially-invalid UTF-16 to valid UTF-8 with errors replaced + * with the REPLACEMENT CHARACTER. + * + * The length of the destination buffer must be at least the length of the + * source buffer times three. + * + * Returns the number of bytes written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL` or if the two memory blocks overlap. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +size_t encoding_mem_convert_utf16_to_utf8(const char16_t* src, size_t src_len, + char* dst, size_t dst_len); + +/** + * Converts potentially-invalid UTF-16 to valid UTF-8 with errors replaced + * with the REPLACEMENT CHARACTER with potentially insufficient output + * space. + * + * Writes the number of code units read into `*src_len` and the number of + * bytes written into `*dst_len`. + * + * Guarantees that the bytes in the destination beyond the number of + * bytes claimed as written by the second item of the return tuple + * are left unmodified. + * + * Not all code units are read if there isn't enough output space. + * Note that this method isn't designed for general streamability but for + * not allocating memory for the worst case up front. Specifically, + * if the input starts with or ends with an unpaired surrogate, those are + * replaced with the REPLACEMENT CHARACTER. + * + * Matches the semantics of `TextEncoder.encodeInto()` from the + * Encoding Standard. + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL` or if the two memory blocks overlap. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +void encoding_mem_convert_utf16_to_utf8_partial(const char16_t* src, + size_t* src_len, char* dst, + size_t* dst_len); + +/** + * If the input is valid UTF-8 representing only Unicode code points from + * U+0000 to U+00FF, inclusive, converts the input into output that + * represents the value of each code point as the unsigned byte value of + * each output byte. + * + * If the input does not fulfill the condition stated above, this function + * panics if debug assertions are enabled (and fuzzing isn't) and otherwise + * does something that is memory-safe without any promises about any + * properties of the output. In particular, callers shouldn't assume the + * output to be the same across crate versions or CPU architectures and + * should not assume that non-ASCII input can't map to ASCII output. + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * Returns the number of bytes written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * If debug assertions are enabled (and not fuzzing) and the input is + * not in the range U+0000 to U+00FF, inclusive. + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL` or if the two memory blocks overlap. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +size_t encoding_mem_convert_utf8_to_latin1_lossy(const char* src, + size_t src_len, char* dst, + size_t dst_len); + +/** + * Converts potentially-invalid UTF-8 to valid UTF-16 with errors replaced + * with the REPLACEMENT CHARACTER. + * + * The length of the destination buffer must be at least the length of the + * source buffer _plus one_. + * + * Returns the number of `char16_t`s written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL` or if the two memory blocks overlap. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +size_t encoding_mem_convert_utf8_to_utf16(const char* src, size_t src_len, + char16_t* dst, size_t dst_len); + +/** + * Converts potentially-invalid UTF-8 to valid UTF-16 signaling on error. + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * Returns the number of `char16_t`s written or `SIZE_MAX` if the input was + * invalid. + * + * When the input was invalid, some output may have been written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL` or if the two memory blocks overlap. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +size_t encoding_mem_convert_utf8_to_utf16_without_replacement(const char* src, + size_t src_len, + char16_t* dst, + size_t dst_len); + +/** + * Copies ASCII from source to destination up to the first non-ASCII byte + * (or the end of the input if it is ASCII in its entirety). + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * Returns the number of bytes written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL` or if the two memory blocks overlap. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +size_t encoding_mem_copy_ascii_to_ascii(const char* src, size_t src_len, + char* dst, size_t dst_len); + +/** + * Copies ASCII from source to destination zero-extending it to UTF-16 up to + * the first non-ASCII byte (or the end of the input if it is ASCII in its + * entirety). + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * Returns the number of `char16_t`s written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL` or if the two memory blocks overlap. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +size_t encoding_mem_copy_ascii_to_basic_latin(const char* src, size_t src_len, + char16_t* dst, size_t dst_len); + +/** + * Copies Basic Latin from source to destination narrowing it to ASCII up to + * the first non-Basic Latin code unit (or the end of the input if it is + * Basic Latin in its entirety). + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * Returns the number of bytes written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * + * # Undefined behavior + * + * UB ensues if `src` and `src_len` don't designate a valid memory block, if + * `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory + * block, if `dst` is `NULL` or if the two memory blocks overlap. (If + * `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and + * aligned. Likewise for `dst` and `dst_len`.) + */ +size_t encoding_mem_copy_basic_latin_to_ascii(const char16_t* src, + size_t src_len, char* dst, + size_t dst_len); + +/** + * Replaces unpaired surrogates in the input with the REPLACEMENT CHARACTER. + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block + * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but + * still has to be non-`NULL` and aligned.) + */ +void encoding_mem_ensure_utf16_validity(char16_t* buffer, size_t len); + +/** + * Checks whether the buffer is all-ASCII. + * + * May read the entire buffer even if it isn't all-ASCII. (I.e. the function + * is not guaranteed to fail fast.) + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block + * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but + * still has to be non-`NULL`.) + */ +bool encoding_mem_is_ascii(const char* buffer, size_t len); + +/** + * Checks whether the buffer is all-Basic Latin (i.e. UTF-16 representing + * only ASCII characters). + * + * May read the entire buffer even if it isn't all-ASCII. (I.e. the function + * is not guaranteed to fail fast.) + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block + * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but + * still has to be non-`NULL` and aligned.) + */ +bool encoding_mem_is_basic_latin(const char16_t* buffer, size_t len); + +/** + * Checks whether a scalar value triggers right-to-left processing. + * + * The check is done on a Unicode block basis without regard to assigned + * vs. unassigned code points in the block. Hebrew presentation forms in + * the Alphabetic Presentation Forms block are treated as if they formed + * a block on their own (i.e. it treated as right-to-left). Additionally, + * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked + * for. Control characters that are technically bidi controls but do not + * cause right-to-left behavior without the presence of right-to-left + * characters or right-to-left controls are not checked for. As a special + * case, U+FEFF is excluded from Arabic Presentation Forms-B. + * + * # Undefined behavior + * + * Undefined behavior ensues if `c` is not a valid Unicode Scalar Value. + */ +bool encoding_mem_is_char_bidi(char32_t c); + +/** + * Checks whether a valid UTF-8 buffer contains code points that trigger + * right-to-left processing. + * + * The check is done on a Unicode block basis without regard to assigned + * vs. unassigned code points in the block. Hebrew presentation forms in + * the Alphabetic Presentation Forms block are treated as if they formed + * a block on their own (i.e. it treated as right-to-left). Additionally, + * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked + * for. Control characters that are technically bidi controls but do not + * cause right-to-left behavior without the presence of right-to-left + * characters or right-to-left controls are not checked for. As a special + * case, U+FEFF is excluded from Arabic Presentation Forms-B. + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block, + * if `buffer` is `NULL`, or if the memory designated by `buffer` and + * `buffer_len` does not contain valid UTF-8. (If `buffer_len` is `0`, `buffer` + * may be bogus but still has to be non-`NULL`.) + */ +bool encoding_mem_is_str_bidi(const char* buffer, size_t len); + +/** + * Checks whether the buffer represents only code points less than or equal + * to U+00FF. + * + * Fails fast. (I.e. returns before having read the whole buffer if code + * points above U+00FF are discovered. + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block, + * if `buffer` is `NULL`, or if the memory designated by `buffer` and + * `buffer_len` does not contain valid UTF-8. (If `buffer_len` is `0`, `buffer` + * may be bogus but still has to be non-`NULL`.) + */ +bool encoding_mem_is_str_latin1(const char* buffer, size_t len); + +/** + * Checks whether a UTF-16 buffer contains code points that trigger + * right-to-left processing. + * + * The check is done on a Unicode block basis without regard to assigned + * vs. unassigned code points in the block. Hebrew presentation forms in + * the Alphabetic Presentation Forms block are treated as if they formed + * a block on their own (i.e. it treated as right-to-left). Additionally, + * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked + * for. Control characters that are technically bidi controls but do not + * cause right-to-left behavior without the presence of right-to-left + * characters or right-to-left controls are not checked for. As a special + * case, U+FEFF is excluded from Arabic Presentation Forms-B. + * Returns `true` if the input contains an RTL character or an unpaired + * high surrogate that could be the high half of an RTL character. + * Returns `false` if the input contains neither RTL characters nor + * unpaired high surrogates that could be higher halves of RTL characters. + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block + * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but + * still has to be non-`NULL` and aligned.) + */ +bool encoding_mem_is_utf16_bidi(const char16_t* buffer, size_t len); + +/** + * Checks whether a UTF-16 code unit triggers right-to-left processing. + * + * The check is done on a Unicode block basis without regard to assigned + * vs. unassigned code points in the block. Hebrew presentation forms in + * the Alphabetic Presentation Forms block are treated as if they formed + * a block on their own (i.e. it treated as right-to-left). Additionally, + * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked + * for. Control characters that are technically bidi controls but do not + * cause right-to-left behavior without the presence of right-to-left + * characters or right-to-left controls are not checked for. As a special + * case, U+FEFF is excluded from Arabic Presentation Forms-B. + * Since supplementary-plane right-to-left blocks are identifiable from the + * high surrogate without examining the low surrogate, this function returns + * `true` for such high surrogates making the function suitable for handling + * supplementary-plane text without decoding surrogate pairs to scalar + * values. Obviously, such high surrogates are then reported as right-to-left + * even if actually unpaired. + */ +bool encoding_mem_is_utf16_code_unit_bidi(char16_t u); + +/** + * Checks whether the buffer represents only code point less than or equal + * to U+00FF. + * + * May read the entire buffer even if it isn't all-Latin1. (I.e. the function + * is not guaranteed to fail fast.) + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block + * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but + * still has to be non-`NULL` and aligned.) + */ +bool encoding_mem_is_utf16_latin1(const char16_t* buffer, size_t len); + +/** + * Checks whether a potentially-invalid UTF-8 buffer contains code points + * that trigger right-to-left processing. + * + * The check is done on a Unicode block basis without regard to assigned + * vs. unassigned code points in the block. Hebrew presentation forms in + * the Alphabetic Presentation Forms block are treated as if they formed + * a block on their own (i.e. it treated as right-to-left). Additionally, + * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked + * for. Control characters that are technically bidi controls but do not + * cause right-to-left behavior without the presence of right-to-left + * characters or right-to-left controls are not checked for. As a special + * case, U+FEFF is excluded from Arabic Presentation Forms-B. + * Returns `true` if the input is invalid UTF-8 or the input contains an + * RTL character. Returns `false` if the input is valid UTF-8 and contains + * no RTL characters. + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block + * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but + * still has to be non-`NULL`.) + */ +bool encoding_mem_is_utf8_bidi(const char* buffer, size_t len); + +/** + * Checks whether the buffer is valid UTF-8 representing only code points + * less than or equal to U+00FF. + * + * Fails fast. (I.e. returns before having read the whole buffer if UTF-8 + * invalidity or code points above U+00FF are discovered. + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block + * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but + * still has to be non-`NULL`.) + */ +bool encoding_mem_is_utf8_latin1(const char* buffer, size_t len); + +/** + * Returns the index of the first unpaired surrogate or, if the input is + * valid UTF-16 in its entirety, the length of the input. + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block + * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but + * still has to be non-`NULL` and aligned.) + */ +size_t encoding_mem_utf16_valid_up_to(const char16_t* buffer, size_t len); + +/** + * Returns the index of first byte that starts an invalid byte + * sequence or a non-Latin1 byte sequence, or the length of the + * string if there are neither. + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block + * or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but + * still has to be non-`NULL` and aligned.) + */ +size_t encoding_mem_utf8_latin1_up_to(const char* buffer, size_t len); + +/** + * Returns the index of first byte that starts a non-Latin1 byte + * sequence, or the length of the string if there are none. + * + * # Undefined behavior + * + * UB ensues if `buffer` and `buffer_len` don't designate a valid memory block, + * if `buffer` is `NULL`, or if the memory block does not contain valid UTF-8. + * (If `buffer_len` is `0`, `buffer` may be bogus but still has to be non-`NULL` + * and aligned.) + */ +size_t encoding_mem_str_latin1_up_to(const char* buffer, size_t len); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // encoding_rs_mem_h_ diff --git a/third_party/rust/encoding_c_mem/include/encoding_rs_mem_cpp.h b/third_party/rust/encoding_c_mem/include/encoding_rs_mem_cpp.h new file mode 100644 index 0000000000..b6173d7ef4 --- /dev/null +++ b/third_party/rust/encoding_c_mem/include/encoding_rs_mem_cpp.h @@ -0,0 +1,578 @@ +// Copyright Mozilla Foundation. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#pragma once + +#ifndef encoding_rs_mem_cpp_h_ +#define encoding_rs_mem_cpp_h_ + +#include +#include +#include +#include "gsl/gsl" + +#include "encoding_rs_mem.h" + +namespace encoding_rs { +namespace mem { + +namespace detail { +/** + * Replaces `nullptr` with a bogus pointer suitable for use as part of a + * zero-length Rust slice. + */ +template +static inline T* null_to_bogus(T* ptr) { + return ptr ? ptr : reinterpret_cast(alignof(T)); +} +}; // namespace detail + +/** + * Checks whether a potentially invalid UTF-16 buffer contains code points + * that trigger right-to-left processing or is all-Latin1. + * + * Possibly more efficient than performing the checks separately. + * + * Returns `Latin1Bidi::Latin1` if `is_utf16_latin1()` would return `true`. + * Otherwise, returns `Latin1Bidi::Bidi` if `is_utf16_bidi()` would return + * `true`. Otherwise, returns `Latin1Bidi::LeftToRight`. + */ +inline Latin1Bidi check_for_latin1_and_bidi(std::u16string_view buffer) { + return encoding_mem_check_utf16_for_latin1_and_bidi( + encoding_rs::mem::detail::null_to_bogus(buffer.data()), + buffer.size()); +} + +/** + * Checks whether a potentially invalid UTF-8 buffer contains code points + * that trigger right-to-left processing or is all-Latin1. + * + * Possibly more efficient than performing the checks separately. + * + * Returns `Latin1Bidi::Latin1` if `is_utf8_latin1()` would return `true`. + * + * Otherwise, returns `Latin1Bidi::Bidi` if `is_utf8_bidi()` would return + * `true`. Otherwise, returns `Latin1Bidi::LeftToRight`. + */ +inline Latin1Bidi check_for_latin1_and_bidi(std::string_view buffer) { + return encoding_mem_check_utf8_for_latin1_and_bidi( + encoding_rs::mem::detail::null_to_bogus(buffer.data()), + buffer.size()); +} + +/** + * Converts bytes whose unsigned value is interpreted as Unicode code point + * (i.e. U+0000 to U+00FF, inclusive) to UTF-16. + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * The number of `char16_t`s written equals the length of the source buffer. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + */ +inline void convert_latin1_to_utf16(gsl::span src, + gsl::span dst) { + encoding_mem_convert_latin1_to_utf16( + encoding_rs::mem::detail::null_to_bogus(src.data()), + src.size(), encoding_rs::mem::detail::null_to_bogus(dst.data()), + dst.size()); +} + +/** + * Converts bytes whose unsigned value is interpreted as Unicode code point + * (i.e. U+0000 to U+00FF, inclusive) to UTF-8. + * + * The length of the destination buffer must be at least the length of the + * source buffer times two. + * + * Returns the number of bytes written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * + * # Safety + * + * Note that this function may write garbage beyond the number of bytes + * indicated by the return value. + * + * # Undefined behavior + * + * UB ensues if `src` and `dst` overlap. + */ +inline size_t convert_latin1_to_utf8(gsl::span src, + gsl::span dst) { + return encoding_mem_convert_latin1_to_utf8( + encoding_rs::mem::detail::null_to_bogus(src.data()), + src.size(), encoding_rs::mem::detail::null_to_bogus(dst.data()), + dst.size()); +} + +/** + * Converts bytes whose unsigned value is interpreted as Unicode code point + * (i.e. U+0000 to U+00FF, inclusive) to UTF-8 with potentially insufficient + * output space. + * + * Returns the number of bytes read and the number of bytes written. + * + * If the output isn't large enough, not all input is consumed. + * + * # Undefined behavior + * + * UB ensues if `src` and `dst` overlap. + */ +inline std::tuple convert_latin1_to_utf8_partial( + gsl::span src, gsl::span dst) { + size_t src_read = src.size(); + size_t dst_written = dst.size(); + encoding_mem_convert_latin1_to_utf8_partial( + encoding_rs::mem::detail::null_to_bogus(src.data()), + &src_read, encoding_rs::mem::detail::null_to_bogus(dst.data()), + &dst_written); + return {src_read, dst_written}; +} + +/** + * Converts valid UTF-8 to valid UTF-16. + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * Returns the number of `char16_t`s written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + */ +inline size_t convert_str_to_utf16(std::string_view src, + gsl::span dst) { + return encoding_mem_convert_str_to_utf16( + encoding_rs::mem::detail::null_to_bogus( + reinterpret_cast(src.data())), + src.size(), encoding_rs::mem::detail::null_to_bogus(dst.data()), + dst.size()); +} + +/** + * If the input is valid UTF-16 representing only Unicode code points from + * U+0000 to U+00FF, inclusive, converts the input into output that + * represents the value of each code point as the unsigned byte value of + * each output byte. + * + * If the input does not fulfill the condition stated above, does something + * that is memory-safe without any promises about any properties of the + * output and will probably assert in debug builds in future versions. + * In particular, callers shouldn't assume the output to be the same across + * crate versions or CPU architectures and should not assume that non-ASCII + * input can't map to ASCII output. + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * The number of bytes written equals the length of the source buffer. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * (Probably in future versions if debug assertions are enabled (and not + * fuzzing) and the input is not in the range U+0000 to U+00FF, inclusive.) + */ +inline void convert_utf16_to_latin1_lossy(std::u16string_view src, + gsl::span dst) { + encoding_mem_convert_utf16_to_latin1_lossy( + encoding_rs::mem::detail::null_to_bogus(src.data()), + src.size(), encoding_rs::mem::detail::null_to_bogus(dst.data()), + dst.size()); +} + +/** + * Converts potentially-invalid UTF-16 to valid UTF-8 with errors replaced + * with the REPLACEMENT CHARACTER. + * + * The length of the destination buffer must be at least the length of the + * source buffer times three. + * + * Returns the number of bytes written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + */ +inline size_t convert_utf16_to_utf8(std::u16string_view src, + gsl::span dst) { + return encoding_mem_convert_utf16_to_utf8( + encoding_rs::mem::detail::null_to_bogus(src.data()), + src.size(), encoding_rs::mem::detail::null_to_bogus(dst.data()), + dst.size()); +} + +/** + * Converts potentially-invalid UTF-16 to valid UTF-8 with errors replaced + * with the REPLACEMENT CHARACTER with potentially insufficient output + * space. + * + * Returns the number of code units read and the number of bytes written. + * + * Guarantees that the bytes in the destination beyond the number of + * bytes claimed as written by the second item of the return tuple + * are left unmodified. + * + * Not all code units are read if there isn't enough output space. + * Note that this method isn't designed for general streamability but for + * not allocating memory for the worst case up front. Specifically, + * if the input starts with or ends with an unpaired surrogate, those are + * replaced with the REPLACEMENT CHARACTER. + * + * Matches the semantics of `TextEncoder.encodeInto()` from the + * Encoding Standard. + */ +inline std::tuple convert_utf16_to_utf8_partial( + std::u16string_view src, gsl::span dst) { + size_t src_read = src.size(); + size_t dst_written = dst.size(); + encoding_mem_convert_utf16_to_utf8_partial( + encoding_rs::mem::detail::null_to_bogus(src.data()), + &src_read, encoding_rs::mem::detail::null_to_bogus(dst.data()), + &dst_written); + return {src_read, dst_written}; +} + +/** + * If the input is valid UTF-8 representing only Unicode code points from + * U+0000 to U+00FF, inclusive, converts the input into output that + * represents the value of each code point as the unsigned byte value of + * each output byte. + * + * If the input does not fulfill the condition stated above, this function + * panics if debug assertions are enabled (and fuzzing isn't) and otherwise + * does something that is memory-safe without any promises about any + * properties of the output. In particular, callers shouldn't assume the + * output to be the same across crate versions or CPU architectures and + * should not assume that non-ASCII input can't map to ASCII output. + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * Returns the number of bytes written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * If debug assertions are enabled (and not fuzzing) and the input is + * not in the range U+0000 to U+00FF, inclusive. + * + * # Undefined behavior + * + * UB ensues if `src` and `dst` overlap. + */ +inline size_t convert_utf8_to_latin1_lossy(std::string_view src, + gsl::span dst) { + return encoding_mem_convert_utf8_to_latin1_lossy( + encoding_rs::mem::detail::null_to_bogus( + reinterpret_cast(src.data())), + src.size(), encoding_rs::mem::detail::null_to_bogus(dst.data()), + dst.size()); +} + +/** + * Converts potentially-invalid UTF-8 to valid UTF-16 with errors replaced + * with the REPLACEMENT CHARACTER. + * + * The length of the destination buffer must be at least the length of the + * source buffer _plus one_. + * + * Returns the number of `char16_t`s written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + */ +inline size_t convert_utf8_to_utf16(std::string_view src, + gsl::span dst) { + return encoding_mem_convert_utf8_to_utf16( + encoding_rs::mem::detail::null_to_bogus( + reinterpret_cast(src.data())), + src.size(), encoding_rs::mem::detail::null_to_bogus(dst.data()), + dst.size()); +} + +/** + * Converts potentially-invalid UTF-8 to valid UTF-16 signaling on error. + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * Returns the number of `char16_t`s written or `std::nullopt` if the input was + * invalid. + * + * When the input was invalid, some output may have been written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + */ +inline std::optional convert_utf8_to_utf16_without_replacement( + std::string_view src, gsl::span dst) { + size_t val = encoding_mem_convert_utf8_to_utf16_without_replacement( + encoding_rs::mem::detail::null_to_bogus( + reinterpret_cast(src.data())), + src.size(), encoding_rs::mem::detail::null_to_bogus(dst.data()), + dst.size()); + if (val == SIZE_MAX) { + return std::nullopt; + } + return val; +} + +/** + * Copies ASCII from source to destination up to the first non-ASCII byte + * (or the end of the input if it is ASCII in its entirety). + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * Returns the number of bytes written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + * + * # Undefined behavior + * + * UB ensues if `src` and `dst` overlap. + */ +inline size_t copy_ascii_to_ascii(gsl::span src, + gsl::span dst) { + return encoding_mem_copy_ascii_to_ascii( + encoding_rs::mem::detail::null_to_bogus(src.data()), + src.size(), encoding_rs::mem::detail::null_to_bogus(dst.data()), + dst.size()); +} + +/** + * Copies ASCII from source to destination zero-extending it to UTF-16 up to + * the first non-ASCII byte (or the end of the input if it is ASCII in its + * entirety). + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * Returns the number of `char16_t`s written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + */ +inline size_t copy_ascii_to_basic_latin(gsl::span src, + gsl::span dst) { + return encoding_mem_copy_ascii_to_basic_latin( + encoding_rs::mem::detail::null_to_bogus(src.data()), + src.size(), encoding_rs::mem::detail::null_to_bogus(dst.data()), + dst.size()); +} + +/** + * Copies Basic Latin from source to destination narrowing it to ASCII up to + * the first non-Basic Latin code unit (or the end of the input if it is + * Basic Latin in its entirety). + * + * The length of the destination buffer must be at least the length of the + * source buffer. + * + * Returns the number of bytes written. + * + * # Panics + * + * Panics if the destination buffer is shorter than stated above. + */ +inline size_t copy_basic_latin_to_ascii(gsl::span src, + gsl::span dst) { + return encoding_mem_copy_basic_latin_to_ascii( + encoding_rs::mem::detail::null_to_bogus(src.data()), + src.size(), encoding_rs::mem::detail::null_to_bogus(dst.data()), + dst.size()); +} + +/** + * Replaces unpaired surrogates in the input with the REPLACEMENT CHARACTER. + */ +inline void ensure_utf16_validity(gsl::span buffer) { + encoding_mem_ensure_utf16_validity( + encoding_rs::mem::detail::null_to_bogus(buffer.data()), + buffer.size()); +} + +/** + * Checks whether the buffer is all-ASCII. + * + * May read the entire buffer even if it isn't all-ASCII. (I.e. the function + * is not guaranteed to fail fast.) + */ +inline bool is_ascii(std::string_view buffer) { + return encoding_mem_is_ascii( + encoding_rs::mem::detail::null_to_bogus(buffer.data()), + buffer.size()); +} + +/** + * Checks whether the buffer is all-Basic Latin (i.e. UTF-16 representing + * only ASCII characters). + * + * May read the entire buffer even if it isn't all-ASCII. (I.e. the function + * is not guaranteed to fail fast.) + */ +inline bool is_ascii(std::u16string_view buffer) { + return encoding_mem_is_basic_latin( + encoding_rs::mem::detail::null_to_bogus(buffer.data()), + buffer.size()); +} + +/** + * Checks whether a scalar value triggers right-to-left processing. + * + * The check is done on a Unicode block basis without regard to assigned + * vs. unassigned code points in the block. Hebrew presentation forms in + * the Alphabetic Presentation Forms block are treated as if they formed + * a block on their own (i.e. it treated as right-to-left). Additionally, + * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked + * for. Control characters that are technically bidi controls but do not + * cause right-to-left behavior without the presence of right-to-left + * characters or right-to-left controls are not checked for. As a special + * case, U+FEFF is excluded from Arabic Presentation Forms-B. + * + * # Undefined behavior + * + * Undefined behavior ensues if `c` is not a valid Unicode Scalar Value. + */ +inline bool is_scalar_value_bidi(char32_t c) { + return encoding_mem_is_char_bidi(c); +} + +/** + * Checks whether a UTF-16 buffer contains code points that trigger + * right-to-left processing. + * + * The check is done on a Unicode block basis without regard to assigned + * vs. unassigned code points in the block. Hebrew presentation forms in + * the Alphabetic Presentation Forms block are treated as if they formed + * a block on their own (i.e. it treated as right-to-left). Additionally, + * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked + * for. Control characters that are technically bidi controls but do not + * cause right-to-left behavior without the presence of right-to-left + * characters or right-to-left controls are not checked for. As a special + * case, U+FEFF is excluded from Arabic Presentation Forms-B. + * Returns `true` if the input contains an RTL character or an unpaired + * high surrogate that could be the high half of an RTL character. + * Returns `false` if the input contains neither RTL characters nor + * unpaired high surrogates that could be higher halves of RTL characters. + */ +inline bool is_bidi(std::u16string_view buffer) { + return encoding_mem_is_utf16_bidi( + encoding_rs::mem::detail::null_to_bogus(buffer.data()), + buffer.size()); +} + +/** + * Checks whether a UTF-16 code unit triggers right-to-left processing. + * + * The check is done on a Unicode block basis without regard to assigned + * vs. unassigned code points in the block. Hebrew presentation forms in + * the Alphabetic Presentation Forms block are treated as if they formed + * a block on their own (i.e. it treated as right-to-left). Additionally, + * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked + * for. Control characters that are technically bidi controls but do not + * cause right-to-left behavior without the presence of right-to-left + * characters or right-to-left controls are not checked for. As a special + * case, U+FEFF is excluded from Arabic Presentation Forms-B. + * Since supplementary-plane right-to-left blocks are identifiable from the + * high surrogate without examining the low surrogate, this function returns + * `true` for such high surrogates making the function suitable for handling + * supplementary-plane text without decoding surrogate pairs to scalar + * values. Obviously, such high surrogates are then reported as right-to-left + * even if actually unpaired. + */ +inline bool is_utf16_code_unit_bidi(char16_t u) { + return encoding_mem_is_utf16_code_unit_bidi(u); +} + +/** + * Checks whether the buffer represents only code point less than or equal + * to U+00FF. + * + * May read the entire buffer even if it isn't all-Latin1. (I.e. the function + * is not guaranteed to fail fast.) + */ +inline bool is_utf16_latin1(std::u16string_view buffer) { + return encoding_mem_is_utf16_latin1( + encoding_rs::mem::detail::null_to_bogus(buffer.data()), + buffer.size()); +} + +/** + * Checks whether a potentially-invalid UTF-8 buffer contains code points + * that trigger right-to-left processing. + * + * The check is done on a Unicode block basis without regard to assigned + * vs. unassigned code points in the block. Hebrew presentation forms in + * the Alphabetic Presentation Forms block are treated as if they formed + * a block on their own (i.e. it treated as right-to-left). Additionally, + * the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked + * for. Control characters that are technically bidi controls but do not + * cause right-to-left behavior without the presence of right-to-left + * characters or right-to-left controls are not checked for. As a special + * case, U+FEFF is excluded from Arabic Presentation Forms-B. + * Returns `true` if the input is invalid UTF-8 or the input contains an + * RTL character. Returns `false` if the input is valid UTF-8 and contains + * no RTL characters. + */ +inline bool is_bidi(std::string_view buffer) { + return encoding_mem_is_utf8_bidi( + encoding_rs::mem::detail::null_to_bogus(buffer.data()), + buffer.size()); +} + +/** + * Checks whether the buffer is valid UTF-8 representing only code points + * less than or equal to U+00FF. + * + * Fails fast. (I.e. returns before having read the whole buffer if UTF-8 + * invalidity or code points above U+00FF are discovered. + */ +inline bool is_utf8_latin1(std::string_view buffer) { + return encoding_mem_is_utf8_latin1( + encoding_rs::mem::detail::null_to_bogus(buffer.data()), + buffer.size()); +} + +/** + * Returns the index of the first unpaired surrogate or, if the input is + * valid UTF-16 in its entirety, the length of the input. + */ +inline size_t utf16_valid_up_to(std::u16string_view buffer) { + return encoding_mem_utf16_valid_up_to( + encoding_rs::mem::detail::null_to_bogus(buffer.data()), + buffer.size()); +} + +/** + * Returns the index of first byte that starts a non-Latin1 byte + * sequence, or the length of the string if there are none. + */ +inline size_t utf8_latin1_up_to(std::string_view buffer) { + return encoding_mem_utf8_latin1_up_to( + encoding_rs::mem::detail::null_to_bogus(buffer.data()), + buffer.size()); +} + +}; // namespace mem +}; // namespace encoding_rs + +#endif // encoding_rs_mem_cpp_h_ diff --git a/third_party/rust/encoding_c_mem/src/lib.rs b/third_party/rust/encoding_c_mem/src/lib.rs new file mode 100644 index 0000000000..e5f31c1be0 --- /dev/null +++ b/third_party/rust/encoding_c_mem/src/lib.rs @@ -0,0 +1,825 @@ +// Copyright Mozilla Foundation. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! FFI bindings for `encoding_rs::mem`. +//! +//! _Note:_ "Latin1" in this module refers to the Unicode range from U+0000 to +//! U+00FF, inclusive, and does not refer to the windows-1252 range. This +//! in-memory encoding is sometimes used as a storage optimization of text +//! when UTF-16 indexing and length semantics are exposed. + +use encoding_rs::mem::Latin1Bidi; + +/// Checks whether the buffer is all-ASCII. +/// +/// May read the entire buffer even if it isn't all-ASCII. (I.e. the function +/// is not guaranteed to fail fast.) +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block +/// or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_is_ascii(buffer: *const u8, len: usize) -> bool { + encoding_rs::mem::is_ascii(::std::slice::from_raw_parts(buffer, len)) +} + +/// Checks whether the buffer is all-Basic Latin (i.e. UTF-16 representing +/// only ASCII characters). +/// +/// May read the entire buffer even if it isn't all-ASCII. (I.e. the function +/// is not guaranteed to fail fast.) +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block +/// or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL` and aligned.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_is_basic_latin(buffer: *const u16, len: usize) -> bool { + encoding_rs::mem::is_basic_latin(::std::slice::from_raw_parts(buffer, len)) +} + +/// Checks whether the buffer is valid UTF-8 representing only code points +/// less than or equal to U+00FF. +/// +/// Fails fast. (I.e. returns before having read the whole buffer if UTF-8 +/// invalidity or code points above U+00FF are discovered. +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block +/// or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_is_utf8_latin1(buffer: *const u8, len: usize) -> bool { + encoding_rs::mem::is_utf8_latin1(::std::slice::from_raw_parts(buffer, len)) +} + +/// Checks whether the buffer represents only code points less than or equal +/// to U+00FF. +/// +/// Fails fast. (I.e. returns before having read the whole buffer if code +/// points above U+00FF are discovered. +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block, +/// if `buffer` is `NULL`, or if the memory designated by `buffer` and `buffer_len` +/// does not contain valid UTF-8. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_is_str_latin1(buffer: *const u8, len: usize) -> bool { + encoding_rs::mem::is_str_latin1(::std::str::from_utf8_unchecked( + ::std::slice::from_raw_parts(buffer, len), + )) +} + +/// Checks whether the buffer represents only code point less than or equal +/// to U+00FF. +/// +/// May read the entire buffer even if it isn't all-Latin1. (I.e. the function +/// is not guaranteed to fail fast.) +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block +/// or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL` and aligned.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_is_utf16_latin1(buffer: *const u16, len: usize) -> bool { + encoding_rs::mem::is_utf16_latin1(::std::slice::from_raw_parts(buffer, len)) +} + +/// Checks whether a potentially-invalid UTF-8 buffer contains code points +/// that trigger right-to-left processing. +/// +/// The check is done on a Unicode block basis without regard to assigned +/// vs. unassigned code points in the block. Hebrew presentation forms in +/// the Alphabetic Presentation Forms block are treated as if they formed +/// a block on their own (i.e. it treated as right-to-left). Additionally, +/// the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked +/// for. Control characters that are technically bidi controls but do not +/// cause right-to-left behavior without the presence of right-to-left +/// characters or right-to-left controls are not checked for. As a special +/// case, U+FEFF is excluded from Arabic Presentation Forms-B. +/// +/// Returns `true` if the input is invalid UTF-8 or the input contains an +/// RTL character. Returns `false` if the input is valid UTF-8 and contains +/// no RTL characters. +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block +/// or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_is_utf8_bidi(buffer: *const u8, len: usize) -> bool { + encoding_rs::mem::is_utf8_bidi(::std::slice::from_raw_parts(buffer, len)) +} + +/// Checks whether a valid UTF-8 buffer contains code points that trigger +/// right-to-left processing. +/// +/// The check is done on a Unicode block basis without regard to assigned +/// vs. unassigned code points in the block. Hebrew presentation forms in +/// the Alphabetic Presentation Forms block are treated as if they formed +/// a block on their own (i.e. it treated as right-to-left). Additionally, +/// the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked +/// for. Control characters that are technically bidi controls but do not +/// cause right-to-left behavior without the presence of right-to-left +/// characters or right-to-left controls are not checked for. As a special +/// case, U+FEFF is excluded from Arabic Presentation Forms-B. +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block, +/// if `buffer` is `NULL`, or if the memory designated by `buffer` and `buffer_len` +/// does not contain valid UTF-8. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_is_str_bidi(buffer: *const u8, len: usize) -> bool { + encoding_rs::mem::is_str_bidi(::std::str::from_utf8_unchecked( + ::std::slice::from_raw_parts(buffer, len), + )) +} + +/// Checks whether a UTF-16 buffer contains code points that trigger +/// right-to-left processing. +/// +/// The check is done on a Unicode block basis without regard to assigned +/// vs. unassigned code points in the block. Hebrew presentation forms in +/// the Alphabetic Presentation Forms block are treated as if they formed +/// a block on their own (i.e. it treated as right-to-left). Additionally, +/// the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked +/// for. Control characters that are technically bidi controls but do not +/// cause right-to-left behavior without the presence of right-to-left +/// characters or right-to-left controls are not checked for. As a special +/// case, U+FEFF is excluded from Arabic Presentation Forms-B. +/// +/// Returns `true` if the input contains an RTL character or an unpaired +/// high surrogate that could be the high half of an RTL character. +/// Returns `false` if the input contains neither RTL characters nor +/// unpaired high surrogates that could be higher halves of RTL characters. +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block +/// or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL` and aligned.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_is_utf16_bidi(buffer: *const u16, len: usize) -> bool { + encoding_rs::mem::is_utf16_bidi(::std::slice::from_raw_parts(buffer, len)) +} + +/// Checks whether a scalar value triggers right-to-left processing. +/// +/// The check is done on a Unicode block basis without regard to assigned +/// vs. unassigned code points in the block. Hebrew presentation forms in +/// the Alphabetic Presentation Forms block are treated as if they formed +/// a block on their own (i.e. it treated as right-to-left). Additionally, +/// the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked +/// for. Control characters that are technically bidi controls but do not +/// cause right-to-left behavior without the presence of right-to-left +/// characters or right-to-left controls are not checked for. As a special +/// case, U+FEFF is excluded from Arabic Presentation Forms-B. +/// +/// # Undefined behavior +/// +/// Undefined behavior ensues if `c` is not a valid Unicode Scalar Value. +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_is_char_bidi(c: char) -> bool { + encoding_rs::mem::is_char_bidi(c) +} + +/// Checks whether a UTF-16 code unit triggers right-to-left processing. +/// +/// The check is done on a Unicode block basis without regard to assigned +/// vs. unassigned code points in the block. Hebrew presentation forms in +/// the Alphabetic Presentation Forms block are treated as if they formed +/// a block on their own (i.e. it treated as right-to-left). Additionally, +/// the four RIGHT-TO-LEFT FOO controls in General Punctuation are checked +/// for. Control characters that are technically bidi controls but do not +/// cause right-to-left behavior without the presence of right-to-left +/// characters or right-to-left controls are not checked for. As a special +/// case, U+FEFF is excluded from Arabic Presentation Forms-B. +/// +/// Since supplementary-plane right-to-left blocks are identifiable from the +/// high surrogate without examining the low surrogate, this function returns +/// `true` for such high surrogates making the function suitable for handling +/// supplementary-plane text without decoding surrogate pairs to scalar +/// values. Obviously, such high surrogates are then reported as right-to-left +/// even if actually unpaired. +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_is_utf16_code_unit_bidi(u: u16) -> bool { + encoding_rs::mem::is_utf16_code_unit_bidi(u) +} + +/// Checks whether a potentially invalid UTF-8 buffer contains code points +/// that trigger right-to-left processing or is all-Latin1. +/// +/// Possibly more efficient than performing the checks separately. +/// +/// Returns `Latin1Bidi::Latin1` if `is_utf8_latin1()` would return `true`. +/// Otherwise, returns `Latin1Bidi::Bidi` if `is_utf8_bidi()` would return +/// `true`. Otherwise, returns `Latin1Bidi::LeftToRight`. +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block +/// or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_check_utf8_for_latin1_and_bidi( + buffer: *const u8, + len: usize, +) -> Latin1Bidi { + encoding_rs::mem::check_utf8_for_latin1_and_bidi(::std::slice::from_raw_parts(buffer, len)) +} + +/// Checks whether a valid UTF-8 buffer contains code points +/// that trigger right-to-left processing or is all-Latin1. +/// +/// Possibly more efficient than performing the checks separately. +/// +/// Returns `Latin1Bidi::Latin1` if `is_str_latin1()` would return `true`. +/// Otherwise, returns `Latin1Bidi::Bidi` if `is_str_bidi()` would return +/// `true`. Otherwise, returns `Latin1Bidi::LeftToRight`. +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block, +/// if `buffer` is `NULL`, or if the memory designated by `buffer` and `buffer_len` +/// does not contain valid UTF-8. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_check_str_for_latin1_and_bidi( + buffer: *const u8, + len: usize, +) -> Latin1Bidi { + encoding_rs::mem::check_str_for_latin1_and_bidi(::std::str::from_utf8_unchecked( + ::std::slice::from_raw_parts(buffer, len), + )) +} + +/// Checks whether a potentially invalid UTF-16 buffer contains code points +/// that trigger right-to-left processing or is all-Latin1. +/// +/// Possibly more efficient than performing the checks separately. +/// +/// Returns `Latin1Bidi::Latin1` if `is_utf16_latin1()` would return `true`. +/// Otherwise, returns `Latin1Bidi::Bidi` if `is_utf16_bidi()` would return +/// `true`. Otherwise, returns `Latin1Bidi::LeftToRight`. +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block +/// or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL` and aligned.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_check_utf16_for_latin1_and_bidi( + buffer: *const u16, + len: usize, +) -> Latin1Bidi { + encoding_rs::mem::check_utf16_for_latin1_and_bidi(::std::slice::from_raw_parts(buffer, len)) +} + +/// Converts potentially-invalid UTF-8 to valid UTF-16 with errors replaced +/// with the REPLACEMENT CHARACTER. +/// +/// The length of the destination buffer must be at least the length of the +/// source buffer _plus one_. +/// +/// Returns the number of `u16`s written. +/// +/// # Panics +/// +/// Panics if the destination buffer is shorter than stated above. +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL` or if the two memory blocks overlap. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_convert_utf8_to_utf16( + src: *const u8, + src_len: usize, + dst: *mut u16, + dst_len: usize, +) -> usize { + encoding_rs::mem::convert_utf8_to_utf16( + ::std::slice::from_raw_parts(src, src_len), + ::std::slice::from_raw_parts_mut(dst, dst_len), + ) +} + +/// Converts valid UTF-8 to valid UTF-16. +/// +/// The length of the destination buffer must be at least the length of the +/// source buffer. +/// +/// Returns the number of `u16`s written. +/// +/// # Panics +/// +/// Panics if the destination buffer is shorter than stated above. +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL`, if the two memory blocks overlap, of if the +/// buffer designated by `src` and `src_len` does not contain valid UTF-8. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_convert_str_to_utf16( + src: *const u8, + src_len: usize, + dst: *mut u16, + dst_len: usize, +) -> usize { + encoding_rs::mem::convert_str_to_utf16( + ::std::str::from_utf8_unchecked(::std::slice::from_raw_parts(src, src_len)), + ::std::slice::from_raw_parts_mut(dst, dst_len), + ) +} + +/// Converts potentially-invalid UTF-8 to valid UTF-16 signaling on error. +/// +/// The length of the destination buffer must be at least the length of the +/// source buffer. +/// +/// Returns the number of `u16`s written or `SIZE_MAX` if the input was invalid. +/// +/// When the input was invalid, some output may have been written. +/// +/// # Panics +/// +/// Panics if the destination buffer is shorter than stated above. +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL` or if the two memory blocks overlap. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_convert_utf8_to_utf16_without_replacement( + src: *const u8, + src_len: usize, + dst: *mut u16, + dst_len: usize, +) -> usize { + encoding_rs::mem::convert_utf8_to_utf16_without_replacement( + ::std::slice::from_raw_parts(src, src_len), + ::std::slice::from_raw_parts_mut(dst, dst_len), + ).unwrap_or(::std::usize::MAX) +} + +/// Converts potentially-invalid UTF-16 to valid UTF-8 with errors replaced +/// with the REPLACEMENT CHARACTER with potentially insufficient output +/// space. +/// +/// Writes the number of code units read into `*src_len` and the number of +/// bytes written into `*dst_len`. +/// +/// Guarantees that the bytes in the destination beyond the number of +/// bytes claimed as written by the second item of the return tuple +/// are left unmodified. +/// +/// Not all code units are read if there isn't enough output space. +/// +/// Note that this method isn't designed for general streamability but for +/// not allocating memory for the worst case up front. Specifically, +/// if the input starts with or ends with an unpaired surrogate, those are +/// replaced with the REPLACEMENT CHARACTER. +/// +/// Matches the semantics of `TextEncoder.encodeInto()` from the +/// Encoding Standard. +/// +/// # Safety +/// +/// If you want to convert into a `&mut str`, use +/// `convert_utf16_to_str_partial()` instead of using this function +/// together with the `unsafe` method `as_bytes_mut()` on `&mut str`. +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL` or if the two memory blocks overlap. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_convert_utf16_to_utf8_partial( + src: *const u16, + src_len: *mut usize, + dst: *mut u8, + dst_len: *mut usize, +) { + let (read, written) = encoding_rs::mem::convert_utf16_to_utf8_partial( + ::std::slice::from_raw_parts(src, *src_len), + ::std::slice::from_raw_parts_mut(dst, *dst_len), + ); + *src_len = read; + *dst_len = written; +} + +/// Converts potentially-invalid UTF-16 to valid UTF-8 with errors replaced +/// with the REPLACEMENT CHARACTER. +/// +/// The length of the destination buffer must be at least the length of the +/// source buffer times three. +/// +/// Returns the number of bytes written. +/// +/// # Panics +/// +/// Panics if the destination buffer is shorter than stated above. +/// +/// # Safety +/// +/// If you want to convert into a `&mut str`, use `convert_utf16_to_str()` +/// instead of using this function together with the `unsafe` method +/// `as_bytes_mut()` on `&mut str`. +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL` or if the two memory blocks overlap. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_convert_utf16_to_utf8( + src: *const u16, + src_len: usize, + dst: *mut u8, + dst_len: usize, +) -> usize { + encoding_rs::mem::convert_utf16_to_utf8( + ::std::slice::from_raw_parts(src, src_len), + ::std::slice::from_raw_parts_mut(dst, dst_len), + ) +} + +/// Converts bytes whose unsigned value is interpreted as Unicode code point +/// (i.e. U+0000 to U+00FF, inclusive) to UTF-16. +/// +/// The length of the destination buffer must be at least the length of the +/// source buffer. +/// +/// The number of `u16`s written equals the length of the source buffer. +/// +/// # Panics +/// +/// Panics if the destination buffer is shorter than stated above. +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL` or if the two memory blocks overlap. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_convert_latin1_to_utf16( + src: *const u8, + src_len: usize, + dst: *mut u16, + dst_len: usize, +) { + encoding_rs::mem::convert_latin1_to_utf16( + ::std::slice::from_raw_parts(src, src_len), + ::std::slice::from_raw_parts_mut(dst, dst_len), + ); +} + +/// Converts bytes whose unsigned value is interpreted as Unicode code point +/// (i.e. U+0000 to U+00FF, inclusive) to UTF-8 with potentially insufficient +/// output space. +/// +/// Writes the number of code units read into `*src_len` and the number of +/// bytes written into `*dst_len`. +/// +/// If the output isn't large enough, not all input is consumed. +/// +/// # Safety +/// +/// If you want to convert into a `&mut str`, use +/// `encoding_mem_convert_latin1_to_str_partial()` instead of using this function +/// together with the `unsafe` method `as_bytes_mut()` on `&mut str`. +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL` or if the two memory blocks overlap. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_convert_latin1_to_utf8_partial( + src: *const u8, + src_len: *mut usize, + dst: *mut u8, + dst_len: *mut usize, +) { + let (read, written) = encoding_rs::mem::convert_latin1_to_utf8_partial( + ::std::slice::from_raw_parts(src, *src_len), + ::std::slice::from_raw_parts_mut(dst, *dst_len), + ); + *src_len = read; + *dst_len = written; +} + +/// Converts bytes whose unsigned value is interpreted as Unicode code point +/// (i.e. U+0000 to U+00FF, inclusive) to UTF-8. +/// +/// The length of the destination buffer must be at least the length of the +/// source buffer times two. +/// +/// Returns the number of bytes written. +/// +/// # Panics +/// +/// Panics if the destination buffer is shorter than stated above. +/// +/// # Safety +/// +/// Note that this function may write garbage beyond the number of bytes +/// indicated by the return value, so using a `&mut str` interpreted as +/// `&mut [u8]` as the destination is not safe. If you want to convert into +/// a `&mut str`, use `convert_utf16_to_str()` instead of this function. +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL` or if the two memory blocks overlap. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_convert_latin1_to_utf8( + src: *const u8, + src_len: usize, + dst: *mut u8, + dst_len: usize, +) -> usize { + encoding_rs::mem::convert_latin1_to_utf8( + ::std::slice::from_raw_parts(src, src_len), + ::std::slice::from_raw_parts_mut(dst, dst_len), + ) +} + +/// If the input is valid UTF-8 representing only Unicode code points from +/// U+0000 to U+00FF, inclusive, converts the input into output that +/// represents the value of each code point as the unsigned byte value of +/// each output byte. +/// +/// If the input does not fulfill the condition stated above, this function +/// panics if debug assertions are enabled (and fuzzing isn't) and otherwise +/// does something that is memory-safe without any promises about any +/// properties of the output. In particular, callers shouldn't assume the +/// output to be the same across crate versions or CPU architectures and +/// should not assume that non-ASCII input can't map to ASCII output. +/// +/// The length of the destination buffer must be at least the length of the +/// source buffer. +/// +/// Returns the number of bytes written. +/// +/// # Panics +/// +/// Panics if the destination buffer is shorter than stated above. +/// +/// If debug assertions are enabled (and not fuzzing) and the input is +/// not in the range U+0000 to U+00FF, inclusive. +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL` or if the two memory blocks overlap. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_convert_utf8_to_latin1_lossy( + src: *const u8, + src_len: usize, + dst: *mut u8, + dst_len: usize, +) -> usize { + encoding_rs::mem::convert_utf8_to_latin1_lossy( + ::std::slice::from_raw_parts(src, src_len), + ::std::slice::from_raw_parts_mut(dst, dst_len), + ) +} + +/// If the input is valid UTF-16 representing only Unicode code points from +/// U+0000 to U+00FF, inclusive, converts the input into output that +/// represents the value of each code point as the unsigned byte value of +/// each output byte. +/// +/// If the input does not fulfill the condition stated above, does something +/// that is memory-safe without any promises about any properties of the +/// output and will probably assert in debug builds in future versions. +/// In particular, callers shouldn't assume the output to be the same across +/// crate versions or CPU architectures and should not assume that non-ASCII +/// input can't map to ASCII output. +/// +/// The length of the destination buffer must be at least the length of the +/// source buffer. +/// +/// The number of bytes written equals the length of the source buffer. +/// +/// # Panics +/// +/// Panics if the destination buffer is shorter than stated above. +/// +/// (Probably in future versions if debug assertions are enabled (and not +/// fuzzing) and the input is not in the range U+0000 to U+00FF, inclusive.) +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL` or if the two memory blocks overlap. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_convert_utf16_to_latin1_lossy( + src: *const u16, + src_len: usize, + dst: *mut u8, + dst_len: usize, +) { + encoding_rs::mem::convert_utf16_to_latin1_lossy( + ::std::slice::from_raw_parts(src, src_len), + ::std::slice::from_raw_parts_mut(dst, dst_len), + ); +} + +/// Returns the index of the first unpaired surrogate or, if the input is +/// valid UTF-16 in its entirety, the length of the input. +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block +/// or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL` and aligned.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_utf16_valid_up_to(buffer: *const u16, len: usize) -> usize { + encoding_rs::mem::utf16_valid_up_to(::std::slice::from_raw_parts(buffer, len)) +} + +/// Returns the index of first byte that starts an invalid byte +/// sequence or a non-Latin1 byte sequence, or the length of the +/// string if there are neither. +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block +/// or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL` and aligned.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_utf8_latin1_up_to(buffer: *const u8, len: usize) -> usize { + encoding_rs::mem::utf8_latin1_up_to(::std::slice::from_raw_parts(buffer, len)) +} + +/// Returns the index of first byte that starts a non-Latin1 byte +/// sequence, or the length of the string if there are none. +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block, +/// if `buffer` is `NULL`, or if the memory block does not contain valid UTF-8. +/// (If `buffer_len` is `0`, `buffer` may be bogus but still has to be non-`NULL` +/// and aligned.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_str_latin1_up_to(buffer: *const u8, len: usize) -> usize { + encoding_rs::mem::str_latin1_up_to(::std::str::from_utf8_unchecked( + ::std::slice::from_raw_parts(buffer, len), + )) +} + +/// Replaces unpaired surrogates in the input with the REPLACEMENT CHARACTER. +/// +/// # Undefined behavior +/// +/// UB ensues if `buffer` and `buffer_len` don't designate a valid memory block +/// or if `buffer` is `NULL`. (If `buffer_len` is `0`, `buffer` may be bogus but +/// still has to be non-`NULL` and aligned.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_ensure_utf16_validity(buffer: *mut u16, len: usize) { + encoding_rs::mem::ensure_utf16_validity(::std::slice::from_raw_parts_mut(buffer, len)); +} + +/// Copies ASCII from source to destination up to the first non-ASCII byte +/// (or the end of the input if it is ASCII in its entirety). +/// +/// The length of the destination buffer must be at least the length of the +/// source buffer. +/// +/// Returns the number of bytes written. +/// +/// # Panics +/// +/// Panics if the destination buffer is shorter than stated above. +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL` or if the two memory blocks overlap. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_copy_ascii_to_ascii( + src: *const u8, + src_len: usize, + dst: *mut u8, + dst_len: usize, +) -> usize { + encoding_rs::mem::copy_ascii_to_ascii( + ::std::slice::from_raw_parts(src, src_len), + ::std::slice::from_raw_parts_mut(dst, dst_len), + ) +} + +/// Copies ASCII from source to destination zero-extending it to UTF-16 up to +/// the first non-ASCII byte (or the end of the input if it is ASCII in its +/// entirety). +/// +/// The length of the destination buffer must be at least the length of the +/// source buffer. +/// +/// Returns the number of `u16`s written. +/// +/// # Panics +/// +/// Panics if the destination buffer is shorter than stated above. +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL` or if the two memory blocks overlap. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_copy_ascii_to_basic_latin( + src: *const u8, + src_len: usize, + dst: *mut u16, + dst_len: usize, +) -> usize { + encoding_rs::mem::copy_ascii_to_basic_latin( + ::std::slice::from_raw_parts(src, src_len), + ::std::slice::from_raw_parts_mut(dst, dst_len), + ) +} + +/// Copies Basic Latin from source to destination narrowing it to ASCII up to +/// the first non-Basic Latin code unit (or the end of the input if it is +/// Basic Latin in its entirety). +/// +/// The length of the destination buffer must be at least the length of the +/// source buffer. +/// +/// Returns the number of bytes written. +/// +/// # Panics +/// +/// Panics if the destination buffer is shorter than stated above. +/// +/// # Undefined behavior +/// +/// UB ensues if `src` and `src_len` don't designate a valid memory block, if +/// `src` is `NULL`, if `dst` and `dst_len` don't designate a valid memory +/// block, if `dst` is `NULL` or if the two memory blocks overlap. (If +/// `src_len` is `0`, `src` may be bogus but still has to be non-`NULL` and +/// aligned. Likewise for `dst` and `dst_len`.) +#[no_mangle] +pub unsafe extern "C" fn encoding_mem_copy_basic_latin_to_ascii( + src: *const u16, + src_len: usize, + dst: *mut u8, + dst_len: usize, +) -> usize { + encoding_rs::mem::copy_basic_latin_to_ascii( + ::std::slice::from_raw_parts(src, src_len), + ::std::slice::from_raw_parts_mut(dst, dst_len), + ) +} -- cgit v1.2.3