docs: public void read() throws IOException {
      readFileId();
      in.resetCRC();
  
      long startcode = in.readStartCode();
  
      while (true) {
        // Start parsing main and stream information
        header = new MainHeaderPacket();
  
        if (!Startcode.MAIN.equalsCode(startcode)) {
          throw new IOException(String.format("expected main header found: 0x%X", startcode));
        }
  
        header.read(in, startcode);
        startcode = readReservedHeaders();
  
        streams.clear();
        for (int i = 0; i < header.streamCount; i++) {
          if (!Startcode.STREAM.equalsCode(startcode)) {
            throw new IOException(String.format("expected stream header found: 0x%X", startcode));
          }
  
          StreamHeaderPacket streamHeader = new StreamHeaderPacket();
          streamHeader.read(in, startcode);
  
          Stream stream = new Stream(header, streamHeader);
          streams.add(stream);
          listener.stream(stream);
  
          startcode = readReservedHeaders();
        }
  
        while (Startcode.INFO.equalsCode(startcode)) {
          new Packet().read(in, startcode); // Discard for the moment
          startcode = readReservedHeaders();
        }
  
        if (Startcode.INDEX.equalsCode(startcode)) {
          new Packet().read(in, startcode); // Discard for the moment
          startcode = in.readStartCode();
        }
  
        // Now main frame parsing loop
        while (!Startcode.MAIN.equalsCode(startcode)) {
  
          if (Startcode.SYNCPOINT.equalsCode(startcode)) {
            new Packet().read(in, startcode); // Discard for the moment
            startcode = in.readStartCode();
          }
  
          if (Startcode.isPossibleStartcode(startcode)) {
            throw new IOException("expected framecode, found " + Startcode.toString(startcode));
          }
  
          Frame f = new Frame();
          f.read(this, in, (int) startcode);
  
          listener.frame(f);
  
          try {
            startcode = readReservedHeaders();
          } catch (java.io.EOFException e) {
            return;
          }
        }
      }
    }