Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions crates/bridge_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,11 @@ impl<'a> CoreBridgeState<'a> {
rhandle.read_exact(buf).map_err(Error::from)
}

fn input_read_partial(&mut self, handle: *mut InputHandle, buf: &mut [u8]) -> Result<usize> {
let rhandle: &mut InputHandle = unsafe { &mut *handle };
rhandle.read(buf).map_err(Error::from)
}

fn input_getc(&mut self, handle: *mut InputHandle) -> Result<u8> {
let rhandle: &mut InputHandle = unsafe { &mut *handle };
rhandle.getc()
Expand Down Expand Up @@ -1181,6 +1186,9 @@ pub extern "C" fn ttbc_input_ungetc(

/// Read data from a Tectonic input handle
///
/// This read corresponds to Rust's read_exact, i.e. it will return exactly the number of requested
/// bytes or error (-1).
///
/// # Safety
///
/// This function is unsafe because it dereferences raw C pointers.
Expand All @@ -1202,6 +1210,32 @@ pub unsafe extern "C" fn ttbc_input_read(
}
}

/// Read data from a Tectonic input handle
///
/// This read corresponds to Rust's read, i.e. it can return less bytes than requested (and does
/// when buffering)
///
/// # Safety
///
/// This function is unsafe because it dereferences raw C pointers.
#[no_mangle]
pub unsafe extern "C" fn ttbc_input_read_partial(
es: &mut CoreBridgeState,
handle: *mut InputHandle,
data: *mut u8,
len: libc::size_t,
) -> libc::ssize_t {
let rdata = slice::from_raw_parts_mut(data, len);

match es.input_read_partial(handle, rdata) {
Ok(size) => size as isize,
Err(e) => {
tt_warning!(es.status, "{}-byte read failed", len; e);
-1
}
}
}

/// Close a Tectonic input file.
#[no_mangle]
pub extern "C" fn ttbc_input_close(
Expand Down
5 changes: 5 additions & 0 deletions crates/bridge_core/support/support.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@ ttstub_input_read(rust_input_handle_t handle, char *data, size_t len)
return ttbc_input_read(tectonic_global_bridge_core, handle, (uint8_t *) data, len);
}

ssize_t
ttstub_input_read_partial(rust_input_handle_t handle, char *data, size_t len)
{
return ttbc_input_read_partial(tectonic_global_bridge_core, handle, (uint8_t *) data, len);
}

int
ttstub_input_getc(rust_input_handle_t handle)
Expand Down
1 change: 1 addition & 0 deletions crates/bridge_core/support/tectonic_bridge_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ size_t ttstub_input_get_size(rust_input_handle_t handle);
time_t ttstub_input_get_mtime(rust_input_handle_t handle);
size_t ttstub_input_seek(rust_input_handle_t handle, ssize_t offset, int whence);
ssize_t ttstub_input_read(rust_input_handle_t handle, char *data, size_t len);
ssize_t ttstub_input_read_partial(rust_input_handle_t handle, char *data, size_t len);
int ttstub_input_getc(rust_input_handle_t handle);
int ttstub_input_ungetc(rust_input_handle_t handle, int ch);
int ttstub_input_close(rust_input_handle_t handle);
Expand Down
2 changes: 2 additions & 0 deletions crates/bridge_core/support/tectonic_bridge_core_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ int ttbc_input_ungetc(ttbc_state_t *es, ttbc_input_handle_t *handle, int ch);
*/
ssize_t ttbc_input_read(ttbc_state_t *es, ttbc_input_handle_t *handle, uint8_t *data, size_t len);

ssize_t ttbc_input_read_partial(ttbc_state_t *es, ttbc_input_handle_t *handle, uint8_t *data, size_t len);

/**
* Close a Tectonic input file.
*/
Expand Down
2 changes: 1 addition & 1 deletion crates/pdf_io/pdf_io/dpx-spc_pdfm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1664,7 +1664,7 @@ spc_handler_pdfm_stream_with_type (struct spc_env *spe, struct spc_arg *args, in
}
fstream = pdf_new_stream(STREAM_COMPRESS);
while ((nb_read =
ttstub_input_read(handle, work_buffer, WORK_BUFFER_SIZE)) > 0)
ttstub_input_read_partial(handle, work_buffer, WORK_BUFFER_SIZE)) > 0)
pdf_add_stream(fstream, work_buffer, nb_read);
ttstub_input_close(handle);
break;
Expand Down
11 changes: 11 additions & 0 deletions tests/tex-outputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,3 +363,14 @@ fn xetex_g_builtins() {
fn xetex_ot_builtins() {
TestCase::new("xetex_ot_builtins").check_pdf(true).go()
}

#[test]
fn pdf_fstream() {
// Need to do this here since we call test_path unusually early.
util::set_test_root();

TestCase::new("pdf_fstream")
.with_fs(&test_path(&["tex-outputs"]))
.check_pdf(true)
.go()
}
3 changes: 3 additions & 0 deletions tests/tex-outputs/pdf_fstream.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**
(pdf_fstream.tex [1] )
Output written on pdf_fstream.xdv (1 page, 588 bytes).
Binary file added tests/tex-outputs/pdf_fstream.pdf
Binary file not shown.
22 changes: 22 additions & 0 deletions tests/tex-outputs/pdf_fstream.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
\special{dvipdfmx:config C 0x40} % don't use object streams
\special{dvipdfmx:config z 0} % don't use compression

\special{pdf:fstream @SourceFile (\jobname.tex)}
\special{pdf:ann width 10bp height 20bp
<<
/Type /Annot
/Subtype /FileAttachment
/FS <<
/Type /Filespec
/F (\jobname.tex)
/EF << /F @SourceFile >>
>>
/Name /PushPin
/C [0.8 0.2 0.2]
/T (Source code of this document)
/Subj (Source code of this document)
/Contents (Source code of this document)
>>
}

\bye
Binary file added tests/tex-outputs/pdf_fstream.xdv
Binary file not shown.
Loading