зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1624057 - Update mp4parse-rust to 63ca8c6. r=kinetik
Also update the update-rust.sh script in a couple ways: - Stop copying the source for mp4parse_fallible into the tree; use crates.io - Include submodules in mp4parse-rust checkout; needed for tests - Exclude unnecessary build.rs from mp4parse_fallible, it was causing problems - Update mp4rust_capi/Cargo.toml patch to exclude cdylib. It's only necessary for test_ffi and causes build problems otherwise Differential Revision: https://phabricator.services.mozilla.com/D68139 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
6458fb2f4f
Коммит
6ec77fef76
|
@ -294,9 +294,12 @@ checksum = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2"
|
|||
|
||||
[[package]]
|
||||
name = "bitreader"
|
||||
version = "0.3.0"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80b13e2ab064ff3aa0bdbf1eff533f9822dc37899821f5f98c67f263eab51707"
|
||||
checksum = "5fa7f0adf37cd5472c978a1ff4be89c1880a923d10df4cfef6a10855a666e09b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bits"
|
||||
|
@ -500,9 +503,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.6"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "chardetng"
|
||||
|
@ -2717,9 +2720,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mp4parse_fallible"
|
||||
version = "0.0.1"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6626c2aef76eb8f984eef02e475883d3fe9112e114720446c5810fc5f045cd30"
|
||||
checksum = "704f773471ac3e7110427b6bdf93184932b19319c9b7717688da5424e519b10a"
|
||||
|
||||
[[package]]
|
||||
name = "msdos_time"
|
||||
|
|
|
@ -42,7 +42,6 @@ exclude = [
|
|||
"gfx/webrender_bindings",
|
||||
"media/mp4parse-rust/mp4parse",
|
||||
"media/mp4parse-rust/mp4parse_capi",
|
||||
"media/mp4parse-rust/mp4parse_fallible",
|
||||
"xpcom/rust/gkrust_utils",
|
||||
"tools/lint/test/files/clippy",
|
||||
"tools/fuzzing/rust",
|
||||
|
|
|
@ -55,55 +55,52 @@ TEST(rust, MP4MetadataEmpty)
|
|||
{
|
||||
Mp4parseStatus rv;
|
||||
Mp4parseIo io;
|
||||
Mp4parseParser* parser = nullptr;
|
||||
|
||||
// Shouldn't be able to read with no context.
|
||||
rv = mp4parse_read(nullptr);
|
||||
rv = mp4parse_new(nullptr, nullptr);
|
||||
EXPECT_EQ(rv, MP4PARSE_STATUS_BAD_ARG);
|
||||
|
||||
// Shouldn't be able to wrap an Mp4parseIo with null members.
|
||||
io = {nullptr, nullptr};
|
||||
Mp4parseParser* context = mp4parse_new(&io);
|
||||
EXPECT_EQ(context, nullptr);
|
||||
rv = mp4parse_new(&io, &parser);
|
||||
EXPECT_EQ(rv, MP4PARSE_STATUS_BAD_ARG);
|
||||
EXPECT_EQ(parser, nullptr);
|
||||
|
||||
io = {nullptr, &io};
|
||||
context = mp4parse_new(&io);
|
||||
EXPECT_EQ(context, nullptr);
|
||||
rv = mp4parse_new(&io, &parser);
|
||||
EXPECT_EQ(rv, MP4PARSE_STATUS_BAD_ARG);
|
||||
EXPECT_EQ(parser, nullptr);
|
||||
|
||||
// FIXME: this should probably be accepted.
|
||||
io = {error_reader, nullptr};
|
||||
context = mp4parse_new(&io);
|
||||
EXPECT_EQ(context, nullptr);
|
||||
rv = mp4parse_new(&io, &parser);
|
||||
EXPECT_EQ(rv, MP4PARSE_STATUS_BAD_ARG);
|
||||
EXPECT_EQ(parser, nullptr);
|
||||
|
||||
// Read method errors should propagate.
|
||||
io = {error_reader, &io};
|
||||
context = mp4parse_new(&io);
|
||||
ASSERT_NE(context, nullptr);
|
||||
rv = mp4parse_read(context);
|
||||
rv = mp4parse_new(&io, &parser);
|
||||
ASSERT_EQ(parser, nullptr);
|
||||
EXPECT_EQ(rv, MP4PARSE_STATUS_IO);
|
||||
mp4parse_free(context);
|
||||
|
||||
// Short buffers should fail.
|
||||
read_vector buf(0);
|
||||
io = {vector_reader, &buf};
|
||||
context = mp4parse_new(&io);
|
||||
ASSERT_NE(context, nullptr);
|
||||
rv = mp4parse_read(context);
|
||||
rv = mp4parse_new(&io, &parser);
|
||||
ASSERT_EQ(parser, nullptr);
|
||||
EXPECT_EQ(rv, MP4PARSE_STATUS_INVALID);
|
||||
mp4parse_free(context);
|
||||
|
||||
buf.buffer.reserve(4097);
|
||||
context = mp4parse_new(&io);
|
||||
ASSERT_NE(context, nullptr);
|
||||
rv = mp4parse_read(context);
|
||||
rv = mp4parse_new(&io, &parser);
|
||||
ASSERT_EQ(parser, nullptr);
|
||||
EXPECT_EQ(rv, MP4PARSE_STATUS_INVALID);
|
||||
mp4parse_free(context);
|
||||
|
||||
// Empty buffers should fail.
|
||||
buf.buffer.resize(4097, 0);
|
||||
context = mp4parse_new(&io);
|
||||
rv = mp4parse_read(context);
|
||||
rv = mp4parse_new(&io, &parser);
|
||||
ASSERT_EQ(parser, nullptr);
|
||||
EXPECT_EQ(rv, MP4PARSE_STATUS_UNSUPPORTED);
|
||||
mp4parse_free(context);
|
||||
}
|
||||
|
||||
TEST(rust, MP4Metadata)
|
||||
|
@ -119,16 +116,15 @@ TEST(rust, MP4Metadata)
|
|||
fclose(f);
|
||||
|
||||
Mp4parseIo io = {vector_reader, &reader};
|
||||
Mp4parseParser* context = mp4parse_new(&io);
|
||||
ASSERT_NE(nullptr, context);
|
||||
|
||||
Mp4parseStatus rv = mp4parse_read(context);
|
||||
Mp4parseParser* parser = nullptr;
|
||||
Mp4parseStatus rv = mp4parse_new(&io, &parser);
|
||||
ASSERT_NE(nullptr, parser);
|
||||
EXPECT_EQ(MP4PARSE_STATUS_OK, rv);
|
||||
|
||||
uint32_t tracks = 0;
|
||||
rv = mp4parse_get_track_count(context, &tracks);
|
||||
rv = mp4parse_get_track_count(parser, &tracks);
|
||||
EXPECT_EQ(MP4PARSE_STATUS_OK, rv);
|
||||
EXPECT_EQ(2U, tracks);
|
||||
|
||||
mp4parse_free(context);
|
||||
mp4parse_free(parser);
|
||||
}
|
||||
|
|
|
@ -90,21 +90,23 @@ static intptr_t read_source(uint8_t* buffer, uintptr_t size, void* userdata) {
|
|||
MP4Metadata::MP4Metadata(ByteStream* aSource)
|
||||
: mSource(aSource), mSourceAdaptor(aSource) {
|
||||
DDLINKCHILD("source", aSource);
|
||||
|
||||
Mp4parseIo io = {read_source, &mSourceAdaptor};
|
||||
mParser.reset(mp4parse_new(&io));
|
||||
MOZ_ASSERT(mParser);
|
||||
}
|
||||
|
||||
MP4Metadata::~MP4Metadata() = default;
|
||||
|
||||
nsresult MP4Metadata::Parse() {
|
||||
Mp4parseStatus rv = mp4parse_read(mParser.get());
|
||||
if (rv != MP4PARSE_STATUS_OK) {
|
||||
Mp4parseIo io = {read_source, &mSourceAdaptor};
|
||||
Mp4parseParser* parser = nullptr;
|
||||
Mp4parseStatus status = mp4parse_new(&io, &parser);
|
||||
if (status == MP4PARSE_STATUS_OK && parser) {
|
||||
mParser.reset(parser);
|
||||
MOZ_ASSERT(mParser);
|
||||
} else {
|
||||
MOZ_ASSERT(!mParser);
|
||||
MOZ_LOG(gMP4MetadataLog, LogLevel::Debug,
|
||||
("Parse failed, return code %d\n", rv));
|
||||
return rv == MP4PARSE_STATUS_OOM ? NS_ERROR_OUT_OF_MEMORY
|
||||
: NS_ERROR_DOM_MEDIA_METADATA_ERR;
|
||||
("Parse failed, return code %d\n", status));
|
||||
return status == MP4PARSE_STATUS_OOM ? NS_ERROR_OUT_OF_MEMORY
|
||||
: NS_ERROR_DOM_MEDIA_METADATA_ERR;
|
||||
}
|
||||
|
||||
UpdateCrypto();
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
diff --git a/media/mp4parse-rust/mp4parse_capi/Cargo.toml b/media/mp4parse-rust/mp4parse_capi/Cargo.toml
|
||||
index f04ad37ac568..a04b1e977735 100644
|
||||
--- a/media/mp4parse-rust/mp4parse_capi/Cargo.toml
|
||||
diff --git a/media/mp4parse-rust/_upstream/mp4parse/mp4parse_capi/Cargo.toml b/media/mp4parse-rust/mp4parse_capi/Cargo.toml
|
||||
index 2c606b4..895739f 100644
|
||||
--- a/media/mp4parse-rust/_upstream/mp4parse/mp4parse_capi/Cargo.toml
|
||||
+++ b/media/mp4parse-rust/mp4parse_capi/Cargo.toml
|
||||
@@ -18,6 +18,8 @@ exclude = [
|
||||
@@ -18,8 +18,7 @@ exclude = [
|
||||
"*.mp4",
|
||||
]
|
||||
|
||||
+build = false
|
||||
+
|
||||
-[lib]
|
||||
-crate-type = ["lib", "cdylib"]
|
||||
+build = false # See bug 1611431 - Generate mp4parse-rust bindings as part of mach build
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "https://github.com/mozilla/mp4parse-rust" }
|
||||
|
||||
@@ -30,9 +32,6 @@ num-traits = "0.2.0"
|
||||
@@ -33,9 +32,6 @@ num-traits = "0.2.0"
|
||||
[dev-dependencies]
|
||||
env_logger = "0.5.3"
|
||||
env_logger = "0.7.1"
|
||||
|
||||
-[build-dependencies]
|
||||
-cbindgen = "0.5.2"
|
||||
-
|
||||
[features]
|
||||
fuzz = ["mp4parse/fuzz"]
|
||||
# Enable mp4parse_fallible to use fallible memory allocation rather than
|
||||
# panicking on OOM. Note that this is only safe within Gecko where the system
|
||||
|
|
|
@ -5,6 +5,7 @@ authors = [
|
|||
"Ralph Giles <giles@mozilla.com>",
|
||||
"Matthew Gregan <kinetik@flim.org>",
|
||||
"Alfredo Yang <ayang@mozilla.com>",
|
||||
"Jon Bauman <jbauman@mozilla.com>",
|
||||
]
|
||||
|
||||
description = "Parser for ISO base media file format (mp4)"
|
||||
|
@ -24,16 +25,12 @@ travis-ci = { repository = "https://github.com/mozilla/mp4parse-rust" }
|
|||
|
||||
[dependencies]
|
||||
byteorder = "1.2.1"
|
||||
afl = { version = "0.3", optional = true }
|
||||
abort_on_panic = { version = "1.0.0", optional = true }
|
||||
bitreader = { version = "0.3.0" }
|
||||
bitreader = { version = "0.3.2" }
|
||||
num-traits = "0.2.0"
|
||||
mp4parse_fallible = { version = "0.0.1", optional = true }
|
||||
mp4parse_fallible = { version = "0.0.3", optional = true }
|
||||
log = "0.4"
|
||||
static_assertions = "1.1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
test-assembler = "0.1.2"
|
||||
|
||||
[features]
|
||||
fuzz = ["afl", "abort_on_panic"]
|
||||
env_logger = "0.7.1"
|
||||
|
|
|
@ -42,7 +42,7 @@ macro_rules! box_database {
|
|||
|
||||
#[derive(Default, PartialEq, Clone)]
|
||||
pub struct FourCC {
|
||||
pub value: String
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl From<u32> for FourCC {
|
||||
|
@ -59,9 +59,7 @@ impl From<u32> for FourCC {
|
|||
_ => String::from("null"), // error to retrieve fourcc
|
||||
};
|
||||
|
||||
FourCC {
|
||||
value: box_string
|
||||
}
|
||||
FourCC { value: box_string }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +73,7 @@ impl From<BoxType> for FourCC {
|
|||
impl<'a> From<&'a str> for FourCC {
|
||||
fn from(v: &'a str) -> FourCC {
|
||||
FourCC {
|
||||
value: v.to_owned()
|
||||
value: v.to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,6 +92,11 @@ impl fmt::Display for FourCC {
|
|||
|
||||
box_database!(
|
||||
FileTypeBox 0x6674_7970, // "ftyp"
|
||||
MediaDataBox 0x6d64_6174, // "mdat"
|
||||
PrimaryItemBox 0x7069_746d, // "pitm"
|
||||
ItemInfoBox 0x6969_6e66, // "iinf"
|
||||
ItemInfoEntry 0x696e_6665, // "infe"
|
||||
ItemLocationBox 0x696c_6f63, // "iloc"
|
||||
MovieBox 0x6d6f_6f76, // "moov"
|
||||
MovieHeaderBox 0x6d76_6864, // "mvhd"
|
||||
TrackBox 0x7472_616b, // "trak"
|
||||
|
@ -135,7 +138,7 @@ box_database!(
|
|||
ProtectionSystemSpecificHeaderBox 0x7073_7368, // "pssh"
|
||||
SchemeInformationBox 0x7363_6869, // "schi"
|
||||
TrackEncryptionBox 0x7465_6e63, // "tenc"
|
||||
ProtectionSchemeInformationBox 0x7369_6e66, // "sinf"
|
||||
ProtectionSchemeInfoBox 0x7369_6e66, // "sinf"
|
||||
OriginalFormatBox 0x6672_6d61, // "frma"
|
||||
SchemeTypeBox 0x7363_686d, // "schm"
|
||||
MP3AudioSampleEntry 0x2e6d_7033, // ".mp3" - from F4V.
|
||||
|
@ -149,7 +152,6 @@ box_database!(
|
|||
MetadataItemListEntry 0x696c_7374, // "ilst"
|
||||
MetadataItemDataEntry 0x6461_7461, // "data"
|
||||
MetadataItemNameBox 0x6e61_6d65, // "name"
|
||||
MetadataItemInformationBox 0x6974_6966, // "itif"
|
||||
UserdataBox 0x7564_7461, // "udta"
|
||||
AlbumEntry 0xa961_6c62, // "©alb"
|
||||
ArtistEntry 0xa941_5254, // "©ART"
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -8,5 +8,5 @@ macro_rules! check_parser_state {
|
|||
debug!("bad parser state: {} content bytes left", $src.limit());
|
||||
return Err(Error::InvalidData("unread box content or bad parser sync"));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,53 +0,0 @@
|
|||
/// Regression tests from American Fuzzy Lop test cases.
|
||||
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
/// These all caused panics at some point during development.
|
||||
|
||||
extern crate mp4parse;
|
||||
|
||||
use std::io::Cursor;
|
||||
|
||||
/// https://github.com/mozilla/mp4parse-rust/issues/2
|
||||
///
|
||||
/// Test a box with 4-byte size, smaller than the smallest header.
|
||||
#[test]
|
||||
fn fuzz_2() {
|
||||
let mut c = Cursor::new(b"\x00\x00\x00\x04\xa6\x00\x04\xa6".to_vec());
|
||||
let mut context = mp4parse::MediaContext::new();
|
||||
let _ = mp4parse::read_mp4(&mut c, &mut context);
|
||||
}
|
||||
|
||||
/// https://github.com/mozilla/mp4parse-rust/issues/4
|
||||
///
|
||||
/// Test a large (64 bit) box header with zero declared size.
|
||||
#[test]
|
||||
fn fuzz_4() {
|
||||
let mut c = Cursor::new(b"\x00\x00\x00\x01\x30\x30\x30\x30\x00\x00\x00\x00\x00\x00\x00\x00".to_vec());
|
||||
let mut context = mp4parse::MediaContext::new();
|
||||
let _ = mp4parse::read_mp4(&mut c, &mut context);
|
||||
}
|
||||
|
||||
/// https://github.com/mozilla/mp4parse-rust/issues/5
|
||||
///
|
||||
/// Declares 202116104 compatible brands but does not supply them,
|
||||
/// verifying read is properly bounded at the end of the stream.
|
||||
#[test]
|
||||
fn fuzz_5() {
|
||||
let mut c = Cursor::new(b"\x30\x30\x30\x30\x66\x74\x79\x70\x30\x30\x30\x30\x30\x30\x30\x30".to_vec());
|
||||
let mut context = mp4parse::MediaContext::new();
|
||||
let _ = mp4parse::read_mp4(&mut c, &mut context);
|
||||
}
|
||||
|
||||
/// https://github.com/mozilla/mp4parse-rust/issues/6
|
||||
///
|
||||
/// Declares an ftyp box with a single invalid (short - 3 byte) compatible
|
||||
/// brand and excludes the extra 3 bytes from the stream.
|
||||
#[test]
|
||||
fn fuzz_6() {
|
||||
let mut c = Cursor::new(b"\x00\x00\x00\x13\x66\x74\x79\x70\x30\x30\x30\x30\x30\x30\x30\x30".to_vec());
|
||||
let mut context = mp4parse::MediaContext::new();
|
||||
let _ = mp4parse::read_mp4(&mut c, &mut context);
|
||||
}
|
|
@ -1,13 +1,12 @@
|
|||
/// Check if needed fields are still public.
|
||||
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
extern crate mp4parse as mp4;
|
||||
|
||||
use std::io::{Cursor, Read};
|
||||
use std::fs::File;
|
||||
use std::io::{Cursor, Read};
|
||||
use std::path::Path;
|
||||
|
||||
static MINI_MP4: &str = "tests/minimal.mp4";
|
||||
static MINI_MP4_WITH_METADATA: &str = "tests/metadata.mp4";
|
||||
|
@ -27,6 +26,10 @@ static VIDEO_EME_CENC_MP4: &str = "tests/bipbop_480wp_1001kbps-cenc-video-key1-i
|
|||
static AUDIO_EME_CBCS_MP4: &str = "tests/bipbop_cbcs_audio_init.mp4";
|
||||
static VIDEO_EME_CBCS_MP4: &str = "tests/bipbop_cbcs_video_init.mp4";
|
||||
static VIDEO_AV1_MP4: &str = "tests/tiny_av1.mp4";
|
||||
static IMAGE_AVIF: &str = "av1-avif/testFiles/Microsoft/Monochrome.avif";
|
||||
static IMAGE_AVIF_GRID: &str = "av1-avif/testFiles/Microsoft/Summer_in_Tomsk_720p_5x4_grid.avif";
|
||||
static MICROSOFT_AVIF_TEST_DIR: &str = "av1-avif/testFiles/Microsoft";
|
||||
static NETFLIX_AVIF_TEST_DIR: &str = "av1-avif/testFiles/Netflix/avif";
|
||||
|
||||
// Adapted from https://github.com/GuillaumeGomez/audio-video-metadata/blob/9dff40f565af71d5502e03a2e78ae63df95cfd40/src/metadata.rs#L53
|
||||
#[test]
|
||||
|
@ -64,27 +67,30 @@ fn public_api() {
|
|||
};
|
||||
assert_eq!(v.width, 320);
|
||||
assert_eq!(v.height, 240);
|
||||
assert_eq!(match v.codec_specific {
|
||||
mp4::VideoCodecSpecific::AVCConfig(ref avc) => {
|
||||
assert!(!avc.is_empty());
|
||||
"AVC"
|
||||
}
|
||||
mp4::VideoCodecSpecific::VPxConfig(ref vpx) => {
|
||||
// We don't enter in here, we just check if fields are public.
|
||||
assert!(vpx.bit_depth > 0);
|
||||
assert!(vpx.colour_primaries > 0);
|
||||
assert!(vpx.chroma_subsampling > 0);
|
||||
assert!(!vpx.codec_init.is_empty());
|
||||
"VPx"
|
||||
}
|
||||
mp4::VideoCodecSpecific::ESDSConfig(ref mp4v) => {
|
||||
assert!(!mp4v.is_empty());
|
||||
"MP4V"
|
||||
}
|
||||
mp4::VideoCodecSpecific::AV1Config(ref _av1c) => {
|
||||
"AV1"
|
||||
}
|
||||
}, "AVC");
|
||||
assert_eq!(
|
||||
match v.codec_specific {
|
||||
mp4::VideoCodecSpecific::AVCConfig(ref avc) => {
|
||||
assert!(!avc.is_empty());
|
||||
"AVC"
|
||||
}
|
||||
mp4::VideoCodecSpecific::VPxConfig(ref vpx) => {
|
||||
// We don't enter in here, we just check if fields are public.
|
||||
assert!(vpx.bit_depth > 0);
|
||||
assert!(vpx.colour_primaries > 0);
|
||||
assert!(vpx.chroma_subsampling > 0);
|
||||
assert!(!vpx.codec_init.is_empty());
|
||||
"VPx"
|
||||
}
|
||||
mp4::VideoCodecSpecific::ESDSConfig(ref mp4v) => {
|
||||
assert!(!mp4v.is_empty());
|
||||
"MP4V"
|
||||
}
|
||||
mp4::VideoCodecSpecific::AV1Config(ref _av1c) => {
|
||||
"AV1"
|
||||
}
|
||||
},
|
||||
"AVC"
|
||||
);
|
||||
}
|
||||
mp4::TrackType::Audio => {
|
||||
// track part
|
||||
|
@ -106,36 +112,39 @@ fn public_api() {
|
|||
mp4::SampleEntry::Audio(a) => a,
|
||||
_ => panic!("expected a AudioSampleEntry"),
|
||||
};
|
||||
assert_eq!(match a.codec_specific {
|
||||
mp4::AudioCodecSpecific::ES_Descriptor(ref esds) => {
|
||||
assert_eq!(esds.audio_codec, mp4::CodecType::AAC);
|
||||
assert_eq!(esds.audio_sample_rate.unwrap(), 48000);
|
||||
assert_eq!(esds.audio_object_type.unwrap(), 2);
|
||||
"ES"
|
||||
}
|
||||
mp4::AudioCodecSpecific::FLACSpecificBox(ref flac) => {
|
||||
// STREAMINFO block must be present and first.
|
||||
assert!(!flac.blocks.is_empty());
|
||||
assert_eq!(flac.blocks[0].block_type, 0);
|
||||
assert_eq!(flac.blocks[0].data.len(), 34);
|
||||
"FLAC"
|
||||
}
|
||||
mp4::AudioCodecSpecific::OpusSpecificBox(ref opus) => {
|
||||
// We don't enter in here, we just check if fields are public.
|
||||
assert!(opus.version > 0);
|
||||
"Opus"
|
||||
}
|
||||
mp4::AudioCodecSpecific::ALACSpecificBox(ref alac) => {
|
||||
assert!(alac.data.len() == 24 || alac.data.len() == 48);
|
||||
"ALAC"
|
||||
}
|
||||
mp4::AudioCodecSpecific::MP3 => {
|
||||
"MP3"
|
||||
}
|
||||
mp4::AudioCodecSpecific::LPCM => {
|
||||
"LPCM"
|
||||
}
|
||||
}, "ES");
|
||||
assert_eq!(
|
||||
match a.codec_specific {
|
||||
mp4::AudioCodecSpecific::ES_Descriptor(ref esds) => {
|
||||
assert_eq!(esds.audio_codec, mp4::CodecType::AAC);
|
||||
assert_eq!(esds.audio_sample_rate.unwrap(), 48000);
|
||||
assert_eq!(esds.audio_object_type.unwrap(), 2);
|
||||
"ES"
|
||||
}
|
||||
mp4::AudioCodecSpecific::FLACSpecificBox(ref flac) => {
|
||||
// STREAMINFO block must be present and first.
|
||||
assert!(!flac.blocks.is_empty());
|
||||
assert_eq!(flac.blocks[0].block_type, 0);
|
||||
assert_eq!(flac.blocks[0].data.len(), 34);
|
||||
"FLAC"
|
||||
}
|
||||
mp4::AudioCodecSpecific::OpusSpecificBox(ref opus) => {
|
||||
// We don't enter in here, we just check if fields are public.
|
||||
assert!(opus.version > 0);
|
||||
"Opus"
|
||||
}
|
||||
mp4::AudioCodecSpecific::ALACSpecificBox(ref alac) => {
|
||||
assert!(alac.data.len() == 24 || alac.data.len() == 48);
|
||||
"ALAC"
|
||||
}
|
||||
mp4::AudioCodecSpecific::MP3 => {
|
||||
"MP3"
|
||||
}
|
||||
mp4::AudioCodecSpecific::LPCM => {
|
||||
"LPCM"
|
||||
}
|
||||
},
|
||||
"ES"
|
||||
);
|
||||
assert!(a.samplesize > 0);
|
||||
assert!(a.samplerate > 0.0);
|
||||
}
|
||||
|
@ -154,7 +163,9 @@ fn public_metadata() {
|
|||
let mut c = Cursor::new(&buf);
|
||||
let mut context = mp4::MediaContext::new();
|
||||
mp4::read_mp4(&mut c, &mut context).expect("read_mp4 failed");
|
||||
let udta = context.userdata.expect("didn't find udta")
|
||||
let udta = context
|
||||
.userdata
|
||||
.expect("didn't find udta")
|
||||
.expect("failed to parse udta");
|
||||
let meta = udta.meta.expect("didn't find meta");
|
||||
assert_eq!(meta.title.unwrap(), "Title");
|
||||
|
@ -162,7 +173,10 @@ fn public_metadata() {
|
|||
assert_eq!(meta.album_artist.unwrap(), "Album Artist");
|
||||
assert_eq!(meta.comment.unwrap(), "Comments");
|
||||
assert_eq!(meta.year.unwrap(), "2019");
|
||||
assert_eq!(meta.genre.unwrap(), mp4::Genre::CustomGenre("Custom Genre".to_string()));
|
||||
assert_eq!(
|
||||
meta.genre.unwrap(),
|
||||
mp4::Genre::CustomGenre("Custom Genre".to_string())
|
||||
);
|
||||
assert_eq!(meta.encoder.unwrap(), "Lavf56.40.101");
|
||||
assert_eq!(meta.encoded_by.unwrap(), "Encoded-by");
|
||||
assert_eq!(meta.copyright.unwrap(), "Copyright");
|
||||
|
@ -217,7 +231,9 @@ fn public_metadata_gnre() {
|
|||
let mut c = Cursor::new(&buf);
|
||||
let mut context = mp4::MediaContext::new();
|
||||
mp4::read_mp4(&mut c, &mut context).expect("read_mp4 failed");
|
||||
let udta = context.userdata.expect("didn't find udta")
|
||||
let udta = context
|
||||
.userdata
|
||||
.expect("didn't find udta")
|
||||
.expect("failed to parse udta");
|
||||
let meta = udta.meta.expect("didn't find meta");
|
||||
assert_eq!(meta.title.unwrap(), "Title");
|
||||
|
@ -272,9 +288,10 @@ fn public_metadata_gnre() {
|
|||
|
||||
#[test]
|
||||
fn public_audio_tenc() {
|
||||
let kid =
|
||||
vec![0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04,
|
||||
0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04];
|
||||
let kid = vec![
|
||||
0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d,
|
||||
0x04,
|
||||
];
|
||||
|
||||
let mut fd = File::open(AUDIO_EME_CENC_MP4).expect("Unknown file");
|
||||
let mut buf = Vec::new();
|
||||
|
@ -308,32 +325,32 @@ fn public_audio_tenc() {
|
|||
} else {
|
||||
panic!("Invalid test condition");
|
||||
}
|
||||
},
|
||||
_=> {
|
||||
}
|
||||
_ => {
|
||||
panic!("Invalid test condition");
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_video_cenc() {
|
||||
let system_id =
|
||||
vec![0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02,
|
||||
0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b];
|
||||
let system_id = vec![
|
||||
0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb,
|
||||
0x4b,
|
||||
];
|
||||
|
||||
let kid =
|
||||
vec![0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x03,
|
||||
0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x11];
|
||||
let kid = vec![
|
||||
0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d,
|
||||
0x11,
|
||||
];
|
||||
|
||||
let pssh_box =
|
||||
vec![0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68,
|
||||
0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef, 0xec,
|
||||
0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e,
|
||||
0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00, 0x00, 0x01,
|
||||
0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x03,
|
||||
0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x11,
|
||||
0x00, 0x00, 0x00, 0x00];
|
||||
let pssh_box = vec![
|
||||
0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68, 0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef,
|
||||
0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00,
|
||||
0x00, 0x01, 0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x03, 0x7e, 0x57, 0x1d, 0x03, 0x7e,
|
||||
0x57, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
let mut fd = File::open(VIDEO_EME_CENC_MP4).expect("Unknown file");
|
||||
let mut buf = Vec::new();
|
||||
|
@ -367,8 +384,8 @@ fn public_video_cenc() {
|
|||
} else {
|
||||
panic!("Invalid test condition");
|
||||
}
|
||||
},
|
||||
_=> {
|
||||
}
|
||||
_ => {
|
||||
panic!("Invalid test condition");
|
||||
}
|
||||
}
|
||||
|
@ -385,27 +402,28 @@ fn public_video_cenc() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn publicaudio_cbcs() {
|
||||
let system_id =
|
||||
vec![0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02,
|
||||
0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b];
|
||||
fn public_audio_cbcs() {
|
||||
let system_id = vec![
|
||||
0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb,
|
||||
0x4b,
|
||||
];
|
||||
|
||||
let kid =
|
||||
vec![0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04,
|
||||
0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x21];
|
||||
let kid = vec![
|
||||
0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d,
|
||||
0x21,
|
||||
];
|
||||
|
||||
let default_iv =
|
||||
vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
|
||||
0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66];
|
||||
let default_iv = vec![
|
||||
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
|
||||
0x66,
|
||||
];
|
||||
|
||||
let pssh_box =
|
||||
vec![0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68,
|
||||
0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef, 0xec,
|
||||
0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e,
|
||||
0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00, 0x00, 0x01,
|
||||
0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04,
|
||||
0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x21,
|
||||
0x00, 0x00, 0x00, 0x00];
|
||||
let pssh_box = vec![
|
||||
0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68, 0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef,
|
||||
0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00,
|
||||
0x00, 0x01, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e,
|
||||
0x57, 0x1d, 0x21, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
let mut fd = File::open(AUDIO_EME_CBCS_MP4).expect("Unknown file");
|
||||
let mut buf = Vec::new();
|
||||
|
@ -443,14 +461,16 @@ fn publicaudio_cbcs() {
|
|||
panic!("Invalid test condition");
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
panic!("expected a VideoSampleEntry");
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
assert!(found_encrypted_sample_description,
|
||||
"Should have found an encrypted sample description");
|
||||
assert!(
|
||||
found_encrypted_sample_description,
|
||||
"Should have found an encrypted sample description"
|
||||
);
|
||||
}
|
||||
|
||||
for pssh in context.psshs {
|
||||
|
@ -466,26 +486,27 @@ fn publicaudio_cbcs() {
|
|||
#[test]
|
||||
#[allow(clippy::cognitive_complexity)] // TODO: Consider simplifying this
|
||||
fn public_video_cbcs() {
|
||||
let system_id =
|
||||
vec![0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02,
|
||||
0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b];
|
||||
let system_id = vec![
|
||||
0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb,
|
||||
0x4b,
|
||||
];
|
||||
|
||||
let kid =
|
||||
vec![0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04,
|
||||
0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x21];
|
||||
let kid = vec![
|
||||
0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d,
|
||||
0x21,
|
||||
];
|
||||
|
||||
let default_iv =
|
||||
vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
|
||||
0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66];
|
||||
let default_iv = vec![
|
||||
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
|
||||
0x66,
|
||||
];
|
||||
|
||||
let pssh_box =
|
||||
vec![0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68,
|
||||
0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef, 0xec,
|
||||
0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e,
|
||||
0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00, 0x00, 0x01,
|
||||
0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04,
|
||||
0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x21,
|
||||
0x00, 0x00, 0x00, 0x00];
|
||||
let pssh_box = vec![
|
||||
0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68, 0x01, 0x00, 0x00, 0x00, 0x10, 0x77, 0xef,
|
||||
0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b, 0x00, 0x00,
|
||||
0x00, 0x01, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e, 0x57, 0x1d, 0x04, 0x7e,
|
||||
0x57, 0x1d, 0x21, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
let mut fd = File::open(VIDEO_EME_CBCS_MP4).expect("Unknown file");
|
||||
let mut buf = Vec::new();
|
||||
|
@ -522,14 +543,16 @@ fn public_video_cbcs() {
|
|||
panic!("Invalid test condition");
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
panic!("expected a VideoSampleEntry");
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
assert!(found_encrypted_sample_description,
|
||||
"Should have found an encrypted sample description");
|
||||
assert!(
|
||||
found_encrypted_sample_description,
|
||||
"Should have found an encrypted sample description"
|
||||
);
|
||||
}
|
||||
|
||||
for pssh in context.psshs {
|
||||
|
@ -556,7 +579,7 @@ fn public_video_av1() {
|
|||
// track part
|
||||
assert_eq!(track.duration, Some(mp4::TrackScaledTime(512, 0)));
|
||||
assert_eq!(track.empty_duration, Some(mp4::MediaScaledTime(0)));
|
||||
assert_eq!(track.media_time, Some(mp4::TrackScaledTime(0,0)));
|
||||
assert_eq!(track.media_time, Some(mp4::TrackScaledTime(0, 0)));
|
||||
assert_eq!(track.timescale, Some(mp4::TrackTimeScale(12288, 0)));
|
||||
|
||||
// track.tkhd part
|
||||
|
@ -589,8 +612,51 @@ fn public_video_av1() {
|
|||
assert_eq!(av1c.chroma_sample_position, 0);
|
||||
assert_eq!(av1c.initial_presentation_delay_present, false);
|
||||
assert_eq!(av1c.initial_presentation_delay_minus_one, 0);
|
||||
},
|
||||
}
|
||||
_ => panic!("Invalid test condition"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_primary_item() {
|
||||
let context = &mut mp4::AvifContext::new();
|
||||
let input = &mut File::open(IMAGE_AVIF).expect("Unknown file");
|
||||
mp4::read_avif(input, context).expect("read_avif failed");
|
||||
assert_eq!(context.primary_item.len(), 6979);
|
||||
assert_eq!(context.primary_item[0..4], [0x12, 0x00, 0x0a, 0x0a]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // Remove when we add support; see https://github.com/mozilla/mp4parse-rust/issues/198
|
||||
fn public_avif_primary_item_is_grid() {
|
||||
let context = &mut mp4::AvifContext::new();
|
||||
let input = &mut File::open(IMAGE_AVIF_GRID).expect("Unknown file");
|
||||
mp4::read_avif(input, context).expect("read_avif failed");
|
||||
// Add some additional checks
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_read_samples() {
|
||||
env_logger::init();
|
||||
let microsoft = Path::new(MICROSOFT_AVIF_TEST_DIR)
|
||||
.read_dir()
|
||||
.expect("Cannot read AVIF test dir");
|
||||
let netflix = Path::new(NETFLIX_AVIF_TEST_DIR)
|
||||
.read_dir()
|
||||
.expect("Cannot read AVIF test dir");
|
||||
for entry in microsoft.chain(netflix) {
|
||||
let path = entry.expect("AVIF entry").path();
|
||||
if path.extension().expect("no extension") != "avif" {
|
||||
eprintln!("Skipping {:?}", path);
|
||||
continue; // Skip ReadMe.txt, etc.
|
||||
}
|
||||
if path == Path::new(IMAGE_AVIF_GRID) {
|
||||
eprintln!("Skipping {:?}", path);
|
||||
continue; // Remove when public_avif_primary_item_is_grid passes
|
||||
}
|
||||
let context = &mut mp4::AvifContext::new();
|
||||
let input = &mut File::open(path).expect("Unknow file");
|
||||
mp4::read_avif(input, context).expect("read_avif failed");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ exclude = [
|
|||
"*.mp4",
|
||||
]
|
||||
|
||||
build = false
|
||||
build = false # See bug 1611431 - Generate mp4parse-rust bindings as part of mach build
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "https://github.com/mozilla/mp4parse-rust" }
|
||||
|
@ -30,10 +30,9 @@ mp4parse = {version = "0.11.2", path = "../mp4parse"}
|
|||
num-traits = "0.2.0"
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.5.3"
|
||||
env_logger = "0.7.1"
|
||||
|
||||
[features]
|
||||
fuzz = ["mp4parse/fuzz"]
|
||||
# Enable mp4parse_fallible to use fallible memory allocation rather than
|
||||
# panicking on OOM. Note that this is only safe within Gecko where the system
|
||||
# allocator has been globally overridden (see BMO 1457359).
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
extern crate cbindgen;
|
||||
|
||||
use cbindgen::{Config, RenameRule};
|
||||
|
||||
fn main() {
|
||||
let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
|
||||
println!("cargo:rerun-if-changed=src/lib.rs");
|
||||
|
||||
let config = {
|
||||
let mut c: Config = Default::default();
|
||||
c.header = Some(r##"
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
"##.trim().into());
|
||||
c.trailer = Some(r##"
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
"##.trim().into());
|
||||
c.include_guard = Some("MP4PARSE_CAPI_H".to_owned());
|
||||
c.autogen_warning = Some(
|
||||
"// THIS FILE IS AUTOGENERATED BY mp4parse_capi/build.rs - DO NOT EDIT".to_owned(),
|
||||
);
|
||||
c.language = cbindgen::Language::C;
|
||||
c.enumeration.rename_variants = Some(RenameRule::QualifiedScreamingSnakeCase);
|
||||
c
|
||||
};
|
||||
|
||||
// Generate mp4parse.h.
|
||||
cbindgen::generate_with_config(&crate_dir, config)
|
||||
.expect("Could not generate header")
|
||||
.write_to_file("include/mp4parse.h");
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,10 +0,0 @@
|
|||
[package]
|
||||
name = "mp4parse_fallible"
|
||||
version = "0.0.1"
|
||||
authors = ["The Servo Project Developers"]
|
||||
license = "MPL-2.0"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
name = "mp4parse_fallible"
|
||||
path = "lib.rs"
|
|
@ -1,7 +0,0 @@
|
|||
This is from https://github.com/servo/servo/tree/master/components/fallible
|
||||
with modificaion for mp4 demuxer.
|
||||
|
||||
The purpose of this crate is to solve infallible memory allocation problem
|
||||
which causes OOM easily on win32. This is more like a temporary solution.
|
||||
Once rust supports fallible memory allocation in its stdlib, this can be
|
||||
retired.
|
|
@ -1,92 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::mem;
|
||||
use std::vec::Vec;
|
||||
|
||||
extern "C" {
|
||||
fn realloc(ptr: *mut u8, bytes: usize) -> *mut u8;
|
||||
fn malloc(bytes: usize) -> *mut u8;
|
||||
}
|
||||
|
||||
pub trait FallibleVec<T> {
|
||||
/// Append |val| to the end of |vec|. Returns Ok(()) on success,
|
||||
/// Err(()) if it fails, which can only be due to lack of memory.
|
||||
fn try_push(&mut self, value: T) -> Result<(), ()>;
|
||||
|
||||
/// Expand the vector size. Return Ok(()) on success, Err(()) if it
|
||||
/// fails.
|
||||
fn try_reserve(&mut self, new_cap: usize) -> Result<(), ()>;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// Vec
|
||||
|
||||
impl<T> FallibleVec<T> for Vec<T> {
|
||||
#[inline]
|
||||
fn try_push(&mut self, val: T) -> Result<(), ()> {
|
||||
if self.capacity() == self.len() {
|
||||
let old_cap: usize = self.capacity();
|
||||
let new_cap: usize
|
||||
= if old_cap == 0 { 4 } else { old_cap.checked_mul(2).ok_or(()) ? };
|
||||
|
||||
try_extend_vec(self, new_cap)?;
|
||||
debug_assert!(self.capacity() > self.len());
|
||||
}
|
||||
self.push(val);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_reserve(&mut self, cap: usize) -> Result<(), ()> {
|
||||
let new_cap = cap + self.capacity();
|
||||
try_extend_vec(self, new_cap)?;
|
||||
debug_assert!(self.capacity() == new_cap);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
#[cold]
|
||||
fn try_extend_vec<T>(vec: &mut Vec<T>, new_cap: usize) -> Result<(), ()> {
|
||||
let old_ptr = vec.as_mut_ptr();
|
||||
let old_len = vec.len();
|
||||
|
||||
let old_cap: usize = vec.capacity();
|
||||
|
||||
if old_cap >= new_cap {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let new_size_bytes
|
||||
= new_cap.checked_mul(mem::size_of::<T>()).ok_or(()) ? ;
|
||||
|
||||
let new_ptr = unsafe {
|
||||
if old_cap == 0 {
|
||||
malloc(new_size_bytes)
|
||||
} else {
|
||||
realloc(old_ptr as *mut u8, new_size_bytes)
|
||||
}
|
||||
};
|
||||
|
||||
if new_ptr.is_null() {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let new_vec = unsafe {
|
||||
Vec::from_raw_parts(new_ptr as *mut T, old_len, new_cap)
|
||||
};
|
||||
|
||||
mem::forget(mem::replace(vec, new_vec));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oom_test() {
|
||||
let mut vec: Vec<char> = Vec::new();
|
||||
match vec.try_reserve(std::usize::MAX) {
|
||||
Ok(_) => panic!("it should be OOM"),
|
||||
_ => (),
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
set -e
|
||||
|
||||
# Default version.
|
||||
VER="3e0f34a2eb53c6d892b5061f76c8290e5d39e920"
|
||||
VER="63ca8c6bde27b39dea87fb15e2922a23cb38c8df"
|
||||
|
||||
# Accept version or commit from the command line.
|
||||
if test -n "$1"; then
|
||||
|
@ -13,8 +13,8 @@ fi
|
|||
|
||||
echo "Fetching sources..."
|
||||
rm -rf _upstream
|
||||
git clone https://github.com/mozilla/mp4parse-rust _upstream/mp4parse
|
||||
git clone https://github.com/alfredoyang/mp4parse_fallible _upstream/mp4parse_fallible
|
||||
git clone --recurse-submodules https://github.com/mozilla/mp4parse-rust _upstream/mp4parse
|
||||
|
||||
pushd _upstream/mp4parse
|
||||
git checkout ${VER}
|
||||
echo "Verifying sources..."
|
||||
|
@ -32,11 +32,7 @@ cp _upstream/mp4parse/mp4parse/tests/*.mp4 mp4parse/tests/
|
|||
find mp4parse_capi -not -name cbindgen.toml -delete
|
||||
mkdir -p mp4parse_capi/src
|
||||
cp _upstream/mp4parse/mp4parse_capi/Cargo.toml mp4parse_capi/
|
||||
cp _upstream/mp4parse/mp4parse_capi/build.rs mp4parse_capi/
|
||||
cp _upstream/mp4parse/mp4parse_capi/src/*.rs mp4parse_capi/src/
|
||||
rm -rf mp4parse_fallible
|
||||
mkdir -p mp4parse_fallible
|
||||
cp _upstream/mp4parse_fallible/* mp4parse_fallible/
|
||||
|
||||
echo "Applying patches..."
|
||||
patch -p3 < mp4parse-cargo.patch
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"4ea2fe4a12740a572f459cc5c51ca721b1a7b256a0976be561c9b0a9fce0dcc7","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"8583712ee2b062ff3d4d6d3e16f19ff0f92bc3a0a4beeec11a81ef00146fbd4f","README.md":"a8bfdd9509bb3bb30b30bbe308a717e9827cf97d7a97e5fb5cd69bdd3c88a490","src/lib.rs":"a7ed9d2607f47b7d5d11ccaccf23486a21d072435231d09f4548ad0c4ad62f5b","src/tests.rs":"c4e99780432b3ad05f625961699da72239a975f838cb0ab1cf2501424baed38c"},"package":"80b13e2ab064ff3aa0bdbf1eff533f9822dc37899821f5f98c67f263eab51707"}
|
||||
{"files":{"Cargo.toml":"27cfa3fe44cc78bce30786d727dedef7967e399c0cdec1282e8dafc9c38a6c10","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"8583712ee2b062ff3d4d6d3e16f19ff0f92bc3a0a4beeec11a81ef00146fbd4f","README.md":"28986de2e8d457e76ae3303d80094697e6ef4ad8da06a4a3178bb1b52bff63d5","src/lib.rs":"6947e329a2f20dca35ea14b6f483c23b4812ae55b6851a276355c31fb7dd65e9","src/tests.rs":"b3ed3ae22daa348dc786219b6e2c4f2b1d3ba35d7d4401ea05f773773fdf8807"},"package":"5fa7f0adf37cd5472c978a1ff4be89c1880a923d10df4cfef6a10855a666e09b"}
|
|
@ -1,19 +1,28 @@
|
|||
# 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]
|
||||
name = "bitreader"
|
||||
version = "0.3.0"
|
||||
version = "0.3.2"
|
||||
authors = ["Ilkka Rauta <ilkka.rauta@gmail.com>"]
|
||||
|
||||
description = """
|
||||
BitReader helps reading individual bits from a slice of bytes.
|
||||
|
||||
You can read "unusual" numbers of bits from the byte slice, for example 13 bits
|
||||
at once. The reader internally keeps track of position within the buffer.
|
||||
"""
|
||||
|
||||
documentation = "https://docs.rs/bitreader"
|
||||
description = "BitReader helps reading individual bits from a slice of bytes.\n\nYou can read \"unusual\" numbers of bits from the byte slice, for example 13 bits\nat once. The reader internally keeps track of position within the buffer.\n"
|
||||
homepage = "https://github.com/irauta/bitreader"
|
||||
repository = "https://github.com/irauta/bitreader"
|
||||
|
||||
documentation = "https://docs.rs/bitreader"
|
||||
keywords = ["bit", "bits", "bitstream"]
|
||||
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/irauta/bitreader"
|
||||
[dependencies.cfg-if]
|
||||
version = "0.1.9"
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = []
|
||||
|
|
|
@ -20,7 +20,7 @@ Here is how you read first a single bit, then three bits and finally four bits f
|
|||
|
||||
You can naturally read bits from longer buffer of data than just a single byte.
|
||||
|
||||
As you read bits, the internal cursor of BitReader moves on along the stream of bits. Little endian format is assumed when reading the multi-byte values. BitReader supports reading maximum of 64 bits at a time (with read_u64).
|
||||
As you read bits, the internal cursor of BitReader moves on along the stream of bits. Big endian format is assumed when reading the multi-byte values. BitReader supports reading maximum of 64 bits at a time (with read_u64).
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
//! ```
|
||||
//! You can naturally read bits from longer buffer of data than just a single byte.
|
||||
//!
|
||||
//! As you read bits, the internal cursor of BitReader moves on along the stream of bits. Little
|
||||
//! As you read bits, the internal cursor of BitReader moves on along the stream of bits. Big
|
||||
//! endian format is assumed when reading the multi-byte values. BitReader supports reading maximum
|
||||
//! of 64 bits at a time (with read_u64). Reading signed values directly is not supported at the
|
||||
//! moment.
|
||||
|
@ -46,10 +46,19 @@
|
|||
//! Note that the code will likely not work correctly if the slice is longer than 2^61 bytes, but
|
||||
//! exceeding that should be pretty unlikely. Let's get back to this when people read exabytes of
|
||||
//! information one bit at a time.
|
||||
|
||||
use std::fmt;
|
||||
use std::error::Error;
|
||||
use std::result;
|
||||
#![no_std]
|
||||
cfg_if::cfg_if!{
|
||||
if #[cfg(feature = "std")] {
|
||||
extern crate std;
|
||||
use std::prelude::v1::*;
|
||||
use std::fmt;
|
||||
use std::error::Error;
|
||||
use std::result;
|
||||
} else {
|
||||
use core::result;
|
||||
use core::fmt;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
@ -105,60 +114,79 @@ impl<'a> BitReader<'a> {
|
|||
|
||||
/// Read at most 8 bits into a u8.
|
||||
pub fn read_u8(&mut self, bit_count: u8) -> Result<u8> {
|
||||
let value = try!(self.read_value(bit_count, 8));
|
||||
let value = self.read_value(bit_count, 8)?;
|
||||
Ok((value & 0xff) as u8)
|
||||
}
|
||||
|
||||
/// Fills the entire `output_bytes` slice. If there aren't enough bits remaining
|
||||
/// after the internal cursor's current position, the cursor won't be moved forward
|
||||
/// and the contents of `output_bytes` won't be modified.
|
||||
pub fn read_u8_slice(&mut self, output_bytes: &mut [u8]) -> Result<()> {
|
||||
let requested = output_bytes.len() as u64 * 8;
|
||||
if requested > self.remaining() {
|
||||
Err(BitReaderError::NotEnoughData {
|
||||
position: self.position,
|
||||
length: (self.bytes.len() * 8) as u64,
|
||||
requested: requested,
|
||||
})
|
||||
} else {
|
||||
for byte in output_bytes.iter_mut() {
|
||||
*byte = self.read_u8(8)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Read at most 16 bits into a u16.
|
||||
pub fn read_u16(&mut self, bit_count: u8) -> Result<u16> {
|
||||
let value = try!(self.read_value(bit_count, 16));
|
||||
let value = self.read_value(bit_count, 16)?;
|
||||
Ok((value & 0xffff) as u16)
|
||||
}
|
||||
|
||||
/// Read at most 32 bits into a u32.
|
||||
pub fn read_u32(&mut self, bit_count: u8) -> Result<u32> {
|
||||
let value = try!(self.read_value(bit_count, 32));
|
||||
let value = self.read_value(bit_count, 32)?;
|
||||
Ok((value & 0xffffffff) as u32)
|
||||
}
|
||||
|
||||
/// Read at most 64 bits into a u64.
|
||||
pub fn read_u64(&mut self, bit_count: u8) -> Result<u64> {
|
||||
let value = try!(self.read_value(bit_count, 64));
|
||||
let value = self.read_value(bit_count, 64)?;
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
/// Read at most 8 bits into a i8.
|
||||
/// Assumes the bits are stored in two's complement format.
|
||||
pub fn read_i8(&mut self, bit_count: u8) -> Result<i8> {
|
||||
let value = try!(self.read_signed_value(bit_count, 8));
|
||||
let value = self.read_signed_value(bit_count, 8)?;
|
||||
Ok((value & 0xff) as i8)
|
||||
}
|
||||
|
||||
/// Read at most 16 bits into a i16.
|
||||
/// Assumes the bits are stored in two's complement format.
|
||||
pub fn read_i16(&mut self, bit_count: u8) -> Result<i16> {
|
||||
let value = try!(self.read_signed_value(bit_count, 16));
|
||||
let value = self.read_signed_value(bit_count, 16)?;
|
||||
Ok((value & 0xffff) as i16)
|
||||
}
|
||||
|
||||
/// Read at most 32 bits into a i32.
|
||||
/// Assumes the bits are stored in two's complement format.
|
||||
pub fn read_i32(&mut self, bit_count: u8) -> Result<i32> {
|
||||
let value = try!(self.read_signed_value(bit_count, 32));
|
||||
let value = self.read_signed_value(bit_count, 32)?;
|
||||
Ok((value & 0xffffffff) as i32)
|
||||
}
|
||||
|
||||
/// Read at most 64 bits into a i64.
|
||||
/// Assumes the bits are stored in two's complement format.
|
||||
pub fn read_i64(&mut self, bit_count: u8) -> Result<i64> {
|
||||
let value = try!(self.read_signed_value(bit_count, 64));
|
||||
let value = self.read_signed_value(bit_count, 64)?;
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
/// Read a single bit as a boolean value.
|
||||
/// Interprets 1 as true and 0 as false.
|
||||
pub fn read_bool(&mut self) -> Result<bool> {
|
||||
match try!(self.read_value(1, 1)) {
|
||||
match self.read_value(1, 1)? {
|
||||
0 => Ok(false),
|
||||
_ => Ok(true),
|
||||
}
|
||||
|
@ -183,6 +211,12 @@ impl<'a> BitReader<'a> {
|
|||
self.position - self.relative_offset
|
||||
}
|
||||
|
||||
/// Returns the number of bits not yet read from the underlying slice.
|
||||
pub fn remaining(&self) -> u64 {
|
||||
let total_bits = self.bytes.len() as u64 * 8;
|
||||
total_bits - self.position
|
||||
}
|
||||
|
||||
/// Helper to make sure the "bit cursor" is exactly at the beginning of a byte, or at specific
|
||||
/// multi-byte alignment position.
|
||||
///
|
||||
|
@ -198,7 +232,7 @@ impl<'a> BitReader<'a> {
|
|||
}
|
||||
|
||||
fn read_signed_value(&mut self, bit_count: u8, maximum_count: u8) -> Result<i64> {
|
||||
let unsigned = try!(self.read_value(bit_count, maximum_count));
|
||||
let unsigned = self.read_value(bit_count, maximum_count)?;
|
||||
// Fill the bits above the requested bits with all ones or all zeros,
|
||||
// depending on the sign bit.
|
||||
let sign_bit = unsigned >> (bit_count - 1) & 1;
|
||||
|
@ -263,6 +297,7 @@ pub enum BitReaderError {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Error for BitReaderError {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
|
@ -339,7 +374,7 @@ impl_read_into!(i64, read_i64);
|
|||
// We can't cast to bool, so this requires a separate method.
|
||||
impl ReadInto for bool {
|
||||
fn read(reader: &mut BitReader, bits: u8) -> Result<Self> {
|
||||
match try!(reader.read_u8(bits)) {
|
||||
match reader.read_u8(bits)? {
|
||||
0 => Ok(false),
|
||||
_ => Ok(true),
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ fn read_buffer() {
|
|||
assert_eq!(reader.read_u8(1).unwrap(), 0b0);
|
||||
assert_eq!(reader.read_u8(2).unwrap(), 0b11);
|
||||
|
||||
assert_eq!(reader.position(), 4);
|
||||
assert_eq!(reader.remaining(), 60);
|
||||
|
||||
assert_eq!(reader.read_u8(4).unwrap(), 0b0101);
|
||||
|
||||
assert!(reader.is_aligned(1));
|
||||
|
@ -29,6 +32,9 @@ fn read_buffer() {
|
|||
assert_eq!(reader.read_u16(10).unwrap(), 0b01_0101_0101);
|
||||
assert_eq!(reader.read_u8(3).unwrap(), 0b100);
|
||||
|
||||
assert_eq!(reader.position(), 24);
|
||||
assert_eq!(reader.remaining(), 40);
|
||||
|
||||
assert!(reader.is_aligned(1));
|
||||
|
||||
assert_eq!(reader.read_u32(32).unwrap(), 0b1001_1001_1001_1001_1001_1001_1001_1001);
|
||||
|
@ -150,3 +156,52 @@ fn boolean_values() {
|
|||
assert_eq!(reader.read_bool().unwrap(), v & 0x01 == 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_slice() {
|
||||
let bytes = &[
|
||||
0b1111_0000, 0b0000_1111, 0b1111_0000,
|
||||
0b0000_1000, 0b0000_0100, 0b0000_0011,
|
||||
0b1111_1100, 0b0000_0011, 0b1101_1000,
|
||||
];
|
||||
let mut reader = BitReader::new(bytes);
|
||||
assert_eq!(reader.read_u8(4).unwrap(), 0b1111);
|
||||
// Just some pattern that's definitely not in the bytes array
|
||||
let mut output = [0b1010_1101; 3];
|
||||
reader.read_u8_slice(&mut output).unwrap();
|
||||
assert_eq!(&output, &[0u8, 255u8, 0u8]);
|
||||
|
||||
assert_eq!(reader.read_u8(1).unwrap(), 1);
|
||||
|
||||
reader.read_u8_slice(&mut output[1..2]).unwrap();
|
||||
assert_eq!(&output, &[0u8, 0u8, 0u8]);
|
||||
|
||||
assert_eq!(reader.read_u8(1).unwrap(), 1);
|
||||
|
||||
output = [0b1010_1101; 3];
|
||||
reader.read_u8_slice(&mut output).unwrap();
|
||||
assert_eq!(&output, &[0u8, 255u8, 0u8]);
|
||||
|
||||
reader.read_u8_slice(&mut output[0..1]).unwrap();
|
||||
assert_eq!(output[0], 0b1111_0110);
|
||||
|
||||
assert_eq!(reader.read_u8(2).unwrap(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_slice_too_much() {
|
||||
let bytes = &[
|
||||
0b1111_1111, 0b1111_1111, 0b1111_1111, 0b1111_1111,
|
||||
];
|
||||
let mut reader = BitReader::new(bytes);
|
||||
assert_eq!(reader.read_u8(1).unwrap(), 1);
|
||||
|
||||
let mut output = [0u8; 4];
|
||||
let should_be_error = reader.read_u8_slice(&mut output);
|
||||
assert_eq!(should_be_error.unwrap_err(), BitReaderError::NotEnoughData {
|
||||
position: 1,
|
||||
length: (bytes.len() * 8) as u64,
|
||||
requested: (&output.len() * 8) as u64
|
||||
});
|
||||
assert_eq!(&output, &[0u8; 4]);
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"090d983ec20ad09e59f6b7679b48b9b54e9c0841cf2922b81cba485edcd40876","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"1cd0ebc3b30a9c9eddb0fda5515b5a52ec2b85a087328f0ee9f4d68cbb28afc2","src/lib.rs":"f02d6e295109365cf54884e5282a3e7d1e1f62857c700f23cd013e94a56bd803","tests/xcrate.rs":"30dcb70fbb9c96fda2b7825592558279f534776f72e2a8a0a3e26df4dedb3caa"},"package":"082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"}
|
||||
{"files":{"Cargo.toml":"2cb2370b62c56a7d51b51f9e405b2f377b3ad6f7f8d33bc69e20eb819ad66012","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"2406e83ee174e30aa67f8ab266836fa78545012b196395aff37c152321e2c713","src/lib.rs":"8dfd667d32d8b06e529643c975dfa14c29ce9a894a80e381a1bd867252e65e56","tests/xcrate.rs":"c0734dae6e63beafcd60bf53546115a2320735b51035c9e2387fdf9301580934"},"package":"4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"}
|
|
@ -3,7 +3,7 @@
|
|||
# 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
|
||||
# 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
|
||||
|
@ -11,8 +11,9 @@
|
|||
# will likely look very different (and much more reasonable)
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "cfg-if"
|
||||
version = "0.1.6"
|
||||
version = "0.1.10"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
description = "A macro to ergonomically define an item depending on a large number of #[cfg]\nparameters. Structured like an if-else chain, the first matching branch is the\nitem that gets emitted.\n"
|
||||
homepage = "https://github.com/alexcrichton/cfg-if"
|
||||
|
@ -20,5 +21,16 @@ documentation = "https://docs.rs/cfg-if"
|
|||
readme = "README.md"
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/alexcrichton/cfg-if"
|
||||
[dependencies.compiler_builtins]
|
||||
version = "0.1.2"
|
||||
optional = true
|
||||
|
||||
[dependencies.core]
|
||||
version = "1.0.0"
|
||||
optional = true
|
||||
package = "rustc-std-workspace-core"
|
||||
|
||||
[features]
|
||||
rustc-dep-of-std = ["core", "compiler_builtins"]
|
||||
[badges.travis-ci]
|
||||
repository = "alexcrichton/cfg-if"
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
# cfg-if
|
||||
|
||||
[![Build Status](https://travis-ci.org/alexcrichton/cfg-if.svg?branch=master)](https://travis-ci.org/alexcrichton/cfg-if)
|
||||
|
||||
[Documentation](https://docs.rs/cfg-if)
|
||||
|
||||
A macro to ergonomically define an item depending on a large number of #[cfg]
|
||||
|
@ -16,10 +14,7 @@ cfg-if = "0.1"
|
|||
## Example
|
||||
|
||||
```rust
|
||||
#[macro_use]
|
||||
extern crate cfg_if;
|
||||
|
||||
cfg_if! {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(unix)] {
|
||||
fn foo() { /* unix specific functionality */ }
|
||||
} else if #[cfg(target_pointer_width = "32")] {
|
||||
|
@ -48,5 +43,5 @@ at your option.
|
|||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be
|
||||
for inclusion in `cfg-if` by you, as defined in the Apache-2.0 license, shall be
|
||||
dual licensed as above, without any additional terms or conditions.
|
||||
|
|
|
@ -10,10 +10,7 @@
|
|||
//! # Example
|
||||
//!
|
||||
//! ```
|
||||
//! #[macro_use]
|
||||
//! extern crate cfg_if;
|
||||
//!
|
||||
//! cfg_if! {
|
||||
//! cfg_if::cfg_if! {
|
||||
//! if #[cfg(unix)] {
|
||||
//! fn foo() { /* unix specific functionality */ }
|
||||
//! } else if #[cfg(target_pointer_width = "32")] {
|
||||
|
@ -27,39 +24,40 @@
|
|||
//! ```
|
||||
|
||||
#![no_std]
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/cfg-if")]
|
||||
#![deny(missing_docs)]
|
||||
#![cfg_attr(test, deny(warnings))]
|
||||
|
||||
#[macro_export(local_inner_macros)]
|
||||
/// The main macro provided by this crate. See crate documentation for more
|
||||
/// information.
|
||||
#[macro_export]
|
||||
macro_rules! cfg_if {
|
||||
// match if/else chains with a final `else`
|
||||
($(
|
||||
if #[cfg($($meta:meta),*)] { $($it:item)* }
|
||||
if #[cfg($($meta:meta),*)] { $($tokens:tt)* }
|
||||
) else * else {
|
||||
$($it2:item)*
|
||||
$($tokens2:tt)*
|
||||
}) => {
|
||||
cfg_if! {
|
||||
$crate::cfg_if! {
|
||||
@__items
|
||||
() ;
|
||||
$( ( ($($meta),*) ($($it)*) ), )*
|
||||
( () ($($it2)*) ),
|
||||
$( ( ($($meta),*) ($($tokens)*) ), )*
|
||||
( () ($($tokens2)*) ),
|
||||
}
|
||||
};
|
||||
|
||||
// match if/else chains lacking a final `else`
|
||||
(
|
||||
if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
|
||||
if #[cfg($($i_met:meta),*)] { $($i_tokens:tt)* }
|
||||
$(
|
||||
else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
|
||||
else if #[cfg($($e_met:meta),*)] { $($e_tokens:tt)* }
|
||||
)*
|
||||
) => {
|
||||
cfg_if! {
|
||||
$crate::cfg_if! {
|
||||
@__items
|
||||
() ;
|
||||
( ($($i_met),*) ($($i_it)*) ),
|
||||
$( ( ($($e_met),*) ($($e_it)*) ), )*
|
||||
( ($($i_met),*) ($($i_tokens)*) ),
|
||||
$( ( ($($e_met),*) ($($e_tokens)*) ), )*
|
||||
( () () ),
|
||||
}
|
||||
};
|
||||
|
@ -69,21 +67,22 @@ macro_rules! cfg_if {
|
|||
// Collects all the negated cfgs in a list at the beginning and after the
|
||||
// semicolon is all the remaining items
|
||||
(@__items ($($not:meta,)*) ; ) => {};
|
||||
(@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
|
||||
// Emit all items within one block, applying an approprate #[cfg]. The
|
||||
(@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($tokens:tt)*) ), $($rest:tt)*) => {
|
||||
// Emit all items within one block, applying an appropriate #[cfg]. The
|
||||
// #[cfg] will require all `$m` matchers specified and must also negate
|
||||
// all previous matchers.
|
||||
cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
|
||||
#[cfg(all($($m,)* not(any($($not),*))))] $crate::cfg_if! { @__identity $($tokens)* }
|
||||
|
||||
// Recurse to emit all other items in `$rest`, and when we do so add all
|
||||
// our `$m` matchers to the list of `$not` matchers as future emissions
|
||||
// will have to negate everything we just matched as well.
|
||||
cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
|
||||
$crate::cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
|
||||
};
|
||||
|
||||
// Internal macro to Apply a cfg attribute to a list of items
|
||||
(@__apply $m:meta, $($it:item)*) => {
|
||||
$(#[$m] $it)*
|
||||
// Internal macro to make __apply work out right for different match types,
|
||||
// because of how macros matching/expand stuff.
|
||||
(@__identity $($tokens:tt)*) => {
|
||||
$($tokens)*
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -139,4 +138,39 @@ mod tests {
|
|||
assert!(works4().is_some());
|
||||
assert!(works5());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::assertions_on_constants)]
|
||||
fn test_usage_within_a_function() {
|
||||
cfg_if! {if #[cfg(debug_assertions)] {
|
||||
// we want to put more than one thing here to make sure that they
|
||||
// all get configured properly.
|
||||
assert!(cfg!(debug_assertions));
|
||||
assert_eq!(4, 2+2);
|
||||
} else {
|
||||
assert!(works1().is_some());
|
||||
assert_eq!(10, 5+5);
|
||||
}}
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
fn blah(&self);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Struct;
|
||||
|
||||
impl Trait for Struct {
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "blah")] {
|
||||
fn blah(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
} else {
|
||||
fn blah(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#[macro_use]
|
||||
extern crate cfg_if;
|
||||
|
||||
cfg_if! {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(foo)] {
|
||||
fn works() -> bool { false }
|
||||
} else if #[cfg(test)] {
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"7e0306d977c63a491bea39dde354455f23c7eb283abf874d0122a664bbc082d3","README":"1ff38c3749ba83c9b364c6bb35b95525dd956449ec7386a50faf8fcfdd5a7de4","lib.rs":"3c54447b497f808ab7fa7659f1379acf4c5c3def37fc4cc7778281273b84eabb"},"package":"6626c2aef76eb8f984eef02e475883d3fe9112e114720446c5810fc5f045cd30"}
|
||||
{"files":{"CODE_OF_CONDUCT.md":"902d5357af363426631d907e641e220b3ec89039164743f8442b3f120479b7cf","Cargo.toml":"2edecc4249f6ff011255fe3c92892050e466246b23ee6d002243b0df760625c7","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README":"6f28a5c89ff7c018760402038a991a581771b8f66869268a7288f64915f192a6","lib.rs":"70f5bec52c586809882a1edce407552e8a5c3d0f126eaa92abd676484395cfc8"},"package":"704f773471ac3e7110427b6bdf93184932b19319c9b7717688da5424e519b10a"}
|
|
@ -0,0 +1,15 @@
|
|||
# Community Participation Guidelines
|
||||
|
||||
This repository is governed by Mozilla's code of conduct and etiquette guidelines.
|
||||
For more details, please read the
|
||||
[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
|
||||
|
||||
## How to Report
|
||||
For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.
|
||||
|
||||
<!--
|
||||
## Project Specific Etiquette
|
||||
|
||||
In some cases, there will be additional project etiquette i.e.: (https://bugzilla.mozilla.org/page.cgi?id=etiquette.html).
|
||||
Please update for your project.
|
||||
-->
|
|
@ -3,7 +3,7 @@
|
|||
# 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
|
||||
# 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
|
||||
|
@ -12,7 +12,7 @@
|
|||
|
||||
[package]
|
||||
name = "mp4parse_fallible"
|
||||
version = "0.0.1"
|
||||
version = "0.0.3"
|
||||
authors = ["The Servo Project Developers"]
|
||||
description = "Fallible replacement for Vec"
|
||||
documentation = "https://docs.rs/mp4parse_fallible/"
|
||||
|
|
|
@ -0,0 +1,373 @@
|
|||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
|
@ -1,5 +1,5 @@
|
|||
This is from https://github.com/servo/servo/tree/master/components/fallible
|
||||
with modificaion for mp4 demuxer.
|
||||
with modification for mp4 demuxer.
|
||||
|
||||
The purpose of this crate is to solve infallible memory allocation problem
|
||||
which causes OOM easily on win32. This is more like a temporary solution.
|
||||
|
|
|
@ -15,9 +15,17 @@ pub trait FallibleVec<T> {
|
|||
/// Err(()) if it fails, which can only be due to lack of memory.
|
||||
fn try_push(&mut self, value: T) -> Result<(), ()>;
|
||||
|
||||
/// Expand the vector size. Return Ok(()) on success, Err(()) if it
|
||||
/// fails.
|
||||
fn try_reserve(&mut self, new_cap: usize) -> Result<(), ()>;
|
||||
/// Reserves capacity for at least `additional` more elements to
|
||||
/// be inserted in the vector. Does nothing if capacity is already
|
||||
/// sufficient. Return Ok(()) on success, Err(()) if it fails either
|
||||
/// due to lack of memory, or overflowing the `usize` used to store
|
||||
/// the capacity.
|
||||
fn try_reserve(&mut self, additional: usize) -> Result<(), ()>;
|
||||
|
||||
/// Clones and appends all elements in a slice to the Vec.
|
||||
/// Returns Ok(()) on success, Err(()) if it fails, which can
|
||||
/// only be due to lack of memory.
|
||||
fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), ()> where T: Clone;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
@ -39,10 +47,21 @@ impl<T> FallibleVec<T> for Vec<T> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn try_reserve(&mut self, cap: usize) -> Result<(), ()> {
|
||||
let new_cap = cap + self.capacity();
|
||||
try_extend_vec(self, new_cap)?;
|
||||
debug_assert!(self.capacity() == new_cap);
|
||||
fn try_reserve(&mut self, additional: usize) -> Result<(), ()> {
|
||||
let available = self.capacity().checked_sub(self.len()).expect("capacity >= len");
|
||||
if additional > available {
|
||||
let increase = additional.checked_sub(available).expect("additional > available");
|
||||
let new_cap = self.capacity().checked_add(increase).ok_or(())?;
|
||||
try_extend_vec(self, new_cap)?;
|
||||
debug_assert!(self.capacity() == new_cap);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), ()> where T: Clone {
|
||||
FallibleVec::try_reserve(self, other.len())?;
|
||||
self.extend_from_slice(other);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -83,10 +102,46 @@ fn try_extend_vec<T>(vec: &mut Vec<T>, new_cap: usize) -> Result<(), ()> {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn oom_test() {
|
||||
fn oom() {
|
||||
let mut vec: Vec<char> = Vec::new();
|
||||
match vec.try_reserve(std::usize::MAX) {
|
||||
match FallibleVec::try_reserve(&mut vec, std::usize::MAX) {
|
||||
Ok(_) => panic!("it should be OOM"),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_reserve() {
|
||||
let mut vec = vec![1];
|
||||
let old_cap = vec.capacity();
|
||||
let new_cap = old_cap + 1;
|
||||
FallibleVec::try_reserve(&mut vec, new_cap).unwrap();
|
||||
assert!(vec.capacity() >= new_cap);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_reserve_idempotent() {
|
||||
let mut vec = vec![1];
|
||||
let old_cap = vec.capacity();
|
||||
let new_cap = old_cap + 1;
|
||||
FallibleVec::try_reserve(&mut vec, new_cap).unwrap();
|
||||
let cap_after_reserve = vec.capacity();
|
||||
FallibleVec::try_reserve(&mut vec, new_cap).unwrap();
|
||||
assert_eq!(cap_after_reserve, vec.capacity());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn capacity_overflow() {
|
||||
let mut vec = vec![1];
|
||||
match FallibleVec::try_reserve(&mut vec, std::usize::MAX) {
|
||||
Ok(_) => panic!("capacity calculation should overflow"),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extend_from_slice() {
|
||||
let mut vec = b"foo".to_vec();
|
||||
FallibleVec::try_extend_from_slice(&mut vec, b"bar").unwrap();
|
||||
assert_eq!(&vec, b"foobar");
|
||||
}
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,101 +0,0 @@
|
|||
language: rust
|
||||
# sudo is required to enable kcov to use the personality syscall
|
||||
sudo: required
|
||||
dist: trusty
|
||||
cache: cargo
|
||||
|
||||
rust:
|
||||
- nightly
|
||||
- beta
|
||||
- stable
|
||||
- 1.31.0
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- FEATURES='--features "regexp regexp_macros"'
|
||||
|
||||
before_script:
|
||||
- eval git pull --rebase https://github.com/Geal/nom master
|
||||
- eval git log --pretty=oneline HEAD~5..HEAD
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- rust: nightly
|
||||
env: FEATURES='--no-default-features'
|
||||
- rust: nightly
|
||||
env: FEATURES='--no-default-features --features "alloc"'
|
||||
- rust: stable
|
||||
env: FEATURES=''
|
||||
- rust: nightly
|
||||
env: DOC_FEATURES='--features "std lexical regexp regexp_macros" --no-default-features'
|
||||
before_script:
|
||||
- export PATH=$HOME/.cargo/bin:$PATH
|
||||
script:
|
||||
- eval cargo doc --verbose $DOC_FEATURES
|
||||
- rust: nightly
|
||||
env: FEATURES=''
|
||||
before_script:
|
||||
- export PATH=$HOME/.cargo/bin:$PATH
|
||||
- cargo install cargo-update || echo "cargo-update already installed"
|
||||
- cargo install cargo-travis || echo "cargo-travis already installed"
|
||||
- cargo install-update -a
|
||||
- mkdir -p target/kcov-master
|
||||
script:
|
||||
cargo coveralls --verbose --all-features
|
||||
allow_failures:
|
||||
- rust: stable
|
||||
env: FEATURES=''
|
||||
before_script:
|
||||
- export PATH=$HOME/.cargo/bin:$PATH
|
||||
- rustup component add rustfmt-preview
|
||||
script:
|
||||
- eval cargo fmt -- --write-mode=diff
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/9c035a194ac4fd4cc061
|
||||
on_success: change
|
||||
on_failure: always
|
||||
on_start: false
|
||||
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libcurl4-openssl-dev
|
||||
- libelf-dev
|
||||
- libdw-dev
|
||||
- binutils-dev
|
||||
- cmake
|
||||
sources:
|
||||
- kalakris-cmake
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- /home/travis/.cargo
|
||||
|
||||
before_cache:
|
||||
- rm -rf /home/travis/.cargo/registry
|
||||
|
||||
script:
|
||||
- eval cargo build --verbose $FEATURES
|
||||
- eval cargo test --verbose $FEATURES
|
||||
|
||||
after_success: |
|
||||
case "$TRAVIS_RUST_VERSION" in
|
||||
nightly)
|
||||
if [ "${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" != "master" ]; then
|
||||
git fetch &&
|
||||
git checkout master &&
|
||||
cargo bench --verbose
|
||||
fi
|
||||
|
||||
if [ "$FEATURES" == '--features "regexp regexp_macros"' ]; then
|
||||
cargo bench --verbose
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
;;
|
||||
esac
|
|
@ -19,7 +19,6 @@ clippy:
|
|||
- media/audioipc/
|
||||
- media/mp4parse-rust/mp4parse/
|
||||
- media/mp4parse-rust/mp4parse_capi/
|
||||
- media/mp4parse-rust/mp4parse_fallible/
|
||||
- modules/libpref/init/static_prefs/
|
||||
- mozglue/static/rust/
|
||||
- netwerk/base/mozurl/
|
||||
|
|
Загрузка…
Ссылка в новой задаче