Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider adding runtime-defined endianness #41

Closed
netvl opened this issue Feb 1, 2016 · 8 comments
Closed

Consider adding runtime-defined endianness #41

netvl opened this issue Feb 1, 2016 · 8 comments
Labels

Comments

@netvl
Copy link

netvl commented Feb 1, 2016

Sometimes it is impossible to statically determine required endianness in advance. For example, TIFF image format defines endianness in the first byte of an input file, so it may be either big or little but which exactly is unknown statically. It would be nice if I could use byteorder for this task too.

@BurntSushi
Copy link
Owner

@netvl Hmm, is there any particular reason why NativeEndian doesn't work for you? (This otherwise looks like a dupe of #18.)

@BurntSushi
Copy link
Owner

@netvl Oh, I misread your question. I guess I'm not following. What code have you tried? You should be able to invoke either endianness by calling e.g., BigEndian::read_u32 or LittleEndian::read_u32.

@netvl
Copy link
Author

netvl commented Feb 2, 2016

I'd like to pass the actual endianness to read functions at runtime, something like

let byte_order = if <some check> { LittleEndian } else { BigEndian };
let n = source.read_u16(byte_order);

Here the required byte order is determined at runtime. I also can't use ByteOrder as a trait object because all its methods are static (and anyway, they don't work with Read directly).

@BurntSushi
Copy link
Owner

@netvl Define some helper functions? e.g.,

enum Endian { Little, Big }

fn read_u16(source: &[u8], endian: Endian) -> byteorder::Result<u16> {
    match endian {
        Endian::Little => byteorder::LittleEndian::read_u16(source),
        Endian::Big => byteorder::BigEndian::read_u16(source),
    }
}

read_u16(&[...], Endian::Little)

@netvl
Copy link
Author

netvl commented Feb 2, 2016

Well, yes, that's what I've done. I've written an extension trait for Read and a macro which generates all the necessary methods. I just think that this should be provided by the library :)

@BurntSushi
Copy link
Owner

@netvl I see. I'm not totally convinced the added API surface is really worth it ("I'm trying to use byteorder but there are three different ways to read a big endian number, which one should I use?"). I can see how they would be useful occasionally though.

@netvl
Copy link
Author

netvl commented Feb 2, 2016

Maybe this problem is solved by the proper documentation. Something along the following lines:

There are three ways to read a number in a specific endianness:

  • by using methods of ByteOrder trait, like BigEndian::read_u16(buf), if you need to read a number from a byte slice with a statically known byte order;
  • by using methods of ReadBytesExt extension trait, like source.read_u16::<BigEndian>(), if you need to read a number from a Read instance with a statically known byte order;
  • or by using methods of ReadBytesDynamicExt extension trait, like source.read_u16(byte_order), if you need to read a number from a Read instance when the byte order is determined at runtime.

wimh pushed a commit to wimh/coreutils that referenced this issue Jul 30, 2016
@BurntSushi
Copy link
Owner

I still personally feel like expecting one to write a helper function for this is perfectly fine. I'd really rather not make the API more complex than it already is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants