/******************************************************************************* * Copyright (c) 2011 The Board of Trustees of the Leland Stanford Junior University * as Operator of the SLAC National Accelerator Laboratory. * Copyright (c) 2011 Brookhaven National Laboratory. * EPICS archiver appliance is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. *******************************************************************************/ package edu.stanford.slac.archiverappliance.PB.utils; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import org.apache.log4j.Logger; /** * Simple class to escape/unescape newlines in binary data. * Eventually, this should be recoded as somthing that can participate in NIO. * @author mshankar * */ public class LineEscaper { public static final byte ESCAPE_CHAR = 0x1B; public static final byte ESCAPE_ESCAPE_CHAR = 0x01; public static final byte[] ESCAPE_CHAR_SEQUENCE = { ESCAPE_CHAR, ESCAPE_ESCAPE_CHAR} ; public static final byte NEWLINE_CHAR = 0x0A; public static final byte NEWLINE_ESCAPE_CHAR = 0x02; public static final String NEWLINE_CHAR_STR = "\n"; public static final byte[] NEWLINE_CHAR_SEQUENCE = { ESCAPE_CHAR, NEWLINE_ESCAPE_CHAR} ; public static final byte CARRIAGERETURN_CHAR = 0x0D; public static final byte CARRIAGERETURN_ESCAPE_CHAR = 0x03; public static final byte[] CARRIAGERETURN_CHAR_SEQUENCE = { ESCAPE_CHAR, CARRIAGERETURN_ESCAPE_CHAR} ; private static Logger logger = Logger.getLogger(LineEscaper.class.getName()); public static void escapeNewLines(byte[] input, OutputStream os) throws IOException { if(input == null) return; for(byte b : input) { switch(b) { case ESCAPE_CHAR: os.write(ESCAPE_CHAR_SEQUENCE);break; case NEWLINE_CHAR: os.write(NEWLINE_CHAR_SEQUENCE);break; case CARRIAGERETURN_CHAR: os.write(CARRIAGERETURN_CHAR_SEQUENCE);break; default: os.write(b);break; } } } public static byte[] escapeNewLines(byte[] input) { if(input == null) return null; try { ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length*2); escapeNewLines(input, bos); bos.close(); return bos.toByteArray(); } catch(IOException ex) { logger.error("Exception escaping newlines in buffer", ex); return null; } } public static byte[] unescapeNewLines(byte[] input) { if(input == null) return null; try { // TODO if we eliminate raw byte arrays here, we can shave off about 1 sec out of 17 secs or so for 1Hz 1 year data. ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length); for(int i = 0; i < input.length; i++) { byte b = input[i]; if(b == ESCAPE_CHAR) { i++; if(i >= input.length) { throw new RuntimeException("Index " + i + " is greater then input array length " + input.length); } b = input[i]; switch(b) { case ESCAPE_ESCAPE_CHAR: bos.write(ESCAPE_CHAR);break; case NEWLINE_ESCAPE_CHAR: bos.write(NEWLINE_CHAR);break; case CARRIAGERETURN_ESCAPE_CHAR: bos.write(CARRIAGERETURN_CHAR);break; default: bos.write(b);break; } } else { bos.write(b); } } bos.close(); return bos.toByteArray(); } catch(IOException ex) { logger.error("Exception unescaping new lines ", ex); } return null; } }