Struct DATFile

Source
pub struct DATFile { /* private fields */ }
Expand description

A reference to an open DAT file on the system. This emulates the standard lib std::fs::File but provides additional DAT-specific functionality.

Reads and writes to DAT files are performed only on the data contents of the file. XOR masks are automatically applied as necessary.

§Examples

use libxivdat::dat_file::DATFile;
use libxivdat::dat_type::DATType;
use std::io::Read;

let mut dat_file = match DATFile::open("./resources/TEST_XOR.DAT") {
    Ok(dat_file) => dat_file,
    Err(_) => panic!("Something broke!")
};

match dat_file.file_type() {
    DATType::Macro => {
        let mut macro_bytes = vec![0u8; dat_file.content_size() as usize - 1];
        match dat_file.read(&mut macro_bytes) {
            Ok(count) => println!("Read {} bytes.", count),
            Err(_) => panic!("Reading broke!")
        }
    },
    _ => panic!("Not a macro file!")
};

Implementations§

Source§

impl DATFile

Source

pub fn content_size(&self) -> u32

Returns the size of the current content contained in the DAT file. DAT files store content as a null-terminated CString, so this size is one byte larger than the actual content.

§Examples
use libxivdat::dat_file::DATFile;

let mut dat_file = DATFile::open("./resources/TEST.DAT").unwrap();
let content_size = dat_file.content_size();
Source

pub fn create<P: AsRef<Path>>( path: P, dat_type: DATType, ) -> Result<Self, DATError>

Creates a new DAT file with an empty content block in read/write mode. This will truncate an existing file if one exists at the specified path.

By default, this will use the default max size for the specified type from get_default_max_size_for_type() and default header ending from get_default_end_byte_for_type(). To cicumvent this behavior, you can use create_unsafe(). Note that DAT files with nonstandard sizes may produce undefined behavior in the game client.

§Errors

If an I/O error creating the file occurs, a DATError::FileIO error will be returned wrapping the underlying FS error.

§Examples
use libxivdat::dat_file::DATFile;
use libxivdat::dat_type::DATType;

let mut dat_file = DATFile::create(&path, DATType::Macro);
Source

pub fn create_unsafe<P: AsRef<Path>>( path: P, dat_type: DATType, content_size: u32, max_size: u32, end_byte: u8, ) -> Result<Self, DATError>

Creates a new DAT file with a null-padded content bock of the specifed size in read/write mode. This will truncate an existing file if one exists at the specified path.

This function allows a custom, not-necessarily-valid maximum length and end byte to be set. Note that DAT files with nonstandard sizes and headers may produce undefined behavior in the game client.

§Errors

If an I/O error creating the file occurs, a DATError::FileIO error will be returned wrapping the underlying FS error.

§Examples
use libxivdat::dat_file::DATFile;
use libxivdat::dat_type::DATType;


// Create an empty (content length 1) macro file with a custom max size and end byte. This probably isn't valid.
let mut dat_file = DATFile::create_unsafe(&path, DATType::Macro, 1, 1024, 0x01);
Source

pub fn create_with_content<P: AsRef<Path>>( path: P, dat_type: DATType, content: &[u8], ) -> Result<Self, DATError>

Creates a new DAT file with a specific content block in read/write mode. This will truncate an existing file if one exists at the specified path.

This is shorthand for creating the DAT file, then calling write(). This function also resets the cursor to the beginning of the content block after writing.

By default, this will use the default max size for the specified type from get_default_max_size_for_type() and default header ending from get_default_end_byte_for_type(). To cicumvent this behavior, you can use create_unsafe(). Note that DAT files with nonstandard sizes may produce undefined behavior in the game client.

§Errors

If an I/O error creating the file occurs, a DATError::FileIO error will be returned wrapping the underlying FS error.

A DATError::Overflow is returned if the provided content size is too large, or if the content size exceeds the maximum size.

§Examples
use libxivdat::dat_file::DATFile;
use libxivdat::dat_type::DATType;


let mut dat_file = DATFile::create_with_content(&path, DATType::Macro, b"Not really a macro.");
Source

pub fn file_type(&self) -> DATType

Returns the file type of the DAT file.

§Examples
use libxivdat::dat_file::DATFile;
use libxivdat::dat_type::DATType;

let mut dat_file = DATFile::open("./resources/TEST_XOR.DAT").unwrap();
match dat_file.file_type() {
    DATType::Macro => println!("Macro file!"),
    _ => panic!("Nope!")
}
Source

pub fn header_end_byte(&self) -> u8

Returns the terminating byte of the DAT file’s header. The purpose of this byte is unknown, but it is almost always 0xFF.

§Examples
use libxivdat::dat_file::DATFile;

let mut dat_file = DATFile::open("./resources/TEST_XOR.DAT").unwrap();
let header_end_byte = dat_file.header_end_byte();
Source

pub fn max_size(&self) -> u32

Returns the maximum size allowed for the content block of the DAT file. Content is stored as a null-terminated CString, so the actual maximum allowed content is 1 byte less than max_size.

§Examples
use libxivdat::dat_file::DATFile;

let mut dat_file = DATFile::open("./resources/TEST_XOR.DAT").unwrap();
let header_end_byte = dat_file.max_size();
Source

pub fn metadata(&self) -> Result<Metadata, DATError>

Calls metadata() on the underlying std::fs::File.

§Errors

This function will return any underling I/O errors as a DATError::FileIO.

Source

pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, DATError>

Attempts to open a DAT file in read-only mode. To set different file access with OpenOptions, use open_options()

§Errors

If an I/O error opening the file occurs, a DATError::FileIO error will be returned wrapping the underlying FS error.

A DATError::BadHeader will be returned if the header cannot be validated, indicating a non-DAT or corrupt file.

