@Override protected Schema readSchema() throws IOException { if (footer == null) { if (in.size() <= (ArrowMagic.MAGIC_LENGTH * 2 + 4)) { throw new InvalidArrowFileException("file too small: " + in.size()); } ByteBuffer buffer = ByteBuffer.allocate(4 + ArrowMagic.MAGIC_LENGTH); long footerLengthOffset = in.size() - buffer.remaining(); in.setPosition(footerLengthOffset); in.readFully(buffer); buffer.flip(); byte[] array = buffer.array(); if (!ArrowMagic.validateMagic(Arrays.copyOfRange(array, 4, array.length))) { throw new InvalidArrowFileException("missing Magic number " + Arrays.toString(buffer.array())); } int footerLength = MessageSerializer.bytesToInt(array); if (footerLength <= 0 || footerLength + ArrowMagic.MAGIC_LENGTH * 2 + 4 > in.size()) { throw new InvalidArrowFileException("invalid footer length: " + footerLength); } long footerOffset = footerLengthOffset - footerLength; LOGGER.debug("Footer starts at {}, length: {}", footerOffset, footerLength); ByteBuffer footerBuffer = ByteBuffer.allocate(footerLength); in.setPosition(footerOffset); in.readFully(footerBuffer); footerBuffer.flip(); Footer footerFB = Footer.getRootAsFooter(footerBuffer); this.footer = new ArrowFooter(footerFB); } return footer.getSchema(); }
@Override protected void endInternal(WriteChannel out) throws IOException { long footerStart = out.getCurrentPosition(); out.write(new ArrowFooter(schema, dictionaryBlocks, recordBlocks), false); int footerLength = (int) (out.getCurrentPosition() - footerStart); if (footerLength <= 0) { throw new InvalidArrowFileException("invalid footer"); } out.writeIntLittleEndian(footerLength); LOGGER.debug("Footer starts at {}, length: {}", footerStart, footerLength); ArrowMagic.writeMagic(out, false); LOGGER.debug("magic written, now at {}", out.getCurrentPosition()); }
throw new InvalidArrowFileException("Unrecognized buffer type " + bufferType);