All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.freehep.util.io.ConditionalInputStream Maven / Gradle / Ivy

There is a newer version: 2.2.2
Show newest version
// Copyright 2001-2009, FreeHEP.
package org.freehep.util.io;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * The ConditionalInputStream reads a stream and filters certain parts depending
 * of properties and statements in the input.
 * 

* The following statements, all start with the &at;-sign, are allowed: *

    *
  • @ifdef property, reads everything up to the next * *

    if the property is defined.

  • @ifndef property, reads * everything up to the next *

    if the property is not defined.

  • @else, corresponding * else statement
  • @endif, corresponging endif statement *
* The &at;-sign itself must be escaped by a backslash, if used in * the text followed by any of the keywords described above and no * action should be taken. *

* @author Mark Donszelmann */ public class ConditionalInputStream extends DecodingInputStream { private int[] buffer = new int[4096]; private int index; private int len; private InputStream in; private Properties defines; private int nesting; private boolean[] ok = new boolean[50]; private boolean escape; /** * Creates a Conditional Input Stream from given stream. * * @param input * stream to read from * @param defines * set of properties to be used in ifdefs */ public ConditionalInputStream(InputStream input, Properties defines) { super(); in = input; this.defines = defines; nesting = 0; escape = false; index = 0; len = 0; } @Override public int read() throws IOException { int b; int n; // read from buffer if possible if (index < len) { b = buffer[index]; index++; } else { b = in.read(); } // return if End Of Stream if (b < 0) { return -1; } // escape \@-signs if (b == '\\') { n = in.read(); if (n == '@') { b = ' '; escape = true; } buffer[0] = n; index = 0; len = 1; } // check on @ sign if (b == '@') { if (escape) { escape = false; } else { // read keyword (ifdef, ifndef, else, endif index = 0; StringBuffer s = new StringBuffer(); n = in.read(); while ((n >= 0) && !Character.isWhitespace((char) n)) { s.append((char) n); buffer[index] = n; n = in.read(); index++; } buffer[index] = n; index++; b = ' '; // check on keyword String keyword = s.toString(); if (keyword.equals("ifdef") || keyword.equals("ifndef")) { // skip whitespace and read property s = new StringBuffer(); n = in.read(); while ((n >= 0) && Character.isWhitespace((char) n)) { buffer[index] = n; n = in.read(); index++; } while ((n >= 0) && !Character.isWhitespace((char) n)) { s.append((char) n); buffer[index] = n; n = in.read(); index++; } buffer[index] = n; index++; // check on property String property = s.toString(); if (defines.getProperty(property) != null) { ok[nesting] = (nesting > 0 ? ok[nesting - 1] : true) && keyword.equals("ifdef"); } else { ok[nesting] = (nesting > 0 ? ok[nesting - 1] : true) && keyword.equals("ifndef"); } nesting++; replaceBufferWithWhitespace(index); } else if (keyword.equals("else")) { // FIXME one could have multiple elses without endifs... // calculate inclusion based on ifdef nesting if (nesting <= 0) { throw new RuntimeException( "@else without corresponding @ifdef"); } ok[nesting - 1] = (nesting > 1 ? ok[nesting - 2] : true) && !ok[nesting - 1]; replaceBufferWithWhitespace(index); } else if (keyword.equals("endif")) { // calculate inclusion based on ifdef nesting if (nesting <= 0) { throw new RuntimeException( "@endif without corresponding @ifdef"); } nesting--; replaceBufferWithWhitespace(index); } else { // not an known @ b = '@'; } len = index; index = 0; } } if ((nesting > 0) && !ok[nesting - 1]) { if (!Character.isWhitespace((char) b)) { b = ' '; } } return b & 0x00FF; } private void replaceBufferWithWhitespace(int size) { for (int i = 0; i < size; i++) { if (!Character.isWhitespace((char) buffer[i])) { buffer[i] = ' '; } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy