StifRecordReader { public StifRecord read() throws IOException { int recordStart; int end = -1; StifRecordFactory<?> factory; while (true) { end = -1; while (end == -1) { for (int i = start; i < bufferEnd; ++i) { if (buffer[i] == '\r') { end = i; break; } } if (end != -1) { break; } ByteBuffer bbuffer = ByteBuffer.wrap(buffer); bbuffer.put(buffer, start, BUFFER_SIZE - start); bufferEnd = bufferEnd - start; int bytesRead = inputStream.read(buffer, bufferEnd, BUFFER_SIZE - bufferEnd); if (bytesRead == -1) { if (start >= bufferEnd) { return null; } else { throw new RuntimeException( "Parse error: stif requires trailing newline"); } } bufferEnd += bytesRead; start = 0; } recordStart = start; start = end + 2; int recordType = Integer .parseInt(new String(buffer, recordStart, 2)); factory = recordFactories.get(recordType); if (factory != null) { break; } } return factory.createRecord(buffer, recordStart, end); } StifRecordReader(InputStream stream); StifRecord read();  }
@Test public void testRecordReader() throws IOException { ClassLoader loader = TestStifRecordReader.class.getClassLoader(); InputStream in = loader.getResourceAsStream("stif.m_0014__.210186.sun"); StifRecordReader reader = new StifRecordReader(in); StifRecord record = reader.read(); assertNotNull(record); assertTrue(record instanceof TimetableRecord); TimetableRecord timetable = (TimetableRecord) record; assertSame(ServiceCode.SUNDAY, timetable.getServiceCode()); assertEquals("0014", timetable.getRouteIdentifier()); for (int i = 0; i < 86; ++i) { record = reader.read(); GeographyRecord stop = (GeographyRecord) record; assertNotNull(stop.getBoxID()); assertTrue(stop.getLongitude() > -74.9); assertTrue(stop.getLongitude() < -73.0); } record = reader.read(); TripRecord trip = (TripRecord) record; assertEquals("11559238", trip.getBlockNumber()); assertEquals("M14AD", trip.getRoute()); StifRecord lastRecord = record; while (record != null) { lastRecord = record; record = reader.read(); } assertTrue(lastRecord instanceof SignCodeRecord); }