Skip to content

Commit

Permalink
Merge pull request #68 from jubako/python_32bits
Browse files Browse the repository at this point in the history
  • Loading branch information
mgautierfr authored Oct 10, 2024
2 parents e9a62d8 + 68350f1 commit 0b05a63
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 24 deletions.
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ homepage = "https://github.com/jubako/arx"
license = "MIT"

[workspace.dependencies]
jbk = { git = "https://github.com/jubako/jubako.git", package = "jubako", version = "0.3.1" }
jbk = { git = "https://github.com/jubako/jubako.git", package = "jubako", version = "0.3.2-dev" }
clap = { version = "4.4.5", features = ["derive"] }
clap_mangen = "0.2.20"
clap_complete = "4.5.0"
Expand Down
24 changes: 6 additions & 18 deletions python/src/arx.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::sync::Arc;

use crate::iterator::EntryIter;
use crate::stream::Stream;

use super::content_address::ContentAddress;
use super::entry::Entry;
Expand All @@ -10,7 +11,6 @@ use pyo3::exceptions::PyRuntimeError;
use pyo3::exceptions::{PyOSError, PyUnicodeDecodeError, PyValueError};
use pyo3::prelude::*;
use pyo3::types::PyUnicode;
use std::io::Read;

/// An Arx archive.
///
Expand Down Expand Up @@ -48,21 +48,13 @@ impl Arx {
Self(Arc::new(arx))
}

pub(crate) fn get_content_rust<'py>(
pub(crate) fn get_content_rust(
arx: &arx::Arx,
py: Python<'py>,
content: jbk::ContentAddress,
) -> PyResult<&'py pyo3::types::PyBytes> {
) -> PyResult<Stream> {
let bytes = arx.container.get_bytes(content).unwrap();
match bytes {
MayMissPack::FOUND(bytes) => {
let mut stream = bytes.stream();
let read = |slice: &mut [u8]| {
stream.read_exact(slice).unwrap();
Ok(())
};
pyo3::types::PyBytes::new_with(py, bytes.size().into_usize(), read)
}
MayMissPack::FOUND(bytes) => Ok(Stream(bytes.stream())),
MayMissPack::MISSING(pack_info) => Err(PyOSError::new_err(format!(
"Cannot found pack {}",
pack_info.uuid
Expand Down Expand Up @@ -102,12 +94,8 @@ impl Arx {
}

/// Get the content associated to contentAddress
fn get_content<'py>(
&self,
py: Python<'py>,
content: ContentAddress,
) -> PyResult<&'py pyo3::types::PyBytes> {
Self::get_content_rust(self, py, content.0)
fn get_content(&self, content: ContentAddress) -> PyResult<Stream> {
Self::get_content_rust(self, content.0)
}

fn __iter__(slf: PyRef<'_, Self>) -> PyResult<Py<EntryIter>> {
Expand Down
6 changes: 3 additions & 3 deletions python/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use pyo3::{
prelude::*,
};

use crate::{content_address::ContentAddress, iterator::EntryIter};
use crate::{content_address::ContentAddress, iterator::EntryIter, stream::Stream};

/// An entry i an arx archive.
///
Expand Down Expand Up @@ -148,9 +148,9 @@ impl Entry {
/// Get the content of the file entry.
///
/// Raise an exception if entry is not a file.
fn get_content<'py>(&self, py: Python<'py>) -> PyResult<&'py pyo3::types::PyBytes> {
fn get_content(&self) -> PyResult<Stream> {
match &self.entry {
arx::Entry::File(f) => super::arx::Arx::get_content_rust(&self.arx, py, f.content()),
arx::Entry::File(f) => super::arx::Arx::get_content_rust(&self.arx, f.content()),
_ => Err(PyTypeError::new_err("Not a file")),
}
}
Expand Down
1 change: 1 addition & 0 deletions python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod content_address;
mod creator;
mod entry;
mod iterator;
mod stream;
use pyo3::prelude::*;

/// A Python module implemented in Rust.
Expand Down
38 changes: 38 additions & 0 deletions python/src/stream.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use jbk::reader::ByteStream;
use pyo3::prelude::*;
use std::io::Read;

#[pyclass]
pub struct Stream(pub ByteStream);

#[pymethods]
impl Stream {
/// Read `size` bytes from the stream.
///
/// Returned `bytes` may be shorter than `size` if data left to be read is smaller than requested.
fn read<'py>(&mut self, py: Python<'py>, size: usize) -> PyResult<&'py pyo3::types::PyBytes> {
let size = std::cmp::min(size, self.0.size_left() as usize);
let read_fn = |slice: &mut [u8]| {
self.0.read_exact(slice).unwrap();
Ok(())
};
pyo3::types::PyBytes::new_with(py, size, read_fn)
}

/// Get the full size of the stream.
fn size(&self) -> u64 {
self.0.size()
}

/// Get the size of the data left to read.
///
/// Equivalent to `size() - tell()`
fn size_left(&self) -> u64 {
self.0.size_left()
}

/// Get the current offset (already read data) of the stream.
fn tell(&self) -> u64 {
self.0.offset()
}
}

0 comments on commit 0b05a63

Please sign in to comment.