package com.battery.device.bts; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; final class BtsFrameReader { private static final byte[] FRAME_END = "#\r\n".getBytes(StandardCharsets.UTF_8); private BtsFrameReader() { } static byte[] read(InputStream input, int maxPayloadBytes) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int matched = 0; while (true) { int value = input.read(); if (value < 0) throw new EOFException("BTS connection closed before the frame ended"); if ((byte) value == FRAME_END[matched]) { matched++; if (matched == FRAME_END.length) return buffer.toByteArray(); continue; } if (matched > 0) { for (int i = 0; i < matched; i++) append(buffer, FRAME_END[i], maxPayloadBytes); matched = 0; if ((byte) value == FRAME_END[0]) { matched = 1; continue; } } append(buffer, value, maxPayloadBytes); } } private static void append(ByteArrayOutputStream buffer, int value, int maxPayloadBytes) throws FrameTooLargeException { if (buffer.size() >= maxPayloadBytes) throw new FrameTooLargeException(); buffer.write(value); } static final class FrameTooLargeException extends IOException { private static final long serialVersionUID = 1L; } }