mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 12:50:09 +00:00
Bug 1715648 - Update mp4parse-rust to 1bb484e. r=aosmond
Differential Revision: https://phabricator.services.mozilla.com/D117373
This commit is contained in:
parent
18c31e716e
commit
4f81223dbe
@ -20,7 +20,7 @@ tag = "v0.4.25"
|
||||
[source."https://github.com/mozilla/mp4parse-rust"]
|
||||
git = "https://github.com/mozilla/mp4parse-rust"
|
||||
replace-with = "vendored-sources"
|
||||
rev = "28327103f0c01b5393dd2c97f7858f9747037330"
|
||||
rev = "1bb484e96ae724309e3346968e8ffd4c25e61616"
|
||||
|
||||
[source."https://github.com/mozilla/cubeb-pulse-rs"]
|
||||
git = "https://github.com/mozilla/cubeb-pulse-rs"
|
||||
|
17
Cargo.lock
generated
17
Cargo.lock
generated
@ -1386,15 +1386,6 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||
|
||||
[[package]]
|
||||
name = "fallible_collections"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9599e8ccc571becb62700174680e54e5c50fc5b4d34c1c56d8915e0325650fea"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fallible_collections"
|
||||
version = "0.4.2"
|
||||
@ -3275,12 +3266,12 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "mp4parse"
|
||||
version = "0.11.5"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=28327103f0c01b5393dd2c97f7858f9747037330#28327103f0c01b5393dd2c97f7858f9747037330"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=1bb484e96ae724309e3346968e8ffd4c25e61616#1bb484e96ae724309e3346968e8ffd4c25e61616"
|
||||
dependencies = [
|
||||
"bitreader",
|
||||
"byteorder",
|
||||
"env_logger",
|
||||
"fallible_collections 0.4.2",
|
||||
"fallible_collections",
|
||||
"hashbrown",
|
||||
"log",
|
||||
"num-traits",
|
||||
@ -3294,10 +3285,10 @@ version = "0.1.0"
|
||||
[[package]]
|
||||
name = "mp4parse_capi"
|
||||
version = "0.11.5"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=28327103f0c01b5393dd2c97f7858f9747037330#28327103f0c01b5393dd2c97f7858f9747037330"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=1bb484e96ae724309e3346968e8ffd4c25e61616#1bb484e96ae724309e3346968e8ffd4c25e61616"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"fallible_collections 0.3.1",
|
||||
"fallible_collections",
|
||||
"log",
|
||||
"mp4parse",
|
||||
"num-traits",
|
||||
|
@ -1 +0,0 @@
|
||||
{"files":{"Cargo.toml":"9be745f2a777ab28fdaccf77169f89aad4eb28fee0513628312a00d5e4561c06","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0621878e61f0d0fda054bcbe02df75192c28bde1ecc8289cbd86aeba2dd72720","README.md":"d05831c6d3375eb1fcb35183ab4ff3fa7b5819068b728a49af3102f5f8fdf7e0","src/arc.rs":"60742619b7404d8c46237e9a3f98c49f75f88e4c24513ebca1d0ddad0274b6d6","src/boxed.rs":"40537576912a01ed8bb3bd6b1c8179632613f37f65459e708d4abc2286933c57","src/btree.rs":"b83820fc2a00e2e34127b3037abde8b945f0ca2785f3def725787e6813c3d3e0","src/btree/map.rs":"4d8710cf6f00bd889045a6144de692d9f752d51089db493e859d55e5ba12430a","src/btree/node.rs":"f6b4557d30ca0e30c7c7b6752c7a2c67432aab5c18c08392a28040326620a109","src/btree/search.rs":"ae78f73f3e56ea277b0a02cc39454447b75e12a6c817ecfee00065b3ddbfff67","src/btree/set.rs":"29cc3bff736007b21e14017d880edbcc7c76c30e0c256e811cae1fff0dad13fa","src/format.rs":"cee32d75cf260b19c8db74b50852bc50b8c47189d22b7424b647d084c4a76857","src/hashmap.rs":"d64ce1acfb3a4ea3e1f0130f5bcf6a3064fce01a0055e0f29163034adaa14173","src/lib.rs":"4cd0ef055208600292ec075f600e940eafcd24bd3e74fe34bba9164842d7f380","src/rc.rs":"102ad49f2201b9f69b50cf5a35af1e0039094936354b12572702551970c2f53c","src/try_clone.rs":"32c790435c71dec116756c284d2b953d382292b7727675740229a6b53d8c8b41","src/vec.rs":"f5170e48333803a49d74b670eb48917c77613d3df97ba8bbfb75340d59898ace"},"package":"9599e8ccc571becb62700174680e54e5c50fc5b4d34c1c56d8915e0325650fea"}
|
@ -1,28 +0,0 @@
|
||||
# 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 = "fallible_collections"
|
||||
version = "0.3.1"
|
||||
authors = ["vcombey <vcombey@student.42.fr>"]
|
||||
description = "a crate which adds fallible allocation api to std collections"
|
||||
readme = "README.md"
|
||||
keywords = ["fallible", "collections"]
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/vcombey/fallible_collections.git"
|
||||
[dependencies.hashbrown]
|
||||
version = "0.9"
|
||||
|
||||
[features]
|
||||
std_io = []
|
||||
unstable = []
|
@ -1,201 +0,0 @@
|
||||
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.
|
@ -1,25 +0,0 @@
|
||||
Copyright (c) 2010 The Rust Project Developers
|
||||
|
||||
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.
|
@ -1,73 +0,0 @@
|
||||
Fallible Collections.rs
|
||||
==============
|
||||
|
||||
Implement api on rust collection wich returns a result when an allocation error occurs.
|
||||
This is inspired a lot by [RFC 2116](https://github.com/rust-lang/rfcs/blob/master/text/2116-alloc-me-maybe.md).
|
||||
|
||||
The api currently propose a fallible interface for Vec, Box, Arc, Btree and Rc,
|
||||
a TryClone trait wich is implemented for primitive rust traits and a fallible format macro.
|
||||
|
||||
You can use this with try_clone_derive crate wich derive TryClone for your own types.
|
||||
|
||||
# Getting Started
|
||||
|
||||
[fallible collections is available on crates.io](https://crates.io/crates/fallible_collections).
|
||||
It is recommended to look there for the newest released version, as well as links to the newest builds of the docs.
|
||||
|
||||
At the point of the last update of this README, the latest published version could be used like this:
|
||||
|
||||
Add the following dependency to your Cargo manifest...
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
fallible_collections = "0.3.1"
|
||||
```
|
||||
|
||||
...and see the [docs](https://docs.rs/fallible_collections) for how to use it.
|
||||
|
||||
# Example
|
||||
|
||||
Exemple of using the FallibleBox interface.
|
||||
```rust
|
||||
use fallible_collections::FallibleBox;
|
||||
|
||||
fn main() {
|
||||
// this crate an Ordinary box but return an error on allocation failure
|
||||
let mut a = Box::try_new(5).unwrap();
|
||||
let mut b = Box::new(5);
|
||||
|
||||
assert_eq!(a, b);
|
||||
*a = 3;
|
||||
assert_eq!(*a, 3);
|
||||
}
|
||||
```
|
||||
|
||||
Exemple of using the FallibleVec interface.
|
||||
```rust
|
||||
use fallible_collections::FallibleVec;
|
||||
|
||||
fn main() {
|
||||
// this crate an Ordinary Vec<Vec<u8>> but return an error on allocation failure
|
||||
let a: Vec<Vec<u8>> = try_vec![try_vec![42; 10].unwrap(); 100].unwrap();
|
||||
let b: Vec<Vec<u8>> = vec![vec![42; 10]; 100];
|
||||
assert_eq!(a, b);
|
||||
assert_eq!(a.try_clone().unwrap(), a);
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
|
||||
additional terms or conditions.
|
||||
|
@ -1,46 +0,0 @@
|
||||
//! Implement a Fallible Arc
|
||||
use super::FallibleBox;
|
||||
use super::TryClone;
|
||||
|
||||
use crate::TryReserveError;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::sync::Arc;
|
||||
|
||||
/// trait to implement Fallible Arc
|
||||
pub trait FallibleArc<T> {
|
||||
/// try creating a new Arc, returning a Result<Box<T>,
|
||||
/// TryReserveError> if allocation failed
|
||||
fn try_new(t: T) -> Result<Self, TryReserveError>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
impl<T> FallibleArc<T> for Arc<T> {
|
||||
fn try_new(t: T) -> Result<Self, TryReserveError> {
|
||||
// doesn't work as the inner variable of arc are also stocked in the box
|
||||
let b = Box::try_new(t)?;
|
||||
Ok(Arc::from(b))
|
||||
}
|
||||
}
|
||||
|
||||
/// Just a TryClone boilerplate for Arc
|
||||
impl<T: ?Sized> TryClone for Arc<T> {
|
||||
fn try_clone(&self) -> Result<Self, TryReserveError> {
|
||||
Ok(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn fallible_rc() {
|
||||
use std::sync::Arc;
|
||||
|
||||
let mut x = Arc::new(3);
|
||||
*Arc::get_mut(&mut x).unwrap() = 4;
|
||||
assert_eq!(*x, 4);
|
||||
|
||||
let _y = Arc::clone(&x);
|
||||
assert!(Arc::get_mut(&mut x).is_none());
|
||||
}
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
//! Implement Fallible Box
|
||||
use super::TryClone;
|
||||
use crate::TryReserveError;
|
||||
use alloc::alloc::Layout;
|
||||
use alloc::boxed::Box;
|
||||
use core::borrow::Borrow;
|
||||
use core::ptr::NonNull;
|
||||
|
||||
/// trait to implement Fallible Box
|
||||
pub trait FallibleBox<T> {
|
||||
/// try creating a new box, returning a Result<Box<T>,
|
||||
/// TryReserveError> if allocation failed
|
||||
fn try_new(t: T) -> Result<Self, TryReserveError>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
/// TryBox is a thin wrapper around alloc::boxed::Box to provide support for
|
||||
/// fallible allocation.
|
||||
///
|
||||
/// See the crate documentation for more.
|
||||
pub struct TryBox<T> {
|
||||
inner: Box<T>,
|
||||
}
|
||||
|
||||
impl<T> TryBox<T> {
|
||||
pub fn try_new(t: T) -> Result<Self, TryReserveError> {
|
||||
Ok(Self {
|
||||
inner: Box::try_new(t)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn into_raw(b: TryBox<T>) -> *mut T {
|
||||
Box::into_raw(b.inner)
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// See std::boxed::from_raw
|
||||
pub unsafe fn from_raw(raw: *mut T) -> Self {
|
||||
Self {
|
||||
inner: Box::from_raw(raw),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TryClone> TryClone for TryBox<T> {
|
||||
fn try_clone(&self) -> Result<Self, TryReserveError> {
|
||||
let clone: T = (*self.inner).try_clone()?;
|
||||
Self::try_new(clone)
|
||||
}
|
||||
}
|
||||
|
||||
fn alloc(layout: Layout) -> Result<NonNull<u8>, TryReserveError> {
|
||||
#[cfg(feature = "unstable")] // requires allocator_api
|
||||
{
|
||||
use core::alloc::AllocRef as _;
|
||||
let mut g = alloc::alloc::Global;
|
||||
g.alloc(layout, alloc::alloc::AllocInit::Uninitialized)
|
||||
.map_err(|_e| TryReserveError::AllocError {
|
||||
layout,
|
||||
non_exhaustive: (),
|
||||
})
|
||||
.map(|memory_block| memory_block.ptr)
|
||||
}
|
||||
#[cfg(not(feature = "unstable"))]
|
||||
{
|
||||
match layout.size() {
|
||||
0 => {
|
||||
// Required for alloc safety
|
||||
// See https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html#safety-1
|
||||
Ok(NonNull::dangling())
|
||||
}
|
||||
1..=core::usize::MAX => {
|
||||
let ptr = unsafe { alloc::alloc::alloc(layout) };
|
||||
core::ptr::NonNull::new(ptr).ok_or(TryReserveError::AllocError { layout })
|
||||
}
|
||||
_ => unreachable!("size must be non-negative"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FallibleBox<T> for Box<T> {
|
||||
fn try_new(t: T) -> Result<Self, TryReserveError> {
|
||||
let layout = Layout::for_value(&t);
|
||||
let ptr = alloc(layout)?.as_ptr() as *mut T;
|
||||
unsafe {
|
||||
core::ptr::write(ptr, t);
|
||||
Ok(Box::from_raw(ptr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TryClone> TryClone for Box<T> {
|
||||
fn try_clone(&self) -> Result<Self, TryReserveError> {
|
||||
Self::try_new(Borrow::<T>::borrow(self).try_clone()?)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn boxed() {
|
||||
let mut v = Box::try_new(5).unwrap();
|
||||
assert_eq!(*v, 5);
|
||||
*v = 3;
|
||||
assert_eq!(*v, 3);
|
||||
}
|
||||
// #[test]
|
||||
// fn big_alloc() {
|
||||
// let layout = Layout::from_size_align(1_000_000_000_000, 8).unwrap();
|
||||
// let ptr = unsafe { alloc::alloc::alloc(layout) };
|
||||
// assert!(ptr.is_null());
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn trybox_zst() {
|
||||
let b = Box::try_new(()).expect("ok");
|
||||
assert_eq!(b, Box::new(()));
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
//! Implement Fallible Btree, As there is no try_reserve methods on btree, I add no choice but to fork the std implementation and change return types.
|
||||
//! Currently this functionality is only available when building this crate with nightly and the `unstable` feature.
|
||||
pub mod map;
|
||||
pub use map::BTreeMap;
|
||||
|
||||
pub mod set;
|
||||
pub use set::BTreeSet;
|
||||
|
||||
mod node;
|
||||
mod search;
|
||||
use crate::TryReserveError;
|
||||
|
||||
#[doc(hidden)]
|
||||
trait Recover<Q: ?Sized> {
|
||||
type Key;
|
||||
|
||||
fn get(&self, key: &Q) -> Option<&Self::Key>;
|
||||
fn take(&mut self, key: &Q) -> Option<Self::Key>;
|
||||
fn replace(&mut self, key: Self::Key) -> Result<Option<Self::Key>, TryReserveError>;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,66 +0,0 @@
|
||||
use core::borrow::Borrow;
|
||||
|
||||
use core::cmp::Ordering;
|
||||
|
||||
use super::node::{marker, ForceResult::*, Handle, NodeRef};
|
||||
|
||||
use SearchResult::*;
|
||||
|
||||
pub enum SearchResult<BorrowType, K, V, FoundType, GoDownType> {
|
||||
Found(Handle<NodeRef<BorrowType, K, V, FoundType>, marker::KV>),
|
||||
GoDown(Handle<NodeRef<BorrowType, K, V, GoDownType>, marker::Edge>),
|
||||
}
|
||||
|
||||
pub fn search_tree<BorrowType, K, V, Q: ?Sized>(
|
||||
mut node: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
|
||||
key: &Q,
|
||||
) -> SearchResult<BorrowType, K, V, marker::LeafOrInternal, marker::Leaf>
|
||||
where
|
||||
Q: Ord,
|
||||
K: Borrow<Q>,
|
||||
{
|
||||
loop {
|
||||
match search_node(node, key) {
|
||||
Found(handle) => return Found(handle),
|
||||
GoDown(handle) => match handle.force() {
|
||||
Leaf(leaf) => return GoDown(leaf),
|
||||
Internal(internal) => {
|
||||
node = internal.descend();
|
||||
continue;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn search_node<BorrowType, K, V, Type, Q: ?Sized>(
|
||||
node: NodeRef<BorrowType, K, V, Type>,
|
||||
key: &Q,
|
||||
) -> SearchResult<BorrowType, K, V, Type, Type>
|
||||
where
|
||||
Q: Ord,
|
||||
K: Borrow<Q>,
|
||||
{
|
||||
match search_linear(&node, key) {
|
||||
(idx, true) => Found(Handle::new_kv(node, idx)),
|
||||
(idx, false) => SearchResult::GoDown(Handle::new_edge(node, idx)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn search_linear<BorrowType, K, V, Type, Q: ?Sized>(
|
||||
node: &NodeRef<BorrowType, K, V, Type>,
|
||||
key: &Q,
|
||||
) -> (usize, bool)
|
||||
where
|
||||
Q: Ord,
|
||||
K: Borrow<Q>,
|
||||
{
|
||||
for (i, k) in node.keys().iter().enumerate() {
|
||||
match key.cmp(k.borrow()) {
|
||||
Ordering::Greater => {}
|
||||
Ordering::Equal => return (i, true),
|
||||
Ordering::Less => return (i, false),
|
||||
}
|
||||
}
|
||||
(node.keys().len(), false)
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,47 +0,0 @@
|
||||
//! A try_format! macro replacing format!
|
||||
use super::FallibleVec;
|
||||
use crate::TryReserveError;
|
||||
use alloc::fmt::{Arguments, Write};
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
/// Take a max capacity a try allocating a string with it.
|
||||
///
|
||||
/// # Warning:
|
||||
///
|
||||
/// the max capacity must be > to the formating of the
|
||||
/// arguments. If writing the argument on the string exceed the
|
||||
/// capacity, no error is return and an allocation can occurs which
|
||||
/// can lead to a panic
|
||||
pub fn try_format(max_capacity: usize, args: Arguments<'_>) -> Result<String, TryReserveError> {
|
||||
let v = Vec::try_with_capacity(max_capacity)?;
|
||||
let mut s = String::from_utf8(v).expect("wtf an empty vec should be valid utf8");
|
||||
s.write_fmt(args)
|
||||
.expect("a formatting trait implementation returned an error");
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
/// Take a max capacity a try allocating a string with it.
|
||||
///
|
||||
/// # Warning:
|
||||
///
|
||||
/// the max capacity must be > to the formating of the
|
||||
/// arguments. If writing the argument on the string exceed the
|
||||
/// capacity, no error is return and an allocation can occurs which
|
||||
/// can lead to a panic
|
||||
macro_rules! tryformat {
|
||||
($max_capacity:tt, $($arg:tt)*) => (
|
||||
$crate::format::try_format($max_capacity, format_args!($($arg)*))
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn format() {
|
||||
assert_eq!(tryformat!(1, "1").unwrap(), format!("1"));
|
||||
assert_eq!(tryformat!(1, "{}", 1).unwrap(), format!("{}", 1));
|
||||
assert_eq!(tryformat!(3, "{}", 123).unwrap(), format!("{}", 123));
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
//! Implement Fallible HashMap
|
||||
use super::TryClone;
|
||||
use crate::TryReserveError;
|
||||
use core::borrow::Borrow;
|
||||
use core::default::Default;
|
||||
use core::hash::Hash;
|
||||
|
||||
type HashMap<K, V> = hashbrown::hash_map::HashMap<K, V>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct TryHashMap<K, V> {
|
||||
inner: HashMap<K, V>,
|
||||
}
|
||||
|
||||
impl<K, V> TryHashMap<K, V>
|
||||
where
|
||||
K: Eq + Hash,
|
||||
{
|
||||
pub fn with_capacity(capacity: usize) -> Result<Self, TryReserveError> {
|
||||
let mut map = Self {
|
||||
inner: HashMap::new(),
|
||||
};
|
||||
map.reserve(capacity)?;
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq,
|
||||
{
|
||||
self.inner.get(k)
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, k: K, v: V) -> Result<Option<V>, TryReserveError> {
|
||||
self.reserve(if self.inner.capacity() == 0 { 4 } else { 1 })?;
|
||||
Ok(self.inner.insert(k, v))
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> hashbrown::hash_map::Iter<'_, K, V> {
|
||||
self.inner.iter()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.inner.len()
|
||||
}
|
||||
|
||||
pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq,
|
||||
{
|
||||
self.inner.remove(k)
|
||||
}
|
||||
|
||||
fn reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
|
||||
self.inner.try_reserve(additional)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> IntoIterator for TryHashMap<K, V> {
|
||||
type Item = (K, V);
|
||||
type IntoIter = hashbrown::hash_map::IntoIter<K, V>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.inner.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> TryClone for TryHashMap<K, V>
|
||||
where
|
||||
K: Eq + Hash + TryClone,
|
||||
V: TryClone,
|
||||
{
|
||||
fn try_clone(&self) -> Result<Self, TryReserveError> {
|
||||
let mut clone = Self::with_capacity(self.inner.len())?;
|
||||
|
||||
for (key, value) in self.inner.iter() {
|
||||
clone.insert(key.try_clone()?, value.try_clone()?)?;
|
||||
}
|
||||
|
||||
Ok(clone)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tryhashmap_oom() {
|
||||
match TryHashMap::<char, char>::default().reserve(core::usize::MAX) {
|
||||
Ok(_) => panic!("it should be OOM"),
|
||||
_ => (),
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
//! impl Fallible collections on allocation errors, quite as describe
|
||||
//! in [RFC 2116](https://github.com/rust-lang/rfcs/blob/master/text/2116-alloc-me-maybe.md)
|
||||
//! This was used in the turbofish OS hobby project to mitigate the
|
||||
//! the lack of faillible allocation in rust.
|
||||
//!
|
||||
//! The `Try*` types in this module are thin wrappers around the stdlib types to add
|
||||
//! support for fallible allocation. The API differences from the stdlib types ensure
|
||||
//! that all operations which allocate return a `Result`. For the most part, this simply
|
||||
//! means adding a `Result` return value to functions which return nothing or a
|
||||
//! non-`Result` value. However, these types implement some traits whose API cannot
|
||||
//! communicate failure, but which do require allocation, so it is important that these
|
||||
//! wrapper types do not implement these traits.
|
||||
//!
|
||||
//! Specifically, these types must not implement any of the following traits:
|
||||
//! - Clone
|
||||
//! - Extend
|
||||
//! - From
|
||||
//! - FromIterator
|
||||
//!
|
||||
//! This list may not be exhaustive. Exercise caution when implementing
|
||||
//! any new traits to ensure they won't potentially allocate in a way that
|
||||
//! can't return a Result to indicate allocation failure.
|
||||
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
#![cfg_attr(feature = "unstable", feature(try_reserve))]
|
||||
#![cfg_attr(feature = "unstable", feature(specialization))]
|
||||
#![cfg_attr(feature = "unstable", feature(allocator_api))]
|
||||
#![cfg_attr(feature = "unstable", feature(dropck_eyepatch))]
|
||||
#![cfg_attr(feature = "unstable", feature(ptr_internals))]
|
||||
#![cfg_attr(feature = "unstable", feature(core_intrinsics))]
|
||||
#![cfg_attr(feature = "unstable", feature(maybe_uninit_ref))]
|
||||
#![cfg_attr(feature = "unstable", feature(maybe_uninit_slice))]
|
||||
#![cfg_attr(feature = "unstable", feature(maybe_uninit_extra))]
|
||||
#![cfg_attr(feature = "unstable", feature(internal_uninit_const))]
|
||||
extern crate alloc;
|
||||
#[cfg(feature = "std_io")]
|
||||
extern crate std;
|
||||
|
||||
pub mod boxed;
|
||||
pub use boxed::*;
|
||||
#[macro_use]
|
||||
pub mod vec;
|
||||
pub use vec::*;
|
||||
pub mod rc;
|
||||
pub use rc::*;
|
||||
pub mod arc;
|
||||
pub use arc::*;
|
||||
#[cfg(feature = "unstable")]
|
||||
pub mod btree;
|
||||
#[cfg(not(feature = "unstable"))]
|
||||
pub mod hashmap;
|
||||
#[cfg(not(feature = "unstable"))]
|
||||
pub use hashmap::*;
|
||||
#[macro_use]
|
||||
pub mod format;
|
||||
pub mod try_clone;
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
pub use alloc::collections::TryReserveError;
|
||||
#[cfg(not(feature = "unstable"))]
|
||||
pub use hashbrown::TryReserveError;
|
||||
|
||||
#[cfg(feature = "std_io")]
|
||||
pub use vec::std_io::*;
|
||||
|
||||
/// trait for trying to clone an elem, return an error instead of
|
||||
/// panic if allocation failed
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use fallible_collections::TryClone;
|
||||
/// let mut vec = vec![42, 100];
|
||||
/// assert_eq!(vec.try_clone().unwrap(), vec)
|
||||
/// ```
|
||||
pub trait TryClone {
|
||||
/// try clone method, (Self must be sized because of Result
|
||||
/// constraint)
|
||||
fn try_clone(&self) -> Result<Self, TryReserveError>
|
||||
where
|
||||
Self: core::marker::Sized;
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
//! Implement a Fallible Rc
|
||||
use super::FallibleBox;
|
||||
use crate::TryReserveError;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::rc::Rc;
|
||||
/// trait to implement Fallible Rc
|
||||
pub trait FallibleRc<T> {
|
||||
/// try creating a new Rc, returning a Result<Box<T>,
|
||||
/// TryReserveError> if allocation failed
|
||||
fn try_new(t: T) -> Result<Self, TryReserveError>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
impl<T> FallibleRc<T> for Rc<T> {
|
||||
fn try_new(t: T) -> Result<Self, TryReserveError> {
|
||||
let b = Box::try_new(t)?;
|
||||
Ok(Rc::from(b))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn fallible_rc() {
|
||||
use std::rc::Rc;
|
||||
|
||||
let mut x = Rc::new(3);
|
||||
*Rc::get_mut(&mut x).unwrap() = 4;
|
||||
assert_eq!(*x, 4);
|
||||
|
||||
let _y = Rc::clone(&x);
|
||||
assert!(Rc::get_mut(&mut x).is_none());
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
//! this module implements try clone for primitive rust types
|
||||
|
||||
use super::TryClone;
|
||||
use crate::TryReserveError;
|
||||
|
||||
macro_rules! impl_try_clone {
|
||||
($($e: ty),*) => {
|
||||
$(impl TryClone for $e {
|
||||
#[inline(always)]
|
||||
fn try_clone(&self) -> Result<Self, TryReserveError>
|
||||
where
|
||||
Self: core::marker::Sized,
|
||||
{
|
||||
Ok(*self)
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
impl_try_clone!(u8, u16, u32, u64, i8, i16, i32, i64, usize, isize, bool);
|
||||
|
||||
impl<T: TryClone> TryClone for Option<T> {
|
||||
fn try_clone(&self) -> Result<Self, TryReserveError> {
|
||||
Ok(match self {
|
||||
Some(t) => Some(t.try_clone()?),
|
||||
None => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
// impl<T: Copy> TryClone for T {
|
||||
// fn try_clone(&self) -> Result<Self, TryReserveError>
|
||||
// where
|
||||
// Self: core::marker::Sized,
|
||||
// {
|
||||
// Ok(*self)
|
||||
// }
|
||||
// }
|
@ -1,872 +0,0 @@
|
||||
//! Implement Fallible Vec
|
||||
use super::TryClone;
|
||||
use crate::TryReserveError;
|
||||
#[allow(unused_imports)]
|
||||
use alloc::alloc::{alloc, realloc, Layout};
|
||||
use alloc::vec::Vec;
|
||||
use core::convert::TryInto as _;
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
#[macro_export]
|
||||
/// macro trying to create a vec, return a
|
||||
/// Result<Vec<T>,TryReserveError>
|
||||
macro_rules! try_vec {
|
||||
($elem:expr; $n:expr) => (
|
||||
$crate::vec::try_from_elem($elem, $n)
|
||||
);
|
||||
($($x:expr),*) => (
|
||||
match <alloc::boxed::Box<_> as $crate::boxed::FallibleBox<_>>::try_new([$($x),*]) {
|
||||
Err(e) => Err(e),
|
||||
Ok(b) => Ok(<[_]>::into_vec(b)),
|
||||
}
|
||||
);
|
||||
($($x:expr,)*) => ($crate::try_vec![$($x),*])
|
||||
}
|
||||
|
||||
/// trait implementing all fallible methods on vec
|
||||
pub trait FallibleVec<T> {
|
||||
/// see reserve
|
||||
fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>;
|
||||
/// see push
|
||||
fn try_push(&mut self, elem: T) -> Result<(), TryReserveError>;
|
||||
/// try push and give back ownership in case of error
|
||||
fn try_push_give_back(&mut self, elem: T) -> Result<(), (T, TryReserveError)>;
|
||||
/// see with capacity, (Self must be sized by the constraint of Result)
|
||||
fn try_with_capacity(capacity: usize) -> Result<Self, TryReserveError>
|
||||
where
|
||||
Self: core::marker::Sized;
|
||||
/// see insert
|
||||
fn try_insert(&mut self, index: usize, element: T) -> Result<(), (T, TryReserveError)>;
|
||||
/// see append
|
||||
fn try_append(&mut self, other: &mut Self) -> Result<(), TryReserveError>;
|
||||
/// see resize, only works when the `value` implements Copy, otherwise, look at try_resize_no_copy
|
||||
fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
|
||||
where
|
||||
T: Copy + Clone;
|
||||
fn try_resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), TryReserveError>
|
||||
where
|
||||
F: FnMut() -> T;
|
||||
/// resize the vec by trying to clone the value repeatingly
|
||||
fn try_resize_no_copy(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
|
||||
where
|
||||
T: TryClone;
|
||||
/// see resize, only works when the `value` implements Copy, otherwise, look at try_extend_from_slice_no_copy
|
||||
fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveError>
|
||||
where
|
||||
T: Copy + Clone;
|
||||
/// extend the vec by trying to clone the value in `other`
|
||||
fn try_extend_from_slice_no_copy(&mut self, other: &[T]) -> Result<(), TryReserveError>
|
||||
where
|
||||
T: TryClone;
|
||||
}
|
||||
|
||||
/// TryVec is a thin wrapper around alloc::vec::Vec to provide support for
|
||||
/// fallible allocation.
|
||||
///
|
||||
/// See the crate documentation for more.
|
||||
#[derive(PartialEq)]
|
||||
pub struct TryVec<T> {
|
||||
inner: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T> Default for TryVec<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
inner: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: core::fmt::Debug> core::fmt::Debug for TryVec<T> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{:?}", self.inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> TryVec<T> {
|
||||
pub fn new() -> Self {
|
||||
Self { inner: Vec::new() }
|
||||
}
|
||||
|
||||
pub fn with_capacity(capacity: usize) -> Result<Self, TryReserveError> {
|
||||
Ok(Self {
|
||||
inner: FallibleVec::try_with_capacity(capacity)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn append(&mut self, other: &mut Self) -> Result<(), TryReserveError> {
|
||||
FallibleVec::try_append(&mut self.inner, &mut other.inner)
|
||||
}
|
||||
|
||||
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[T] {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.inner.clear()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn into_inner(self) -> Vec<T> {
|
||||
self.inner
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.inner.is_empty()
|
||||
}
|
||||
|
||||
pub fn iter_mut(&mut self) -> IterMut<T> {
|
||||
IterMut {
|
||||
inner: self.inner.iter_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> Iter<T> {
|
||||
Iter {
|
||||
inner: self.inner.iter(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
self.inner.pop()
|
||||
}
|
||||
|
||||
pub fn push(&mut self, value: T) -> Result<(), TryReserveError> {
|
||||
FallibleVec::try_push(&mut self.inner, value)
|
||||
}
|
||||
|
||||
pub fn reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
|
||||
FallibleVec::try_reserve(&mut self.inner, additional)
|
||||
}
|
||||
|
||||
pub fn resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), TryReserveError>
|
||||
where
|
||||
F: FnMut() -> T,
|
||||
{
|
||||
FallibleVec::try_resize_with(&mut self.inner, new_len, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TryClone> TryClone for TryVec<T> {
|
||||
fn try_clone(&self) -> Result<Self, TryReserveError> {
|
||||
self.as_slice().try_into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TryClone> TryVec<TryVec<T>> {
|
||||
pub fn concat(&self) -> Result<TryVec<T>, TryReserveError> {
|
||||
let size = self.iter().map(|v| v.inner.len()).sum();
|
||||
let mut result = TryVec::with_capacity(size)?;
|
||||
for v in self.iter() {
|
||||
result.inner.try_extend_from_slice_no_copy(&v.inner)?;
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TryClone> TryVec<T> {
|
||||
pub fn extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveError> {
|
||||
self.inner.try_extend_from_slice_no_copy(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoIterator for TryVec<T> {
|
||||
type Item = T;
|
||||
type IntoIter = alloc::vec::IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.inner.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoIterator for &'a TryVec<T> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = alloc::slice::Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.inner.iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std_io")]
|
||||
pub mod std_io {
|
||||
use super::*;
|
||||
use std::io::{self, Read, Take, Write};
|
||||
|
||||
pub trait TryRead {
|
||||
fn try_read_to_end(&mut self, buf: &mut TryVec<u8>) -> io::Result<usize>;
|
||||
|
||||
fn read_into_try_vec(&mut self) -> io::Result<TryVec<u8>> {
|
||||
let mut buf = TryVec::new();
|
||||
self.try_read_to_end(&mut buf)?;
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Read> TryRead for Take<T> {
|
||||
/// This function reserves the upper limit of what `src` can generate before
|
||||
/// reading all bytes until EOF in this source, placing them into `buf`. If the
|
||||
/// allocation is unsuccessful, or reading from the source generates an error
|
||||
/// before reaching EOF, this will return an error. Otherwise, it will return
|
||||
/// the number of bytes read.
|
||||
///
|
||||
/// Since `Take::limit()` may return a value greater than the number of bytes
|
||||
/// which can be read from the source, it's possible this function may fail
|
||||
/// in the allocation phase even though allocating the number of bytes available
|
||||
/// to read would have succeeded. In general, it is assumed that the callers
|
||||
/// have accurate knowledge of the number of bytes of interest and have created
|
||||
/// `src` accordingly.
|
||||
fn try_read_to_end(&mut self, buf: &mut TryVec<u8>) -> io::Result<usize> {
|
||||
try_read_up_to(self, self.limit(), buf)
|
||||
}
|
||||
}
|
||||
|
||||
/// Read up to `limit` bytes from `src`, placing them into `buf` and returning the
|
||||
/// number of bytes read. Space for `limit` additional bytes is reserved in `buf`, so
|
||||
/// this function will return an error if the allocation fails.
|
||||
pub fn try_read_up_to<R: Read>(
|
||||
src: &mut R,
|
||||
limit: u64,
|
||||
buf: &mut TryVec<u8>,
|
||||
) -> io::Result<usize> {
|
||||
let additional = limit
|
||||
.try_into()
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
|
||||
buf.reserve(additional)
|
||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "reserve allocation failed"))?;
|
||||
let bytes_read = src.take(limit).read_to_end(&mut buf.inner)?;
|
||||
Ok(bytes_read)
|
||||
}
|
||||
|
||||
impl Write for TryVec<u8> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.extend_from_slice(buf)
|
||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "extend_from_slice failed"))?;
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn try_read_to_end() {
|
||||
let mut src = b"1234567890".take(5);
|
||||
let mut buf = TryVec::new();
|
||||
src.try_read_to_end(&mut buf).unwrap();
|
||||
assert_eq!(buf.len(), 5);
|
||||
assert_eq!(buf, b"12345".as_ref());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_into_try_vec() {
|
||||
let mut src = b"1234567890".take(5);
|
||||
let buf = src.read_into_try_vec().unwrap();
|
||||
assert_eq!(buf.len(), 5);
|
||||
assert_eq!(buf, b"12345".as_ref());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_into_try_vec_oom() {
|
||||
let mut src = b"1234567890".take(core::usize::MAX.try_into().expect("usize < u64"));
|
||||
assert!(src.read_into_try_vec().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_read_up_to() {
|
||||
let src = b"1234567890";
|
||||
let mut buf = TryVec::new();
|
||||
super::try_read_up_to(&mut src.as_ref(), 5, &mut buf).unwrap();
|
||||
assert_eq!(buf.len(), 5);
|
||||
assert_eq!(buf, b"12345".as_ref());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_read_up_to_oom() {
|
||||
let src = b"1234567890";
|
||||
let mut buf = TryVec::new();
|
||||
let limit = core::usize::MAX.try_into().expect("usize < u64");
|
||||
let res = super::try_read_up_to(&mut src.as_ref(), limit, &mut buf);
|
||||
assert!(res.is_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PartialEq> PartialEq<Vec<T>> for TryVec<T> {
|
||||
fn eq(&self, other: &Vec<T>) -> bool {
|
||||
self.inner.eq(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: PartialEq> PartialEq<&'a [T]> for TryVec<T> {
|
||||
fn eq(&self, other: &&[T]) -> bool {
|
||||
self.inner.eq(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<&str> for TryVec<u8> {
|
||||
fn eq(&self, other: &&str) -> bool {
|
||||
self.as_slice() == other.as_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl core::convert::AsRef<[u8]> for TryVec<u8> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.inner.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> core::convert::From<Vec<T>> for TryVec<T> {
|
||||
fn from(value: Vec<T>) -> Self {
|
||||
Self { inner: value }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TryClone> core::convert::TryFrom<&[T]> for TryVec<T> {
|
||||
type Error = TryReserveError;
|
||||
|
||||
fn try_from(value: &[T]) -> Result<Self, Self::Error> {
|
||||
let mut v = Self::new();
|
||||
v.inner.try_extend_from_slice_no_copy(value)?;
|
||||
Ok(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl core::convert::TryFrom<&str> for TryVec<u8> {
|
||||
type Error = TryReserveError;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let mut v = Self::new();
|
||||
v.extend_from_slice(value.as_bytes())?;
|
||||
Ok(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> core::ops::Deref for TryVec<T> {
|
||||
type Target = [T];
|
||||
|
||||
fn deref(&self) -> &[T] {
|
||||
self.inner.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> core::ops::DerefMut for TryVec<T> {
|
||||
fn deref_mut(&mut self) -> &mut [T] {
|
||||
self.inner.deref_mut()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Iter<'a, T> {
|
||||
inner: alloc::slice::Iter<'a, T>,
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for Iter<'a, T> {
|
||||
type Item = &'a T;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.inner.next()
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.inner.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IterMut<'a, T> {
|
||||
inner: alloc::slice::IterMut<'a, T>,
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for IterMut<'a, T> {
|
||||
type Item = &'a mut T;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.inner.next()
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.inner.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unstable"))]
|
||||
fn vec_try_reserve<T>(v: &mut Vec<T>, additional: usize) -> Result<(), TryReserveError> {
|
||||
let available = v.capacity().checked_sub(v.len()).expect("capacity >= len");
|
||||
if additional > available {
|
||||
let increase = additional
|
||||
.checked_sub(available)
|
||||
.expect("additional > available");
|
||||
let new_cap = v
|
||||
.capacity()
|
||||
.checked_add(increase)
|
||||
.ok_or(TryReserveError::CapacityOverflow)?;
|
||||
vec_try_extend(v, new_cap)?;
|
||||
debug_assert!(v.capacity() == new_cap);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unstable"))]
|
||||
fn vec_try_extend<T>(v: &mut Vec<T>, new_cap: usize) -> Result<(), TryReserveError> {
|
||||
let old_len = v.len();
|
||||
let old_cap: usize = v.capacity();
|
||||
|
||||
if old_cap >= new_cap {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let elem_size = core::mem::size_of::<T>();
|
||||
let new_alloc_size = new_cap
|
||||
.checked_mul(elem_size)
|
||||
.ok_or(TryReserveError::CapacityOverflow)?;
|
||||
|
||||
// required for alloc safety
|
||||
// See https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html#safety-1
|
||||
// Should be unreachable given prior `old_cap >= new_cap` check.
|
||||
assert!(new_alloc_size > 0);
|
||||
|
||||
let align = core::mem::align_of::<T>();
|
||||
|
||||
let (new_ptr, layout) = {
|
||||
if old_cap == 0 {
|
||||
let layout = Layout::from_size_align(new_alloc_size, align).expect("Invalid layout");
|
||||
let new_ptr = unsafe { alloc(layout) };
|
||||
(new_ptr, layout)
|
||||
} else {
|
||||
let old_alloc_size = old_cap
|
||||
.checked_mul(elem_size)
|
||||
.ok_or(TryReserveError::CapacityOverflow)?;
|
||||
let layout = Layout::from_size_align(old_alloc_size, align).expect("Invalid layout");
|
||||
let new_ptr = unsafe { realloc(v.as_mut_ptr() as *mut u8, layout, new_alloc_size) };
|
||||
(new_ptr, layout)
|
||||
}
|
||||
};
|
||||
|
||||
if new_ptr.is_null() {
|
||||
return Err(TryReserveError::AllocError { layout });
|
||||
}
|
||||
|
||||
let new_vec = unsafe { Vec::from_raw_parts(new_ptr.cast(), old_len, new_cap) };
|
||||
|
||||
core::mem::forget(core::mem::replace(v, new_vec));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl<T> FallibleVec<T> for Vec<T> {
|
||||
fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
|
||||
#[cfg(feature = "unstable")]
|
||||
{
|
||||
self.try_reserve(additional)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unstable"))]
|
||||
{
|
||||
vec_try_reserve(self, additional)
|
||||
}
|
||||
}
|
||||
fn try_push(&mut self, elem: T) -> Result<(), TryReserveError> {
|
||||
FallibleVec::try_reserve(self, 1)?;
|
||||
Ok(self.push(elem))
|
||||
}
|
||||
fn try_push_give_back(&mut self, elem: T) -> Result<(), (T, TryReserveError)> {
|
||||
if let Err(e) = FallibleVec::try_reserve(self, 1) {
|
||||
return Err((elem, e));
|
||||
}
|
||||
Ok(self.push(elem))
|
||||
}
|
||||
fn try_with_capacity(capacity: usize) -> Result<Self, TryReserveError>
|
||||
where
|
||||
Self: core::marker::Sized,
|
||||
{
|
||||
let mut n = Self::new();
|
||||
FallibleVec::try_reserve(&mut n, capacity)?;
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
fn try_insert(&mut self, index: usize, element: T) -> Result<(), (T, TryReserveError)> {
|
||||
if let Err(e) = FallibleVec::try_reserve(self, 1) {
|
||||
return Err((element, e));
|
||||
}
|
||||
Ok(self.insert(index, element))
|
||||
}
|
||||
fn try_append(&mut self, other: &mut Self) -> Result<(), TryReserveError> {
|
||||
FallibleVec::try_reserve(self, other.len())?;
|
||||
Ok(self.append(other))
|
||||
}
|
||||
fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
|
||||
where
|
||||
T: Copy + Clone,
|
||||
{
|
||||
let len = self.len();
|
||||
if new_len > len {
|
||||
FallibleVec::try_reserve(self, new_len - len)?;
|
||||
}
|
||||
Ok(self.resize(new_len, value))
|
||||
}
|
||||
fn try_resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), TryReserveError>
|
||||
where
|
||||
F: FnMut() -> T,
|
||||
{
|
||||
let len = self.len();
|
||||
if new_len > len {
|
||||
FallibleVec::try_reserve(self, new_len - len)?;
|
||||
}
|
||||
Ok(self.resize_with(new_len, f))
|
||||
}
|
||||
fn try_resize_no_copy(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
|
||||
where
|
||||
T: TryClone,
|
||||
{
|
||||
let len = self.len();
|
||||
|
||||
if new_len > len {
|
||||
self.try_extend_with(new_len - len, TryExtendElement(value))
|
||||
} else {
|
||||
Ok(self.truncate(new_len))
|
||||
}
|
||||
}
|
||||
fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveError>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
FallibleVec::try_reserve(self, other.len())?;
|
||||
Ok(self.extend_from_slice(other))
|
||||
}
|
||||
fn try_extend_from_slice_no_copy(&mut self, other: &[T]) -> Result<(), TryReserveError>
|
||||
where
|
||||
T: TryClone,
|
||||
{
|
||||
let mut len = self.len();
|
||||
FallibleVec::try_reserve(self, other.len())?;
|
||||
let mut iterator = other.iter();
|
||||
while let Some(element) = iterator.next() {
|
||||
unsafe {
|
||||
core::ptr::write(self.get_unchecked_mut(len), element.try_clone()?);
|
||||
// NB can't overflow since we would have had to alloc the address space
|
||||
len += 1;
|
||||
self.set_len(len);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
trait ExtendWith<T> {
|
||||
fn next(&mut self) -> Result<T, TryReserveError>;
|
||||
fn last(self) -> T;
|
||||
}
|
||||
|
||||
struct TryExtendElement<T: TryClone>(T);
|
||||
impl<T: TryClone> ExtendWith<T> for TryExtendElement<T> {
|
||||
fn next(&mut self) -> Result<T, TryReserveError> {
|
||||
self.0.try_clone()
|
||||
}
|
||||
fn last(self) -> T {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
trait TryExtend<T> {
|
||||
fn try_extend_with<E: ExtendWith<T>>(
|
||||
&mut self,
|
||||
n: usize,
|
||||
value: E,
|
||||
) -> Result<(), TryReserveError>;
|
||||
}
|
||||
|
||||
impl<T> TryExtend<T> for Vec<T> {
|
||||
/// Extend the vector by `n` values, using the given generator.
|
||||
fn try_extend_with<E: ExtendWith<T>>(
|
||||
&mut self,
|
||||
n: usize,
|
||||
mut value: E,
|
||||
) -> Result<(), TryReserveError> {
|
||||
FallibleVec::try_reserve(self, n)?;
|
||||
|
||||
unsafe {
|
||||
let mut ptr = self.as_mut_ptr().add(self.len());
|
||||
|
||||
let mut local_len = self.len();
|
||||
// Write all elements except the last one
|
||||
for _ in 1..n {
|
||||
core::ptr::write(ptr, value.next()?);
|
||||
ptr = ptr.offset(1);
|
||||
// Increment the length in every step in case next() panics
|
||||
local_len += 1;
|
||||
self.set_len(local_len);
|
||||
}
|
||||
|
||||
if n > 0 {
|
||||
// We can write the last element directly without cloning needlessly
|
||||
core::ptr::write(ptr, value.last());
|
||||
local_len += 1;
|
||||
self.set_len(local_len);
|
||||
}
|
||||
|
||||
// len set by scope guard
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
trait Truncate {
|
||||
fn truncate(&mut self, len: usize);
|
||||
}
|
||||
|
||||
impl<T> Truncate for Vec<T> {
|
||||
fn truncate(&mut self, len: usize) {
|
||||
let current_len = self.len();
|
||||
unsafe {
|
||||
let mut ptr = self.as_mut_ptr().add(current_len);
|
||||
// Set the final length at the end, keeping in mind that
|
||||
// dropping an element might panic. Works around a missed
|
||||
// optimization, as seen in the following issue:
|
||||
// https://github.com/rust-lang/rust/issues/51802
|
||||
let mut local_len = self.len();
|
||||
|
||||
// drop any extra elements
|
||||
for _ in len..current_len {
|
||||
ptr = ptr.offset(-1);
|
||||
core::ptr::drop_in_place(ptr);
|
||||
local_len -= 1;
|
||||
self.set_len(local_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// try creating a vec from an `elem` cloned `n` times, see std::from_elem
|
||||
#[cfg(feature = "unstable")]
|
||||
pub fn try_from_elem<T: TryClone>(elem: T, n: usize) -> Result<Vec<T>, TryReserveError> {
|
||||
<T as SpecFromElem>::try_from_elem(elem, n)
|
||||
}
|
||||
|
||||
// Specialization trait used for Vec::from_elem
|
||||
#[cfg(feature = "unstable")]
|
||||
trait SpecFromElem: Sized {
|
||||
fn try_from_elem(elem: Self, n: usize) -> Result<Vec<Self>, TryReserveError>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
impl<T: TryClone> SpecFromElem for T {
|
||||
default fn try_from_elem(elem: Self, n: usize) -> Result<Vec<T>, TryReserveError> {
|
||||
let mut v = Vec::new();
|
||||
v.try_resize_no_copy(n, elem)?;
|
||||
Ok(v)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
impl SpecFromElem for u8 {
|
||||
#[inline]
|
||||
fn try_from_elem(elem: u8, n: usize) -> Result<Vec<u8>, TryReserveError> {
|
||||
unsafe {
|
||||
let mut v = Vec::try_with_capacity(n)?;
|
||||
core::ptr::write_bytes(v.as_mut_ptr(), elem, n);
|
||||
v.set_len(n);
|
||||
Ok(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TryClone> TryClone for Vec<T> {
|
||||
fn try_clone(&self) -> Result<Self, TryReserveError>
|
||||
where
|
||||
Self: core::marker::Sized,
|
||||
{
|
||||
let mut v = Vec::new();
|
||||
v.try_extend_from_slice_no_copy(self)?;
|
||||
Ok(v)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TryFromIterator<I>: Sized {
|
||||
fn try_from_iterator<T: IntoIterator<Item = I>>(iterator: T) -> Result<Self, TryReserveError>;
|
||||
}
|
||||
|
||||
impl<I> TryFromIterator<I> for Vec<I> {
|
||||
fn try_from_iterator<T: IntoIterator<Item = I>>(iterator: T) -> Result<Self, TryReserveError>
|
||||
where
|
||||
T: IntoIterator<Item = I>,
|
||||
{
|
||||
let mut new = Self::new();
|
||||
for i in iterator {
|
||||
new.try_push(i)?;
|
||||
}
|
||||
Ok(new)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TryCollect<I> {
|
||||
fn try_collect<C: TryFromIterator<I>>(self) -> Result<C, TryReserveError>;
|
||||
}
|
||||
|
||||
impl<I, T> TryCollect<I> for T
|
||||
where
|
||||
T: IntoIterator<Item = I>,
|
||||
{
|
||||
fn try_collect<C: TryFromIterator<I>>(self) -> Result<C, TryReserveError> {
|
||||
C::try_from_iterator(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "unstable")]
|
||||
fn vec() {
|
||||
// let v: Vec<u8> = from_elem(1, 10);
|
||||
let v: Vec<Vec<u8>> = try_vec![try_vec![42; 10].unwrap(); 100].unwrap();
|
||||
println!("{:?}", v);
|
||||
let v2 = try_vec![0, 1, 2];
|
||||
println!("{:?}", v2);
|
||||
assert_eq!(2 + 2, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_clone_vec() {
|
||||
// let v: Vec<u8> = from_elem(1, 10);
|
||||
let v = vec![42; 100];
|
||||
assert_eq!(v.try_clone().unwrap(), v);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_clone_oom() {
|
||||
let layout = Layout::new::<u8>();
|
||||
let v =
|
||||
unsafe { Vec::<u8>::from_raw_parts(alloc(layout), core::usize::MAX, core::usize::MAX) };
|
||||
assert!(v.try_clone().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tryvec_try_clone_oom() {
|
||||
let layout = Layout::new::<u8>();
|
||||
let inner =
|
||||
unsafe { Vec::<u8>::from_raw_parts(alloc(layout), core::usize::MAX, core::usize::MAX) };
|
||||
let tv = TryVec { inner };
|
||||
assert!(tv.try_clone().is_err());
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn try_out_of_mem() {
|
||||
// let v = try_vec![42_u8; 1000000000];
|
||||
// assert_eq!(v.try_clone().unwrap(), v);
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn oom() {
|
||||
let mut vec: Vec<char> = Vec::new();
|
||||
match FallibleVec::try_reserve(&mut vec, core::usize::MAX) {
|
||||
Ok(_) => panic!("it should be OOM"),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tryvec_oom() {
|
||||
let mut vec: TryVec<char> = TryVec::new();
|
||||
match vec.reserve(core::usize::MAX) {
|
||||
Ok(_) => panic!("it should be OOM"),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_reserve() {
|
||||
let mut vec: Vec<_> = vec![1];
|
||||
let additional_room = vec.capacity() - vec.len();
|
||||
let additional = additional_room + 1;
|
||||
let old_cap = vec.capacity();
|
||||
FallibleVec::try_reserve(&mut vec, additional).unwrap();
|
||||
assert!(vec.capacity() > old_cap);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tryvec_reserve() {
|
||||
let mut vec: TryVec<_> = vec![1].into();
|
||||
let old_cap = vec.inner.capacity();
|
||||
let new_cap = old_cap + 1;
|
||||
vec.reserve(new_cap).unwrap();
|
||||
assert!(vec.inner.capacity() >= new_cap);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_reserve_idempotent() {
|
||||
let mut vec: Vec<_> = vec![1];
|
||||
let additional_room = vec.capacity() - vec.len();
|
||||
let additional = additional_room + 1;
|
||||
FallibleVec::try_reserve(&mut vec, additional).unwrap();
|
||||
let cap_after_reserve = vec.capacity();
|
||||
FallibleVec::try_reserve(&mut vec, additional).unwrap();
|
||||
assert_eq!(vec.capacity(), cap_after_reserve);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tryvec_reserve_idempotent() {
|
||||
let mut vec: TryVec<_> = vec![1].into();
|
||||
let old_cap = vec.inner.capacity();
|
||||
let new_cap = old_cap + 1;
|
||||
vec.reserve(new_cap).unwrap();
|
||||
let cap_after_reserve = vec.inner.capacity();
|
||||
vec.reserve(new_cap).unwrap();
|
||||
assert_eq!(cap_after_reserve, vec.inner.capacity());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn capacity_overflow() {
|
||||
let mut vec: Vec<_> = vec![1];
|
||||
match FallibleVec::try_reserve(&mut vec, core::usize::MAX) {
|
||||
Ok(_) => panic!("capacity calculation should overflow"),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tryvec_capacity_overflow() {
|
||||
let mut vec: TryVec<_> = vec![1].into();
|
||||
match vec.reserve(core::usize::MAX) {
|
||||
Ok(_) => panic!("capacity calculation should overflow"),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extend_from_slice() {
|
||||
let mut vec: Vec<u8> = b"foo".as_ref().into();
|
||||
vec.try_extend_from_slice(b"bar").unwrap();
|
||||
assert_eq!(vec, b"foobar".as_ref());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tryvec_extend_from_slice() {
|
||||
let mut vec: TryVec<u8> = b"foo".as_ref().try_into().unwrap();
|
||||
vec.extend_from_slice(b"bar").unwrap();
|
||||
assert_eq!(vec, b"foobar".as_ref());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(feature = "unstable"))]
|
||||
fn try_extend_zst() {
|
||||
let mut vec: Vec<()> = Vec::new();
|
||||
assert_eq!(vec.capacity(), core::usize::MAX);
|
||||
assert!(vec_try_extend(&mut vec, 10).is_ok());
|
||||
assert!(vec_try_extend(&mut vec, core::usize::MAX).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_reserve_zst() {
|
||||
let mut vec: Vec<()> = Vec::new();
|
||||
assert!(FallibleVec::try_reserve(&mut vec, core::usize::MAX).is_ok());
|
||||
}
|
||||
}
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"abe8ca505e29eb49da413f25592a84f9cccee298dcb45b3392d1d4e7c633e3f3","benches/avif_benchmark.rs":"cd99c0dde025ab40d2cd860f53dc697a1587a48c164c3e5c8adfd40add29d772","src/boxes.rs":"2bae06b89cd6f4a8bf6d58fc055b9900c9fe89697a5776c19a2e587b6b20b803","src/lib.rs":"e766d1bfe960aafecae80bf20dd1c8a5323bc9e9cb0ce77726b71e4cf9b93529","src/macros.rs":"76c840f9299797527fe71aa5b378ffb01312767372b45cc62deddb19775400ae","src/tests.rs":"babce5800634d2db0400dedba324431aba45cda558aa09feec79e50a288dd4c0","src/unstable.rs":"5a0edd7f803fdc355a46bc8142f29aca976d5bbb24cc5d94a3d7c61d0cf4634a","tests/1x1-black-alpha-50pct-premultiplied.avif":"31a8c235bf2cf601a593a7bc33f7f2779f2d5b2e0cd145897b931fce94b0c0b8","tests/amr_nb_1f.3gp":"d1423e3414ad06b69f8b58d5c916ec353ba2d0402d99dec9f1c88acc33b6a127","tests/amr_wb_1f.3gp":"be635b24097e8757b0c04d70ab28e00417ca113e86108b6c269b79b64b89bcd5","tests/bbb_sunflower_QCIF_30fps_h263_noaudio_1f.3gp":"03e5b1264d0a188d77b9e676ba3ce23a801b17aaa11c0343dfd851d6ea4e3a40","tests/clap-basic-1_3x3-to-1x1.avif":"83af9c8196fa93b2475163585a23d0eb5a8f8015d0db8da7a5d6de61adfb1876","tests/corrupt/av1C-missing-essential.avif":"a1501254c4071847b2269fe40b81409c389ff14e91cf7c0005a47e6ea97a6803","tests/corrupt/bad-ipma-flags.avif":"ecde7997b97db1910b9dcc7ca8e3c8957da0e83681ea9008c66dc9f12b78ad19","tests/corrupt/bad-ipma-version.avif":"7f9a1a0b4ebbf8d800d22eaae5ff78970cc6b811317db6c1467c6883952b7c9b","tests/corrupt/bug-1655846.avif":"e0a5a06225800fadf05f5352503a4cec11af73eef705c43b4acab5f4a99dea50","tests/corrupt/bug-1661347.avif":"31c26561e1d9eafb60f7c5968b82a0859d203d73f17f26b29276256acee12966","tests/corrupt/hdlr-not-first.avif":"2c29308af077209b9c984921b7e36f8fb7ca7cf379cf8eba4c7a91f65bc7a304","tests/corrupt/hdlr-not-pict.avif":"9fe37619606645a95725300a9e34fada9190d1e0b3919881db84353941ca9291","tests/corrupt/imir-before-clap.avif":"22d6b5dacf0ef0be59053beba7564b08037fed859ada2885e3476e0ff0d19c95","tests/corrupt/imir-missing-essential.avif":"b1226e4b1358528befbd3f1126b5caf0c5051b4354777b87e71f6001f3829f87","tests/corrupt/ipma-duplicate-item_id.avif":"ca8c5275b0b8b79c1068489a52d0a5c8f0b4453463971e72b694189f11c10745","tests/corrupt/ipma-duplicate-version-and-flags.avif":"cf8e15ec4b210235f3d68332a1adeb64e35c41b8d8e1e7586ae38b6d9cd8926c","tests/corrupt/ipma-invalid-property-index.avif":"2480e773fa716d22883032d05fd4cf2c6b00fba8796cf4ff286a5d1ba26adff6","tests/corrupt/irot-missing-essential.avif":"b7da1fc1d1b45bb1b7ca3494476e052f711d794a6d010df6870872ed8b9da10e","tests/corrupt/no-alpha-av1C.avif":"ad3d34d6331db7d9bea0c5f37efb88923520e33e08e7c636a5df435a4575eae7","tests/corrupt/no-av1C.avif":"eeb4fc50930c91465999f787c4a2a3b12de20556da0857be72da5a1a9eaa3f01","tests/corrupt/no-hdlr.avif":"91a1eb70c7b6adf2104e471d7deeeb98084a591d64ce09ba106c27edfbc3a409","tests/corrupt/no-ispe.avif":"4b6edfd8c9b40c25dc40305a6057e32b5e65f40da4a9d810c58dbff53254113f","tests/corrupt/no-mif1.avif":"1442aa6ffaeb9512724287768bfd1850d3aa29a651ef05abb33e5dec2b3ee5c2","tests/corrupt/no-pixi-for-alpha.avif":"f8adc3573c79ee25bf6d4dd2693c61661469b28f86a5c7b1d9e41b0e8d2d53bb","tests/corrupt/no-pixi.avif":"4b1776def440dc8b913c170e4479772ee6bbb299b8679f7c564704bd03c9597e","tests/multiple-extents.avif":"b5549ac68793e155a726d754e565cea0da03fa17833d3545f45c79e13f4c9360","tests/overflow.rs":"16b591d8def1a155b3b997622f6ea255536870d99c3d8f97c51755b77a50de3c","tests/public.rs":"f45fd8e3f32da53862bc59531ae30390ba97c511885b2117fa949e73618f6fbe","tests/valid-alpha.avif":"9d417a35b9b62ad3ff66ffbc55f16552aacf821a092aa5ef4adff7e746bd4c2f","tests/valid.avif":"f0b33e09bf01232e0877df325f47986c0bee7764f2a81c9c908ae109e7dc63c4"},"package":null}
|
||||
{"files":{"Cargo.toml":"21a2ada4f794296fd07b2b6f4ff781a7ac256d0d6c0b707621a4c84d142b2cf7","benches/avif_benchmark.rs":"cd99c0dde025ab40d2cd860f53dc697a1587a48c164c3e5c8adfd40add29d772","src/boxes.rs":"2bae06b89cd6f4a8bf6d58fc055b9900c9fe89697a5776c19a2e587b6b20b803","src/lib.rs":"ea3d90a541bd01cbb9f8e25599e77600f2ab011535b23334a433e5bd0d8ac7df","src/macros.rs":"76c840f9299797527fe71aa5b378ffb01312767372b45cc62deddb19775400ae","src/tests.rs":"0662320d5600a51370d3df7b8848814f4e779f10f8ad37edffe9541565dc67be","src/unstable.rs":"5a0edd7f803fdc355a46bc8142f29aca976d5bbb24cc5d94a3d7c61d0cf4634a","tests/1x1-black-alpha-50pct-premultiplied.avif":"31a8c235bf2cf601a593a7bc33f7f2779f2d5b2e0cd145897b931fce94b0c0b8","tests/amr_nb_1f.3gp":"d1423e3414ad06b69f8b58d5c916ec353ba2d0402d99dec9f1c88acc33b6a127","tests/amr_wb_1f.3gp":"be635b24097e8757b0c04d70ab28e00417ca113e86108b6c269b79b64b89bcd5","tests/bbb_sunflower_QCIF_30fps_h263_noaudio_1f.3gp":"03e5b1264d0a188d77b9e676ba3ce23a801b17aaa11c0343dfd851d6ea4e3a40","tests/clap-basic-1_3x3-to-1x1.avif":"83af9c8196fa93b2475163585a23d0eb5a8f8015d0db8da7a5d6de61adfb1876","tests/corrupt/av1C-missing-essential.avif":"a1501254c4071847b2269fe40b81409c389ff14e91cf7c0005a47e6ea97a6803","tests/corrupt/bad-ipma-flags.avif":"ecde7997b97db1910b9dcc7ca8e3c8957da0e83681ea9008c66dc9f12b78ad19","tests/corrupt/bad-ipma-version.avif":"7f9a1a0b4ebbf8d800d22eaae5ff78970cc6b811317db6c1467c6883952b7c9b","tests/corrupt/bug-1655846.avif":"e0a5a06225800fadf05f5352503a4cec11af73eef705c43b4acab5f4a99dea50","tests/corrupt/bug-1661347.avif":"31c26561e1d9eafb60f7c5968b82a0859d203d73f17f26b29276256acee12966","tests/corrupt/hdlr-not-first.avif":"2c29308af077209b9c984921b7e36f8fb7ca7cf379cf8eba4c7a91f65bc7a304","tests/corrupt/hdlr-not-pict.avif":"9fe37619606645a95725300a9e34fada9190d1e0b3919881db84353941ca9291","tests/corrupt/imir-before-clap.avif":"22d6b5dacf0ef0be59053beba7564b08037fed859ada2885e3476e0ff0d19c95","tests/corrupt/imir-missing-essential.avif":"b1226e4b1358528befbd3f1126b5caf0c5051b4354777b87e71f6001f3829f87","tests/corrupt/ipma-duplicate-item_id.avif":"ca8c5275b0b8b79c1068489a52d0a5c8f0b4453463971e72b694189f11c10745","tests/corrupt/ipma-duplicate-version-and-flags.avif":"cf8e15ec4b210235f3d68332a1adeb64e35c41b8d8e1e7586ae38b6d9cd8926c","tests/corrupt/ipma-invalid-property-index.avif":"2480e773fa716d22883032d05fd4cf2c6b00fba8796cf4ff286a5d1ba26adff6","tests/corrupt/irot-missing-essential.avif":"b7da1fc1d1b45bb1b7ca3494476e052f711d794a6d010df6870872ed8b9da10e","tests/corrupt/no-alpha-av1C.avif":"ad3d34d6331db7d9bea0c5f37efb88923520e33e08e7c636a5df435a4575eae7","tests/corrupt/no-av1C.avif":"eeb4fc50930c91465999f787c4a2a3b12de20556da0857be72da5a1a9eaa3f01","tests/corrupt/no-hdlr.avif":"91a1eb70c7b6adf2104e471d7deeeb98084a591d64ce09ba106c27edfbc3a409","tests/corrupt/no-ispe.avif":"4b6edfd8c9b40c25dc40305a6057e32b5e65f40da4a9d810c58dbff53254113f","tests/corrupt/no-mif1.avif":"1442aa6ffaeb9512724287768bfd1850d3aa29a651ef05abb33e5dec2b3ee5c2","tests/corrupt/no-pixi-for-alpha.avif":"f8adc3573c79ee25bf6d4dd2693c61661469b28f86a5c7b1d9e41b0e8d2d53bb","tests/corrupt/no-pixi.avif":"4b1776def440dc8b913c170e4479772ee6bbb299b8679f7c564704bd03c9597e","tests/multiple-extents.avif":"b5549ac68793e155a726d754e565cea0da03fa17833d3545f45c79e13f4c9360","tests/overflow.rs":"16b591d8def1a155b3b997622f6ea255536870d99c3d8f97c51755b77a50de3c","tests/public.rs":"dd2464ef83e861833f7ef9f8a1055254f1453665fd4b5ec32a2a1f6362ce535b","tests/valid-alpha.avif":"9d417a35b9b62ad3ff66ffbc55f16552aacf821a092aa5ef4adff7e746bd4c2f","tests/valid.avif":"f0b33e09bf01232e0877df325f47986c0bee7764f2a81c9c908ae109e7dc63c4"},"package":null}
|
1
third_party/rust/mp4parse/Cargo.toml
vendored
1
third_party/rust/mp4parse/Cargo.toml
vendored
@ -44,6 +44,7 @@ criterion = "0.3"
|
||||
3gpp = []
|
||||
meta-xml = []
|
||||
unstable-api = []
|
||||
mp4v = []
|
||||
|
||||
[[bench]]
|
||||
name = "avif_benchmark"
|
||||
|
51
third_party/rust/mp4parse/src/lib.rs
vendored
51
third_party/rust/mp4parse/src/lib.rs
vendored
@ -407,6 +407,8 @@ pub struct ES_Descriptor {
|
||||
pub extended_audio_object_type: Option<u16>,
|
||||
pub audio_sample_rate: Option<u32>,
|
||||
pub audio_channel_count: Option<u16>,
|
||||
#[cfg(feature = "mp4v")]
|
||||
pub video_codec: CodecType,
|
||||
pub codec_esds: TryVec<u8>,
|
||||
pub decoder_specific_data: TryVec<u8>, // Data in DECODER_SPECIFIC_TAG
|
||||
}
|
||||
@ -902,7 +904,7 @@ impl AvifContext {
|
||||
match &item.image_data {
|
||||
IsobmffItem::Location(extent) => {
|
||||
for mdat in &self.item_storage {
|
||||
if let Some(slice) = mdat.get(&extent) {
|
||||
if let Some(slice) = mdat.get(extent) {
|
||||
return slice;
|
||||
}
|
||||
}
|
||||
@ -3725,6 +3727,14 @@ fn get_audio_object_type(bit_reader: &mut BitReader) -> Result<u16> {
|
||||
|
||||
/// See MPEG-4 Systems (ISO 14496-1:2010) § 7.2.6.7 and probably 14496-3 somewhere?
|
||||
fn read_ds_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
|
||||
#[cfg(feature = "mp4v")]
|
||||
// Check if we are in a Visual esda Box.
|
||||
if esds.video_codec != CodecType::Unknown {
|
||||
esds.decoder_specific_data.extend_from_slice(data)?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// We are in an Audio esda Box.
|
||||
let frequency_table = vec![
|
||||
(0x0, 96000),
|
||||
(0x1, 88200),
|
||||
@ -3899,6 +3909,14 @@ fn read_dc_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
|
||||
let des = &mut Cursor::new(data);
|
||||
let object_profile = des.read_u8()?;
|
||||
|
||||
#[cfg(feature = "mp4v")]
|
||||
{
|
||||
esds.video_codec = match object_profile {
|
||||
0x20..=0x24 => CodecType::MP4V,
|
||||
_ => CodecType::Unknown,
|
||||
};
|
||||
}
|
||||
|
||||
// Skip uninteresting fields.
|
||||
skip(des, 12)?;
|
||||
|
||||
@ -4214,16 +4232,27 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
|
||||
if name != BoxType::MP4VideoSampleEntry || codec_specific.is_some() {
|
||||
return Err(Error::InvalidData("malformed video sample entry"));
|
||||
}
|
||||
let (_, _) = read_fullbox_extra(&mut b.content)?;
|
||||
// Subtract 4 extra to offset the members of fullbox not
|
||||
// accounted for in head.offset
|
||||
let esds_size = b
|
||||
.head
|
||||
.size
|
||||
.checked_sub(b.head.offset + 4)
|
||||
.expect("offset invalid");
|
||||
let esds = read_buf(&mut b.content, esds_size)?;
|
||||
codec_specific = Some(VideoCodecSpecific::ESDSConfig(esds));
|
||||
#[cfg(not(feature = "mp4v"))]
|
||||
{
|
||||
let (_, _) = read_fullbox_extra(&mut b.content)?;
|
||||
// Subtract 4 extra to offset the members of fullbox not
|
||||
// accounted for in head.offset
|
||||
let esds_size = b
|
||||
.head
|
||||
.size
|
||||
.checked_sub(b.head.offset + 4)
|
||||
.expect("offset invalid");
|
||||
let esds = read_buf(&mut b.content, esds_size)?;
|
||||
codec_specific = Some(VideoCodecSpecific::ESDSConfig(esds));
|
||||
}
|
||||
#[cfg(feature = "mp4v")]
|
||||
{
|
||||
// Read ES_Descriptor inside an esds box.
|
||||
// See ISOBMFF (ISO 14496-1:2010 §7.2.6.5)
|
||||
let esds = read_esds(&mut b)?;
|
||||
codec_specific =
|
||||
Some(VideoCodecSpecific::ESDSConfig(esds.decoder_specific_data));
|
||||
}
|
||||
}
|
||||
BoxType::ProtectionSchemeInfoBox => {
|
||||
if name != BoxType::ProtectedVisualSampleEntry {
|
||||
|
4
third_party/rust/mp4parse/src/tests.rs
vendored
4
third_party/rust/mp4parse/src/tests.rs
vendored
@ -1039,8 +1039,10 @@ fn read_stsd_mp4v() {
|
||||
0x2e, 0xa6, 0x60, 0x16, 0xf4, 0x01, 0xf4, 0x24, 0xc8, 0x01, 0xe5, 0x16, 0x84, 0x3c, 0x14,
|
||||
0x63, 0x06, 0x01, 0x02,
|
||||
];
|
||||
|
||||
#[cfg(not(feature = "mp4v"))]
|
||||
let esds_specific_data = &mp4v[90..];
|
||||
#[cfg(feature = "mp4v")]
|
||||
let esds_specific_data = &mp4v[112..151];
|
||||
println!("esds_specific_data {:?}", esds_specific_data);
|
||||
|
||||
let mut stream = make_box(BoxSize::Auto, b"mp4v", |s| s.append_bytes(mp4v.as_slice()));
|
||||
|
31
third_party/rust/mp4parse/tests/public.rs
vendored
31
third_party/rust/mp4parse/tests/public.rs
vendored
@ -79,6 +79,10 @@ static AUDIO_AMRNB_3GP: &str = "tests/amr_nb_1f.3gp";
|
||||
// "ffmpeg -i [input file] -f 3gp -acodec amr_wb -ar 16000 -ac 1 -frames:a 1 -vn output.3gp"
|
||||
#[cfg(feature = "3gpp")]
|
||||
static AUDIO_AMRWB_3GP: &str = "tests/amr_wb_1f.3gp";
|
||||
#[cfg(feature = "mp4v")]
|
||||
// The 1 frame mp4v mp4 file can be generated by ffmpeg with command
|
||||
// "ffmpeg -i [input file] -f mp4 -c:v mpeg4 -vf scale=176x144 -frames:v 1 -an output.mp4"
|
||||
static VIDEO_MP4V_MP4: &str = "tests/bbb_sunflower_QCIF_30fps_mp4v_noaudio_1f.mp4";
|
||||
|
||||
// Adapted from https://github.com/GuillaumeGomez/audio-video-metadata/blob/9dff40f565af71d5502e03a2e78ae63df95cfd40/src/metadata.rs#L53
|
||||
#[test]
|
||||
@ -1054,3 +1058,30 @@ fn public_audio_amrwb() {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "mp4v")]
|
||||
fn public_video_mp4v() {
|
||||
let mut fd = File::open(VIDEO_MP4V_MP4).expect("Unknown file");
|
||||
let mut buf = Vec::new();
|
||||
fd.read_to_end(&mut buf).expect("File error");
|
||||
|
||||
let mut c = Cursor::new(&buf);
|
||||
let context = mp4::read_mp4(&mut c).expect("read_mp4 failed");
|
||||
for track in context.tracks {
|
||||
let stsd = track.stsd.expect("expected an stsd");
|
||||
let v = match stsd.descriptions.first().expect("expected a SampleEntry") {
|
||||
mp4::SampleEntry::Video(ref v) => v,
|
||||
_ => panic!("expected a VideoSampleEntry"),
|
||||
};
|
||||
assert_eq!(v.codec_type, mp4::CodecType::MP4V);
|
||||
assert_eq!(v.width, 176);
|
||||
assert_eq!(v.height, 144);
|
||||
let _codec_specific = match v.codec_specific {
|
||||
mp4::VideoCodecSpecific::ESDSConfig(_) => true,
|
||||
_ => {
|
||||
panic!("expected a ESDSConfig",);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"f664f599ce265f10355fe2cd6e4fbb24eb00e53a02b6a84f6a286d9806a2758d","cbindgen.toml":"e18e132e8c36a81af2629e7260529382486b0bb343f9aa57930348031480aecd","examples/dump.rs":"268093925d28d1636e106d93a2f2917fb1d7ddaf04ecd70880e1551fb578de1a","src/lib.rs":"0128d235a6618d7207f2dbd8eec92eeb7370be92765daa4eeac925cc9098cd08","tests/test_chunk_out_of_range.rs":"b5da583218d98027ed973a29c67434a91a1306f2d2fb39ec4d640d4824c308ce","tests/test_encryption.rs":"b918f0f10e7708bff5fae4becf1d09a188db25d874d0919d509b90266504eed7","tests/test_fragment.rs":"e90eb5a4418d30002655466c0c4b3125c7fd70a74b6871471eaa172f1def9db8","tests/test_rotation.rs":"fb43c2f2dfa496d151c33bdd46c0fd3252387c23cc71e2cac9ed0234de715a81","tests/test_sample_table.rs":"19b8d0b0f7ed79a857329321b49f5a7f687901cadd4cd22bc6728febd919d3ce","tests/test_workaround_stsc.rs":"7dd419f3d55b9a3a039cac57e58a9240a9c8166bcd4356c24f69f731c3ced83b"},"package":null}
|
||||
{"files":{"Cargo.toml":"b0653020f28155bfce958504c81c9fde20175e31774e5e42250dc7d3bc5b9985","cbindgen.toml":"e18e132e8c36a81af2629e7260529382486b0bb343f9aa57930348031480aecd","examples/dump.rs":"268093925d28d1636e106d93a2f2917fb1d7ddaf04ecd70880e1551fb578de1a","src/lib.rs":"0c473f2f08b0eb2455e01164c938dbca67978443c9917d48c0a0e1574510068e","tests/test_chunk_out_of_range.rs":"b5da583218d98027ed973a29c67434a91a1306f2d2fb39ec4d640d4824c308ce","tests/test_encryption.rs":"b918f0f10e7708bff5fae4becf1d09a188db25d874d0919d509b90266504eed7","tests/test_fragment.rs":"e90eb5a4418d30002655466c0c4b3125c7fd70a74b6871471eaa172f1def9db8","tests/test_rotation.rs":"fb43c2f2dfa496d151c33bdd46c0fd3252387c23cc71e2cac9ed0234de715a81","tests/test_sample_table.rs":"19b8d0b0f7ed79a857329321b49f5a7f687901cadd4cd22bc6728febd919d3ce","tests/test_workaround_stsc.rs":"7dd419f3d55b9a3a039cac57e58a9240a9c8166bcd4356c24f69f731c3ced83b"},"package":null}
|
3
third_party/rust/mp4parse_capi/Cargo.toml
vendored
3
third_party/rust/mp4parse_capi/Cargo.toml
vendored
@ -25,7 +25,7 @@ travis-ci = { repository = "https://github.com/mozilla/mp4parse-rust" }
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1.2.1"
|
||||
fallible_collections = { version = "0.3", features = ["std_io"] }
|
||||
fallible_collections = { version = "0.4", features = ["std_io"] }
|
||||
log = "0.4"
|
||||
mp4parse = { version = "0.11.5", path = "../mp4parse", features = ["unstable-api"] }
|
||||
num-traits = "0.2.14"
|
||||
@ -36,3 +36,4 @@ env_logger = "0.8"
|
||||
[features]
|
||||
3gpp = ["mp4parse/3gpp"]
|
||||
meta-xml = ["mp4parse/meta-xml"]
|
||||
mp4v = ["mp4parse/mp4v"]
|
||||
|
3
third_party/rust/mp4parse_capi/src/lib.rs
vendored
3
third_party/rust/mp4parse_capi/src/lib.rs
vendored
@ -973,6 +973,9 @@ fn mp4parse_get_track_video_info_safe(
|
||||
VideoCodecSpecific::AV1Config(_) => Mp4parseCodec::Av1,
|
||||
VideoCodecSpecific::AVCConfig(_) => Mp4parseCodec::Avc,
|
||||
VideoCodecSpecific::H263Config(_) => Mp4parseCodec::H263,
|
||||
#[cfg(feature = "mp4v")]
|
||||
VideoCodecSpecific::ESDSConfig(_) => Mp4parseCodec::Mp4v,
|
||||
#[cfg(not(feature = "mp4v"))]
|
||||
VideoCodecSpecific::ESDSConfig(_) =>
|
||||
// MP4V (14496-2) video is unsupported.
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ description = "Shared Rust code for libxul"
|
||||
geckoservo = { path = "../../../../servo/ports/geckolib" }
|
||||
kvstore = { path = "../../../components/kvstore" }
|
||||
lmdb-rkv-sys = { version = "0.11", features = ["mdb_idl_logn_9"] }
|
||||
mp4parse_capi = { git = "https://github.com/mozilla/mp4parse-rust", rev = "28327103f0c01b5393dd2c97f7858f9747037330" }
|
||||
mp4parse_capi = { git = "https://github.com/mozilla/mp4parse-rust", rev = "1bb484e96ae724309e3346968e8ffd4c25e61616" }
|
||||
nserror = { path = "../../../../xpcom/rust/nserror" }
|
||||
nsstring = { path = "../../../../xpcom/rust/nsstring" }
|
||||
netwerk_helper = { path = "../../../../netwerk/base/rust-helper" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user