package com.hemju.biborder; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; /** * Renumbers all bib references in the text. * * @author Helmut Juskewycz, */ public class OrderAll implements OrderStrategy { private static final int WRITE_BUFFER_SIZE = 1024 * 16; private static final int READ_BUFFER_SIZE = 1024 * 16; private static final char[] READ_BUFFER = new char[READ_BUFFER_SIZE]; private static final char[] WRITE_BUFFER = new char[READ_BUFFER_SIZE]; private static final int DIGITAL_MIN_VALUE = 0x30; private static final int DIGITAL_MAX_VALUE = 0x39; /** * Renumbers all entries, not threadsafe. */ public void order(InputStream in, OutputStream out) { try { Reader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(in))); Writer writer = new BufferedWriter(new OutputStreamWriter(new BufferedOutputStream(out))); StringBuilder bibEntry = null; boolean bibRefStart = false; HashMap mapping = new HashMap(1000); int counter = 1; char actChar; int charsRead; int charsWritten = 0; int bibRefLength; while ((charsRead = reader.read(READ_BUFFER)) >= 0) { for (int j = 0; j < charsRead; j++) { actChar = (char) READ_BUFFER[j]; if (bibRefStart) { if (actChar == ']' && bibEntry != null) {//bibRefEnd so flush to bib ref entry String key = bibEntry.toString(); String value = mapping.get(key); if (value == null) {//create new bib ref entry if none exists String newBibRef = (counter++ + ""); mapping.put(key, newBibRef); value = newBibRef; } bibRefLength = value.length(); for (int m = 0; m < bibRefLength; m++) {//save the entry in the buffer WRITE_BUFFER[charsWritten++] = value.charAt(m); if (charsWritten >= WRITE_BUFFER_SIZE) { writer.write(WRITE_BUFFER); charsWritten = 0; } } } if (actChar >= DIGITAL_MIN_VALUE && actChar <= DIGITAL_MAX_VALUE) {//is digit if (bibEntry == null) { bibEntry = new StringBuilder(); } bibEntry.append(actChar); } else { bibRefStart = false; bibEntry = null; WRITE_BUFFER[charsWritten++] = actChar; } } else { bibRefStart = (actChar == '['); WRITE_BUFFER[charsWritten++] = actChar; } // buffer full, flush to the stream if (charsWritten >= WRITE_BUFFER_SIZE) { writer.write(WRITE_BUFFER); charsWritten = 0; } } } writer.write(WRITE_BUFFER);//write the rest to the stream } catch (IOException ex) { Logger.getLogger(OrderAll.class.getName()).log(Level.SEVERE, null, ex); } } }