Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

214
LINES

< > BotCompany Repo | #1035632 // ByteHead - byte I/O class (can read and write)

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (13644L/77K).

// We use big-endian as DataOutputStream does
sclass ByteHead /*is DataOutput*/ is AutoCloseable {
  settable bool readMode;
  settable bool writeMode;
  gettable InputStream inputStream;
  gettable OutputStream outputStream;
  settable long byteCounter;
  gettable bool eof;
  
  *() {}
  *(InputStream inputStream) { inputStream(inputStream); }
  *(OutputStream outputStream) { outputStream(outputStream); }
  
  selfType inputStream(InputStream inputStream) { this.inputStream = inputStream; readMode(true); this; }
  selfType outputStream(OutputStream outputStream) { this.outputStream = outputStream; writeMode(true); this; }
  
  void write(byte[] data) ctex {
    ensureWriteMode();
    outputStream?.write(data);
    byteCounter += data.length;
  }
  
  void writeFloat(float f) {
    writeInt(Float.floatToIntBits(f));
  }
  
  void writeLong(long l) {
    writeInt((int) (l >> 32));
    writeInt((int) l);
  }
  
  void writeInt(int i) {
    write(i >> 24);
    write(i >> 16);
    write(i >> 8);
    write(i);
  }
  
  void writeShort(int i) {
    write(i >> 8);
    write(i);
  }
  
  void writeByte aka write(int i) ctex {
    ensureWriteMode();
    outputStream?.write(i);
    byteCounter++;
  }
  
  void writeASCII(char c) {
    write(toASCII(c));
  }
  
  void writeASCII(S s) {
    write(toASCII(s));
  }
  
  // write/verify constant ASCII text
  void exchangeASCII(S s) {
    exchangeConstantBytes(toASCII(s));
  }
  
  void exchangeConstantBytes(byte[] data) {
    for i over data:
      exchangeByte(data[i]);
  }
  
  long readLong() {
    long i = ((long) readInt()) << 32;
    ret i | (readInt() & 0xFFFFFFFFL);
  }
  
  float readFloat() {
    ret Float.intBitsToFloat(readInt());
  }
  
  int readInt() {
    int i = read() << 24;
    i |= read() << 16;
    i |= read() << 8;
    ret i | read();
  }
  
  short readShort() {
    int i = read() << 8;
    ret (short) (i | read());
  }
  
  byte[] readBytes(int n) {
    byte[] data = new[n];
    for i to n: {
      int b = read();
      if (b < 0)
        fail("EOF");
      data[i] = (byte) b; 
    }
    ret data;
  }
  
  S readString() {
    int n = readInt();
    if (eof()) null;
    ret fromUtf8(readBytes(n));
  }
  
  // null is written as empty string
  // writes UTF8 length (4 bytes) plus string as UTF8
  void writeString(S s) {
    byte[] utf8 = toUtf8(unnull(s));
    writeInt(l(utf8));
    write(utf8);
  }
  
  // -1 for EOF
  int readByte aka read() ctex {
    ensureReadMode();
    ++byteCounter;
    int b = inputStream.read();
    if (b < 0) eof = true;
    ret b;
  }
  
  void ensureReadMode {
    if (!readMode) fail("Not in read mode");
  }
  
  void ensureWriteMode {
    if (!writeMode) fail("Not in write mode");
  }
  
  // exchange = read or write depending on mode
  
  void exchangeByte(byte getter, IVF1<Byte> setter) {
    exchangeByte(-> getter, setter);
  }
  
  void exchangeByte(IF0<Byte> getter, IVF1<Byte> setter) {
    if (writeMode())
      writeByte(getter!);
    
    if (readMode())
      setter.get(toUByte(readByte()));
  }
  
  void exchangeShort(IF0<Short> getter, IVF1<Short> setter) {
    if (writeMode())
      writeShort(getter!);
    
    if (readMode())
      setter.get(readShort());
  }
  
  void exchangeLong(IVar<Long> var) {
    exchangeLong(var.getter(), var.setter());
  }
  
  void exchangeLong(IF0<Long> getter, IVF1<Long> setter) {
    if (writeMode())
      writeLong(getter!);

    if (readMode())
      setter.get(readLong());
  }
  
  void exchangeByte(byte i) {
    exchangeByte(-> i, j -> assertEquals(i, j));
  }
  
  void exchangeInt(int i) {
    exchangeInt(-> i, j -> assertEquals(i, j));
  }
  
  void exchangeInt(IF0<Int> getter, IVF1<Int> setter) {
    if (writeMode())
      writeInt(getter!);

    if (readMode())
      setter.get(readInt());
  }
  
  void exchange(ByteIO writable) {
    if (writable != null) writable.readWrite(this);
  }
  
  void exchangeAll(Iterable<? extends ByteIO> writables) {  
    if (writables != null)
      for (writable : writables)
        exchange(writable);
  }
  
  // write size in bytes of element first (as int),
  // then the element itself.
  // upon reading, size is actually ignored.
  void exchangeWithSize(ByteIO writable) {
    if (writeMode()) {
      byte[] data = writable.saveToByteArray();
      writeInt(l(data));
      write(data);
    }
    
    if (readMode()) {
      int n = readInt();
      writable.readWrite(this);
    }
  }
  
  void finish {}
  
  public void close() {
    main close(inputStream);
    main close(outputStream);
    finish();
  }
}

download  show line numbers  debug dex  old transpilations   

Travelled to 2 computer(s): elmgxqgtpvxh, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1035632
Snippet name: ByteHead - byte I/O class (can read and write)
Eternal ID of this version: #1035632/40
Text MD5: cdf7caa8ba7ab823327638f1ce76786e
Transpilation MD5: 0bfe76444768cd46018eb82c3eadae23
Author: stefan
Category: javax / io
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-11-08 16:11:29
Source code size: 4780 bytes / 214 lines
Pitched / IR pitched: No / No
Views / Downloads: 280 / 531
Version history: 39 change(s)
Referenced in: #1003674 - Standard Classes + Interfaces (LIVE continued in #1034167)
#1035655 - BitHead - ByteHead that can write individual bits (and non-byte-aligned bytes and partial bytes)
#1035757 - StringHead - string I/O class (can read and write, dev.)