§Examples
use libxivdat::dat_file::DATFile;

let mut dat_file = DATFile::open("./resources/TEST.DAT");
Source

pub fn open_options<P: AsRef<Path>>( path: P, options: &mut OpenOptions, ) -> Result<Self, DATError>

Attempts to open a DAT file using an OpenOptions builder. A reference to the OpenOptions struct itself should be passed in, not the File it opens. Do not end the options chain with open("foo.txt") as with opening a standard file.

§Errors

If an I/O error opening the file occurs, a DATError::FileIO error will be returned wrapping the underlying FS error.

A DATError::BadHeader will be returned if the header cannot be validated, indicating a non-DAT or corrupt file.

§Examples
use libxivdat::dat_file::DATFile;
use std::fs::OpenOptions;

let mut open_opts = OpenOptions::new();
open_opts.read(true).write(true);
let mut dat_file = DATFile::open_options("./resources/TEST.DAT", &mut open_opts);
Source

pub fn set_content_size(&mut self, new_size: u32) -> Result<(), DATError>

Truncates or extends the readable content section of the DAT file. This emulates the behavior of std::fs::File::set_len(), but only operates on the content region of the DAT file. Because DAT files store content as null-terminated CStrings, the actual writeable space will be one byte less than specified.

§Errors

This function will return any underling I/O errors as a DATError::FileIO.

Additionally, it may return a DATError::Overflow error if the new content size would exceed the maximum allowed size. This size may be adjusted using set_max_size(), but modifying it may not produce a valid file for the game client.

Source

pub fn set_max_size(&mut self, new_size: u32) -> Result<(), DATError>

Truncates or extends the full DAT file. This emulates the behavior of std::fs::File::set_len(). Because DAT files store content as null-terminated CStrings, the actual useable space will be one byte less than specified.

Files with a non-default maximum size may cause undefined behavior in the game client.

§Errors

This function will return any underling I/O errors as a DATError::FileIO.

A DATError::Overflow is returned if the maximum size would be shorter than the content size after shrinking. To correct this, first set_content_size().

Source

pub fn sync_all(&self) -> Result<(), DATError>

Calls sync_all() on the underlying std::fs::File.

§Errors

This function will return any underling I/O errors as a DATError::FileIO.

Source

pub fn sync_data(&self) -> Result<(), DATError>

Calls sync_data() on the underlying std::fs::File.

§Errors

This function will return any underling I/O errors as a DATError::FileIO.

Trait Implementations§

Source§

impl Debug for DATFile

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Read for DATFile

Source§

fn read(&mut self, buf: &mut [u8]) -> Result<usize>

Pull some bytes from this source into the specified buffer, returning how many bytes were read. Read more
1.36.0 · Source§

fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>

Like read, except that it reads into a slice of buffers. Read more
Source§

fn is_read_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Reader has an efficient read_vectored implementation. Read more
1.0.0 · Source§

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>

Reads all bytes until EOF in this source, placing them into buf. Read more
1.0.0 · Source§

fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>

Reads all bytes until EOF in this source, appending them to buf. Read more
1.6.0 · Source§

fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>

Reads the exact number of bytes required to fill buf. Read more
Source§

fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Pull some bytes from this source into the specified buffer. Read more
Source§

fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Reads the exact number of bytes required to fill cursor. Read more
1.0.0 · Source§

fn by_ref(&mut self) -> &mut Self
where Self: Sized,

Creates a “by reference” adaptor for this instance of Read. Read more
1.0.0 · Source§

fn bytes(self) -> Bytes<Self>
where Self: Sized,

Transforms this Read instance to an Iterator over its bytes. Read more
1.0.0 · Source§

fn chain<R>(self, next: R) -> Chain<Self, R>
where R: Read, Self: Sized,

Creates an adapter which will chain this stream with another. Read more
1.0.0 · Source§

fn take(self, limit: u64) -> Take<Self>
where Self: Sized,

Creates an adapter which will read at most limit bytes from it. Read more
Source§

impl Seek for DATFile

Source§

fn seek(&mut self, pos: SeekFrom) -> Result<u64, Error>

Seek to an offset, in bytes, in a stream. Read more
1.55.0 · Source§

fn rewind(&mut self) -> Result<(), Error>

Rewind to the beginning of a stream. Read more
Source§

fn stream_len(&mut self) -> Result<u64, Error>

🔬This is a nightly-only experimental API. (seek_stream_len)
Returns the length of this stream (in bytes). Read more
1.51.0 · Source§

fn stream_position(&mut self) -> Result<u64, Error>

Returns the current seek position from the start of the stream. Read more
1.80.0 · Source§

fn seek_relative(&mut self, offset: i64) -> Result<(), Error>

Seeks relative to the current position. Read more
Source§

impl Write for DATFile

Source§

fn write(&mut self, buf: &[u8]) -> Result<usize>

Writes a buffer into this writer, returning how many bytes were written. Read more
Source§

fn flush(&mut self) -> Result<()>

Flushes this output stream, ensuring that all intermediately buffered contents reach their destination. Read more
1.36.0 · Source§

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize, Error>

Like write, except that it writes from a slice of buffers. Read more
Source§

fn is_write_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored implementation. Read more
1.0.0 · Source§

fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>

Attempts to write an entire buffer into this writer. Read more
Source§

fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>

🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more
1.0.0 · Source§

fn write_fmt(&mut self, args: Arguments<'_>) -> Result<(), Error>

Writes a formatted string into this writer, returning any error encountered. Read more
1.0.0 · Source§

fn by_ref(&mut self) -> &mut Self
where Self: Sized,

Creates a “by reference” adapter for this instance of Write. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.