package org.kvj.vimtouch.ext; import java.util.HashMap; import java.util.Map; import org.kvj.vimtouch.ext.Transferable.FieldType; public class IncomingTransfer { private String data; private int index = 0; private Map<String, FieldReader<?>> readers = new HashMap<String, FieldReader<?>>(); public IncomingTransfer(String data) { this.data = data; } public void setIndex(int index) { this.index = index; } public void readAs(String field, FieldReader<?> reader) { readers.put(field, reader); } public char nextChar() throws FieldReaderException { if (index >= data.length()) { throw new FieldReaderException("Out of bounds"); } index++; return data.charAt(index - 1); } public String nextPiece() throws FieldReaderException { int comma = data.indexOf(',', index); if (-1 == comma) { throw new FieldReaderException("Delimiter not found"); } String result = data.substring(index, comma); index = comma + 1; return result; } public int nextInt() throws FieldReaderException { String i = nextPiece(); try { return Integer.parseInt(i, 10); } catch (Exception e) { throw new FieldReaderException("Invalid number: " + i); } } public String nextString() throws FieldReaderException { int length = nextInt(); String result = data.substring(index, index + length); index += length + 1; return result; } public <T> T readWith(FieldReader<T> reader) throws FieldReaderException { char type = nextChar(); if (FieldType.Null.getCode() == type) { // Null reader.set(null); index++; return null; } T value = reader.read(this); reader.set(value); return value; } public void read() throws FieldReaderException { while (index < data.length()) { String field = nextString(); if ("".equals(field)) { // Last field return; } FieldReader<?> reader = readers.get(field); if (null == reader) { throw new FieldReaderException("No reader found for: " + field); } readWith(reader); } } public String getData() { return data; } public int getIndex() { return index; } }