Skip to content

Commit

Permalink
Make the write_core feature no_std compatible (#400)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinaboos committed Nov 25, 2021
1 parent ffaf0de commit 42326eb
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 30 deletions.
13 changes: 8 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ description = "A unified interface for reading and writing object file formats."
features = ['doc']

[dependencies]
crc32fast = { version = "1.2", optional = true }
crc32fast = { version = "1.2", default-features = false, optional = true }
flate2 = { version = "1", optional = true }
indexmap = { version = "1.1", optional = true }
wasmparser = { version = "0.57", optional = true }
memchr = { version = "2.4.1", default-features = false }
hashbrown = { version = "0.11", features = ["ahash"], default-features = false, optional = true }

# Internal feature, only used when building as part of libstd, not part of the
# stable interface of this crate.
Expand All @@ -34,9 +35,11 @@ read_core = []
# Read support for all file formats (including unaligned files).
read = ["read_core", "archive", "coff", "elf", "macho", "pe", "unaligned"]
# Core write support. You will need to enable some file formats too.
write_core = ["crc32fast", "indexmap/std", "std"]
# Write support for all file formats.
write = ["write_core", "coff", "elf", "macho", "pe"]
write_core = ["crc32fast", "indexmap", "hashbrown"]
# Core write support with libstd features. You will need to enable some file formats too.
write_std = ["write_core", "std", "indexmap/std", "crc32fast/std"]
# Write support for all file formats, including libstd features.
write = ["write_std", "coff", "elf", "macho", "pe"]

#=======================================
# Misc features.
Expand Down Expand Up @@ -79,7 +82,7 @@ cargo-all = []
#=======================================
# Documentation should be generated with everything in "all" except for "unaligned".
doc = [
"read_core", "write_core",
"read_core", "write_std",
"std", "compression",
"archive", "coff", "elf", "macho", "pe", "wasm",
]
Expand Down
6 changes: 3 additions & 3 deletions crates/examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ required-features = ["object/read"]

[[bin]]
name = "elfcopy"
required-features = ["object/read_core", "object/write_core", "object/elf"]
required-features = ["object/read_core", "object/write_core", "object/elf", "object/std"]

[[bin]]
name = "elftoefi"
required-features = ["object/read_core", "object/write_core", "object/elf", "object/pe"]
required-features = ["object/read_core", "object/write_core", "object/elf", "object/pe", "object/std"]

[[bin]]
name = "objcopy"
Expand All @@ -48,7 +48,7 @@ required-features = ["object/read"]

[[bin]]
name = "pecopy"
required-features = ["object/read_core", "object/write_core", "object/pe"]
required-features = ["object/read_core", "object/write_core", "object/pe", "object/std"]

[[bin]]
name = "readobj"
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
#[cfg(feature = "cargo-all")]
compile_error!("'--all-features' is not supported; use '--features all' instead");

#[cfg(feature = "read_core")]
#[cfg(any(feature = "read_core", feature = "write_core"))]
#[allow(unused_imports)]
#[macro_use]
extern crate alloc;
Expand Down
4 changes: 2 additions & 2 deletions src/write/coff.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::mem;
use std::vec::Vec;
use alloc::vec::Vec;
use core::mem;

use crate::endian::{LittleEndian as LE, U16Bytes, U32Bytes, U16, U32};
use crate::pe as coff;
Expand Down
2 changes: 1 addition & 1 deletion src/write/elf/object.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::vec::Vec;
use alloc::vec::Vec;

use crate::elf;
use crate::write::elf::writer::*;
Expand Down
6 changes: 3 additions & 3 deletions src/write/elf/writer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Helper for writing ELF files.
use std::mem;
use std::string::String;
use std::vec::Vec;
use alloc::string::String;
use alloc::vec::Vec;
use core::mem;

use crate::elf;
use crate::endian::*;
Expand Down
2 changes: 1 addition & 1 deletion src/write/macho.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::mem;
use core::mem;

use crate::endian::*;
use crate::macho;
Expand Down
16 changes: 10 additions & 6 deletions src/write/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! Interface for writing object files.

use std::borrow::Cow;
use std::boxed::Box;
use std::collections::HashMap;
use std::string::String;
use std::vec::Vec;
use std::{error, fmt, io, result, str};
use alloc::borrow::Cow;
use alloc::string::String;
use alloc::vec::Vec;
use core::{fmt, result, str};
#[cfg(not(feature = "std"))]
use hashbrown::HashMap;
#[cfg(feature = "std")]
use std::{boxed::Box, collections::HashMap, error, io};

use crate::endian::{Endianness, U32, U64};
use crate::{
Expand Down Expand Up @@ -42,6 +44,7 @@ impl fmt::Display for Error {
}
}

#[cfg(feature = "std")]
impl error::Error for Error {}

/// The result type used within the write module.
Expand Down Expand Up @@ -551,6 +554,7 @@ impl<'a> Object<'a> {
///
/// It is advisable to use a buffered writer like [`BufWriter`](std::io::BufWriter)
/// instead of an unbuffered writer like [`File`](std::fs::File).
#[cfg(feature = "std")]
pub fn write_stream<W: io::Write>(&self, w: W) -> result::Result<(), Box<dyn error::Error>> {
let mut stream = StreamingBuffer::new(w);
self.emit(&mut stream)?;
Expand Down
6 changes: 3 additions & 3 deletions src/write/pe.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Helper for writing PE files.
use std::mem;
use std::string::String;
use std::vec::Vec;
use alloc::string::String;
use alloc::vec::Vec;
use core::mem;

use crate::endian::{LittleEndian as LE, *};
use crate::pe;
Expand Down
8 changes: 6 additions & 2 deletions src/write/string.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use indexmap::IndexSet;
use std::vec::Vec;
use alloc::vec::Vec;

#[cfg(feature = "std")]
type IndexSet<K> = indexmap::IndexSet<K>;
#[cfg(not(feature = "std"))]
type IndexSet<K> = indexmap::IndexSet<K, hashbrown::hash_map::DefaultHashBuilder>;

/// An identifer for an entry in a string table.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down
9 changes: 6 additions & 3 deletions src/write/util.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::io;
use std::mem;
use std::vec::Vec;
use alloc::vec::Vec;
#[cfg(feature = "std")]
use std::{io, mem};

use crate::pod::{bytes_of, bytes_of_slice, Pod};

Expand Down Expand Up @@ -86,13 +86,15 @@ impl WritableBuffer for Vec<u8> {
///
/// It is advisable to use a buffered writer like [`BufWriter`](std::io::BufWriter)
/// instead of an unbuffered writer like [`File`](std::fs::File).
#[cfg(feature = "std")]
#[derive(Debug)]
pub struct StreamingBuffer<W> {
writer: W,
len: usize,
result: Result<(), io::Error>,
}

#[cfg(feature = "std")]
impl<W> StreamingBuffer<W> {
/// Create a new `StreamingBuffer` backed by the given writer.
pub fn new(writer: W) -> Self {
Expand All @@ -114,6 +116,7 @@ impl<W> StreamingBuffer<W> {
}
}

#[cfg(feature = "std")]
impl<W: io::Write> WritableBuffer for StreamingBuffer<W> {
#[inline]
fn len(&self) -> usize {
Expand Down

0 comments on commit 42326eb

Please sign in to comment.