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

make byte order types IO wrappers #3820

Closed
wants to merge 2 commits into from

Conversation

simonbyrne
Copy link
Contributor

Converts the ByteOrder types introduced in #3633 to IO wrappers.

Works quite well, requiring no changes for existing read/write methods.

However, I seem to be getting some ambiguous dispatch errors that I can't seem to fix,

@StefanKarpinski
Copy link
Member

I'm much, much happier with this API. cc: @JeffBezanson

@simonbyrne
Copy link
Contributor Author

Ah, I think it's because I'm missing some Bool and Char definitions. Is there an easier way to specify these without enumerating all combinations?

Also, does Char behave the same on both big and little-endian architectures?

@StefanKarpinski
Copy link
Member

Char is a weird case since writing it generally means encoding something as a string, so you generally don't want to actually write Chars. What you do want to do is make sure that string data for which byte ordering is meaningful is ordered correctly. That doesn't mean anything for UTF-8 since it's byte-oriented, but for UTF-16 and UTF-32 have both big and little endian variants.

@timholy
Copy link
Member

timholy commented Jul 24, 2013

I agree that it's better associated with the stream. Good observation, @StefanKarpinski.

@kmsquire
Copy link
Member

Thoughts:

  • In the tests right now, each read and write are creating a new ByteOrderedIO object.
  • If you create one object at the beginning and continue to reference it, you still may need to pass the wrapped IO instance to some functions
  • This will probably break with zlib compressed io, since zlib already handles endian conversion. The only place this matters right now is with the GZip.jl, where GZipStream <: IO.

@simonbyrne
Copy link
Contributor Author

Okay, I've added the extra methods, though the Char methods might be wrong. I've also changed the new types to be immutable, but this now causes a segmentation error in test-spawn.

@JeffBezanson
Copy link
Member

I'm starting to wonder whether we should do all I/O through a type like IOBuffer, with a low-level API for concrete streams that only uses unix-style read/write of chunks of bytes. Similar to @kmsquire 's BufferedReader, which I initially dismissed, but if we're going to start wrapping streams we might be better off going all the way. In particular, we would be able to implement features like byte order, different text encodings, mark/seekmark etc. very efficiently against a known representation (uint8 array), and only once. The low-level API would only consist of a way to fill and consume the buffer (and would probably be quite distinct from the user-level API). This could eliminate some confusion about what to define, and avoid the performance pitfall we currently have where everything is ultimately defined in terms of reading single bytes. I'm worried about ending up with a bunch of I/O wrappers, like BufferedReader{NetworkByteOrder{MyStream}}.

@kmsquire
Copy link
Member

Just to note, the BufferedReader pull request (which is still open #3656) doesn't actually have a BufferedReader any more, and instead just modifies IOBuffer and IOStream. IOBuffer is already used by UV streams in a number of places.

I agree that that's probably the way to go, with one caveat that the current IOBuffer implementation moves around data too much. A better implementation would probably be a ring buffer or bucket brigade (I like that name!), although they're somewhat more complicated.

@simonbyrne
Copy link
Contributor Author

That's strange, the tests seem to now be passing on my machine, but Travis has hit a different error.

@vtjnash
Copy link
Member

vtjnash commented Jul 25, 2013

To take @JeffBezanson's idea in a slightly different direction, what if the I/O wrappers were implemented as functions instead of types?

type FilteredIO
    io::IO
    rfilters::Array{Function,1}
    wfilters::Array{Function,1}
    FilteredIO(io) = new(io, Function[], Function[])
end
write(io::FilteredIO, x) = write(io.io, reduce((x,f)->f(x), x, io.wfilters)

However, it's not immediately clear to me how one would implement reading in this scheme.
read(io::FilteredIO, T) = reduce((x,f)->f(x), read(io.io, T), io.rfilters) is not correct.

read(io::FilteredIO, T) = io.rfilters[1](io.rfilters[2:], io, T) might be closer?

@JeffBezanson
Copy link
Member

see #3887

@simonbyrne simonbyrne deleted the byteorder branch March 10, 2015 11:59
KristofferC pushed a commit that referenced this pull request Mar 5, 2024
Stdlib: Pkg
URL: https://github.com/JuliaLang/Pkg.jl.git
Stdlib branch: master
Julia branch: master
Old commit: 48eea8dbd
New commit: e7d740ac8
Julia version: 1.12.0-DEV
Pkg version: 1.11.0(Does not match)
Bump invoked by: @KristofferC
Powered by:
[BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl)

Diff:
JuliaLang/Pkg.jl@48eea8d...e7d740a

```
$ git log --oneline 48eea8dbd..e7d740ac8
e7d740ac8 move to using Base parallel precompile (#3820)
d1f91fd37 fix relative paths in test project for `[sources]` (#3825)
5c73d7f3c Support a `[sources]` section in Project.toml for specifying paths and repo locations for dependencies (#3783)
0d9aa51a9 do not use UnstableIO for subprocess (in e.g. Pkg.test) (#3823)
```

Co-authored-by: Dilum Aluthge <[email protected]>
mkitti pushed a commit to mkitti/julia that referenced this pull request Apr 13, 2024
…#53610)

Stdlib: Pkg
URL: https://github.com/JuliaLang/Pkg.jl.git
Stdlib branch: master
Julia branch: master
Old commit: 48eea8dbd
New commit: e7d740ac8
Julia version: 1.12.0-DEV
Pkg version: 1.11.0(Does not match)
Bump invoked by: @KristofferC
Powered by:
[BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl)

Diff:
JuliaLang/Pkg.jl@48eea8d...e7d740a

```
$ git log --oneline 48eea8dbd..e7d740ac8
e7d740ac8 move to using Base parallel precompile (JuliaLang#3820)
d1f91fd37 fix relative paths in test project for `[sources]` (JuliaLang#3825)
5c73d7f3c Support a `[sources]` section in Project.toml for specifying paths and repo locations for dependencies (JuliaLang#3783)
0d9aa51a9 do not use UnstableIO for subprocess (in e.g. Pkg.test) (JuliaLang#3823)
```

Co-authored-by: Dilum Aluthge <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants