Compare commits

...

3 Commits

Author SHA1 Message Date
an 92aea23e04 maraiah: make checkdata not a macro 2019-06-18 01:42:17 -04:00
an 17b5456aca maraiah: more documentation 2019-06-18 01:40:39 -04:00
an e64f652281 tycho: organize better 2019-06-17 07:15:26 -04:00
17 changed files with 155 additions and 66 deletions

View File

@ -9,13 +9,7 @@ is derived from the Japanese transliteration of "Mariah," and is pronounced
The basis of this project is the Rust project `maraiah` which provides functions The basis of this project is the Rust project `maraiah` which provides functions
and structures to build applications which work with Marathon's data. and structures to build applications which work with Marathon's data.
Maraiah comes with a set of almost fully portable tools written in Rust, See [the crate documentation](source/lib.rs) for more information.
including binary file reading, safe C-like `enum` reading, improved error
handling, FFI tools, fixed point numbers, and image and sound structures.
Maraiah also comes with APIs for working with various data formats, primarily
Marathon's. It also handles Macintosh PICT files, Portable PixMap, TARGA, RIFF
WAVE, and more.
## `maraiah-leela` ## `maraiah-leela`

View File

@ -160,6 +160,9 @@ macro_rules! rd_impl {
/// ``` /// ```
/// # #[macro_use] extern crate maraiah; /// # #[macro_use] extern crate maraiah;
/// # use maraiah::err::*; /// # use maraiah::err::*;
/// #
/// # fn main() -> ResultS<()>
/// # {
/// let buffer = &[4, 0, 2, 0, 0, 0, 6]; /// let buffer = &[4, 0, 2, 0, 0, 0, 6];
/// ///
/// read_data! { /// read_data! {
@ -176,6 +179,7 @@ macro_rules! rd_impl {
/// assert_eq!(six, 6_u8); /// assert_eq!(six, 6_u8);
/// assert_eq!(byte, &[2, 0, 0, 0]); /// assert_eq!(byte, &[2, 0, 0, 0]);
/// # Ok(()) /// # Ok(())
/// # }
/// ``` /// ```
#[macro_export] #[macro_export]
macro_rules! read_data { macro_rules! read_data {
@ -185,20 +189,24 @@ macro_rules! read_data {
$($ex:ident$(::$exc:ident)*)*;)* $($ex:ident$(::$exc:ident)*)*;)*
} }
) => { ) => {
$crate::check_data!($at + $sz, $b); $crate::bin::check_data($b, $at + $sz)?;
$($crate::rd_impl!($e, $b, $at, $n; $($crate::rd_impl!($e, $b, $at, $n;
$($rn;)? $nam, $($ex$(::$exc)*,)* $t$(::$tc)*);)* $($rn;)? $nam, $($ex$(::$exc)*,)* $t$(::$tc)*);)*
}; };
} }
/// Checks if there is enough data in `b`. /// Checks if there is enough data in `b`.
#[macro_export] ///
macro_rules! check_data { /// # Errors
($sz:expr, $b:expr) => { ///
if $b.len() < $sz { /// Returns `Err` if `b.len()` is less than `sz`.
return Err(err_msg("not enough data")); pub fn check_data(b: &[u8], sz: usize) -> ResultS<()>
} {
}; if b.len() < sz {
Err(err_msg("not enough data"))
} else {
Ok(())
}
} }
/// Casts a `u32` to a `usize`. /// Casts a `u32` to a `usize`.
@ -417,7 +425,7 @@ pub fn rd_ofstable<T, F>(b: &[u8],
for _ in 0..num { for _ in 0..num {
let ofs = usize_from_u32(u32b(&b[p..p + 4])); let ofs = usize_from_u32(u32b(&b[p..p + 4]));
check_data!(ofs, b); check_data(b, ofs)?;
v.push(read(&b[ofs..])?); v.push(read(&b[ofs..])?);
p += 4; p += 4;
} }

View File

@ -1,10 +1,10 @@
#![doc(hidden)] #![doc(hidden)]
/// Creates an enumeration and function for converting a representation into /// Creates an enumeration and function for converting a representation into the
/// the enumeration type. /// enumeration type.
/// ///
/// The syntax is similar to the `bitflags` macro, but each value has the /// The syntax is similar to the `bitflags` macro, but each value has the syntax
/// syntax `value => enumeration`. `enum` is used instead of `struct`. /// `value = enumeration`. `enum` is used instead of `struct`.
/// ///
/// This will generate an `enum $t` as well as implement `TryFrom` on it which /// This will generate an `enum $t` as well as implement `TryFrom` on it which
/// will return `Result<$t, ReprError>`. /// will return `Result<$t, ReprError>`.
@ -39,7 +39,7 @@ macro_rules! c_enum
$(#[$outer:meta])* $(#[$outer:meta])*
$vi:vis enum $t:ident: $ti:ident $vi:vis enum $t:ident: $ti:ident
{ {
$($en:ident = $va:expr),+ $(,)? $($(#[$vouter:meta])* $en:ident = $va:expr),+ $(,)?
} }
) => { ) => {
$(#[$outer])* $(#[$outer])*
@ -47,7 +47,7 @@ macro_rules! c_enum
#[repr($ti)] #[repr($ti)]
$vi enum $t $vi enum $t
{ {
$($en = $va,)+ $($(#[$vouter])* $en = $va,)+
} }
#[allow(unused_qualifications)] #[allow(unused_qualifications)]

View File

@ -1,6 +1,6 @@
//! DEFLATE loader. //! DEFLATE loader.
use crate::{bit::*, err::*}; use crate::{bin::check_data, bit::*, err::*};
use std::cmp::Ordering; use std::cmp::Ordering;
/// Loads a ZLIB file header. /// Loads a ZLIB file header.
@ -76,7 +76,7 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS<usize>
p += 2 + xlen; p += 2 + xlen;
check_data!(p, b); check_data(b, p)?;
} }
if fl & FNAME != 0 { if fl & FNAME != 0 {
@ -90,7 +90,7 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS<usize>
if fl & FHCRC != 0 { if fl & FHCRC != 0 {
p += 2; p += 2;
check_data!(p, b); check_data(b, p)?;
} }
Ok(p) Ok(p)

22
source/doc.rs Normal file
View File

@ -0,0 +1,22 @@
#![doc(hidden)]
/// Macro-izes `#[doc = x]`.
///
/// # Examples
///
/// ```
/// use maraiah::doc_comment;
///
/// doc_comment! {
/// concat!("Have a nice", " day", "!"),
/// const A: u32 = 5;
/// }
///
/// assert_eq!(A, 5);
/// ```
#[macro_export]
macro_rules! doc_comment {
($x:expr, $($tt:tt)*) => {#[doc = $x] $($tt)*}
}
// EOF

View File

@ -1,11 +1,27 @@
//! Foreign function interface utilities. //! Foreign function interface utilities.
use crate::err::*; use crate::err::*;
pub use std::{ffi::*,
os::raw::*, pub use std::{ffi::*, os::raw::*, ptr::{null, null_mut}};
ptr::{null, null_mut}};
/// Creates a C string from a literal. /// Creates a C string from a literal.
///
/// This is done by concatenating a null byte with the string and converting it
/// to a pointer.
///
/// # Examples
///
/// ```
/// use maraiah::c_str;
///
/// let st = c_str!("test");
///
/// assert!(!st.is_null());
///
/// unsafe {
/// assert_eq!(std::slice::from_raw_parts(st, 5), &[116, 101, 115, 116, 0]);
/// }
/// ```
#[macro_export] #[macro_export]
macro_rules! c_str { macro_rules! c_str {
($s:expr) => { ($s:expr) => {
@ -13,9 +29,17 @@ macro_rules! c_str {
}; };
} }
/// Returns [`null`] as a [`*const c_void`].
///
/// [`null`]: fn.null.html
/// [`*const c_void`]: enum.c_void.html
#[inline] #[inline]
pub const fn null_void() -> *const c_void {null()} pub const fn null_void() -> *const c_void {null()}
/// Returns [`null_mut`] as a [`*mut c_void`].
///
/// [`null_mut`]: fn.null_mut.html
/// [`*mut c_void`]: enum.c_void.html
#[inline] #[inline]
pub const fn null_mut_void() -> *mut c_void {null_mut()} pub const fn null_mut_void() -> *mut c_void {null_mut()}

View File

@ -1,3 +1,19 @@
//! This is the base library for the Maraiah tool set. This library contains
//! functions and structures for reading many file formats, primarily those used
//! by Marathon, Marathon 2, and Marathon Infinity.
//!
//! Maraiah comes with a set of almost fully portable tools written in Rust,
//! including binary file reading, safe C-like `enum` reading, improved error
//! handling, FFI tools, fixed point numbers, and image and sound structures.
//!
//! Maraiah also comes with APIs for working with various data formats,
//! primarily Marathon's. It also handles Macintosh PICT files, Portable PixMap,
//! TARGA, RIFF WAVE, and more.
//!
//! # Features
//!
//! Maraiah supports serializing and deserializing through `serde` with the
//! `serde_obj` feature.
#![deny(anonymous_parameters)] #![deny(anonymous_parameters)]
#![deny(bare_trait_objects)] #![deny(bare_trait_objects)]
#![deny(elided_lifetimes_in_paths)] #![deny(elided_lifetimes_in_paths)]
@ -47,12 +63,14 @@
#![deny(clippy::use_self)] #![deny(clippy::use_self)]
#![deny(clippy::used_underscore_binding)] #![deny(clippy::used_underscore_binding)]
#[macro_use]
mod doc;
#[macro_use] #[macro_use]
pub mod ffi; pub mod ffi;
#[macro_use] #[macro_use]
pub mod err; pub mod err;
#[macro_use] #[macro_use]
pub mod cenum; mod cenum;
#[macro_use] #[macro_use]
pub mod bin; pub mod bin;

View File

@ -1,11 +1,11 @@
//! `iidx` chunk. //! `iidx` chunk.
use crate::{bin::u16b, err::*}; use crate::{bin::{check_data, u16b}, err::*};
/// Reads an `iidx` chunk. /// Reads an `iidx` chunk.
pub fn read(b: &[u8]) -> ResultS<(u16, usize)> pub fn read(b: &[u8]) -> ResultS<(u16, usize)>
{ {
check_data!(2, b); check_data(b, 2)?;
Ok((u16b(b), 2)) Ok((u16b(b), 2))
} }

View File

@ -1,28 +1,51 @@
//! Meta-information of this crate. //! Meta-information of this crate.
use crate::ffi;
macro_rules! meta_str { macro_rules! meta_str {
($($name:ident = $cname:ident = $e:expr;)*) => { ($($(#[$outer:meta])* $name:ident = $cname:ident = $e:expr;)*) => {
$( $(
pub const $name: &'static str = $e; $(#[$outer])* pub const $name: &'static str = $e;
pub const $cname: ffi::NT = c_str!($e);
)* )*
pub mod ffi
{
$(
doc_comment! {
concat!("FFI variant of [`",
stringify!($name),
"`]\n\n[`",
stringify!($name),
"`]: ../constant.",
stringify!($name),
".html"),
pub const $cname: crate::ffi::NT = c_str!($e);
}
)*
}
} }
} }
meta_str!( meta_str!(
AUTHORS = C_AUTHORS = env!("CARGO_PKG_AUTHORS"); /// The authors of this crate, `:` separated.
DESCRIPTION = C_DESCRIPTION = env!("CARGO_PKG_DESCRIPTION"); AUTHORS = AUTHORS_C = env!("CARGO_PKG_AUTHORS");
HOMEPAGE = C_HOMEPAGE = env!("CARGO_PKG_HOMEPAGE"); /// The description of this crate.
LICENSE_TEXT = C_LICENSE_TEXT = include_str!("../LICENSE"); DESCRIPTION = DESCRIPTION_C = env!("CARGO_PKG_DESCRIPTION");
NAME = C_NAME = env!("CARGO_PKG_NAME"); /// The home page of this crate.
REPOSITORY = C_REPOSITORY = env!("CARGO_PKG_REPOSITORY"); HOMEPAGE = HOMEPAGE_C = env!("CARGO_PKG_HOMEPAGE");
VERSION = C_VERSION = env!("CARGO_PKG_VERSION"); /// The full license text of this crate.
VERSION_MAJOR = C_VERSION_MAJOR = env!("CARGO_PKG_VERSION_MAJOR"); LICENSE_TEXT = LICENSE_TEXT_C = include_str!("../LICENSE");
VERSION_MINOR = C_VERSION_MINOR = env!("CARGO_PKG_VERSION_MINOR"); /// The name of this crate.
VERSION_PATCH = C_VERSION_PATCH = env!("CARGO_PKG_VERSION_PATCH"); NAME = NAME_C = env!("CARGO_PKG_NAME");
VERSION_PRE = C_VERSION_PRE = env!("CARGO_PKG_VERSION_PRE"); /// The repository of this crate.
REPOSITORY = REPOSITORY_C = env!("CARGO_PKG_REPOSITORY");
/// The full version of this crate.
VERSION = VERSION_C = env!("CARGO_PKG_VERSION");
/// The major version of this crate.
VERSION_MAJOR = VERSION_MAJOR_C = env!("CARGO_PKG_VERSION_MAJOR");
/// The minor version of this crate.
VERSION_MINOR = VERSION_MINOR_C = env!("CARGO_PKG_VERSION_MINOR");
/// The patch version of this crate.
VERSION_PATCH = VERSION_PATCH_C = env!("CARGO_PKG_VERSION_PATCH");
/// The pre-release version of this crate.
VERSION_PRE = VERSION_PRE_C = env!("CARGO_PKG_VERSION_PRE");
); );
// EOF // EOF

View File

@ -2,8 +2,8 @@
"cppFile": "", "cppFile": "",
"rust": { "rust": {
"dir": "", "dir": "",
"interfaceModule": "qintr", "interfaceModule": "ffi",
"implementationModule": "qimpl" "implementationModule": "gui"
}, },
"objects": { "objects": {
"MapModel": { "MapModel": {

View File

@ -21,7 +21,7 @@ ProjectModel::ProjectModel(ProjectModel &&o) :
ProjectModel::~ProjectModel() ProjectModel::~ProjectModel()
{ {
switch(modelType) { switch(modelType) {
case Map: delete modelMap; case Map: delete modelMap; break;
} }
} }

View File

@ -0,0 +1,8 @@
//! GUI implementation.
mod ffi;
mod map;
pub use self::map::MapModel;
// EOF

View File

@ -4,6 +4,6 @@
use maraiah::ffi as libc; use maraiah::ffi as libc;
include!(concat!(env!("OUT_DIR"), "/src/qintr.rs")); include!(concat!(env!("OUT_DIR"), "/src/ffi.rs"));
// EOF // EOF

View File

@ -1,6 +1,6 @@
//! Map model. //! Map model.
use crate::qintr::*; use super::ffi::*;
//use memmap::Mmap; //use memmap::Mmap;
use maraiah::map; use maraiah::map;

View File

@ -1,8 +1,7 @@
use maraiah::{err::*, ffi}; use maraiah::{err::*, ffi};
mod gui;
mod meta; mod meta;
mod qimpl;
mod qintr;
extern "C" { extern "C" {
fn main_cc(app_name: *mut ffi::c_char); fn main_cc(app_name: *mut ffi::c_char);

View File

@ -15,11 +15,11 @@ macro_rules! meta_str {
} }
meta_str!( meta_str!(
tychoAuthors = meta::C_AUTHORS; tychoAuthors = meta::ffi::AUTHORS_C;
tychoHomepage = meta::C_HOMEPAGE; tychoHomepage = meta::ffi::HOMEPAGE_C;
tychoLicenseText = meta::C_LICENSE_TEXT; tychoLicenseText = meta::ffi::LICENSE_TEXT_C;
tychoRepository = meta::C_REPOSITORY; tychoRepository = meta::ffi::REPOSITORY_C;
tychoVersion = meta::C_VERSION; tychoVersion = meta::ffi::VERSION_C;
); );
// EOF // EOF

View File

@ -1,7 +0,0 @@
//! Qt implementation.
mod map;
pub use self::map::*;
// EOF