Package com.cburch.logisim.gui.hex

Source Code of com.cburch.logisim.gui.hex.HexFile$HexReader

/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.logisim.gui.hex;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Arrays;
import java.util.StringTokenizer;

import com.cburch.hex.HexModel;

public class HexFile {
  private HexFile() { }
 
  private static final String RAW_IMAGE_HEADER = "v2.0 raw";
  private static final String COMMENT_MARKER = "#";
 
  private static class HexReader {
    private BufferedReader in;
    private int[] data;
    private StringTokenizer curLine;
    private long leftCount;
    private long leftValue;
   
    public HexReader(BufferedReader in) throws IOException {
      this.in = in;
      data = new int[4096];
      curLine = findNonemptyLine();
    }
   
    private StringTokenizer findNonemptyLine() throws IOException {
      String line = in.readLine();
      while (line != null) {
        int index = line.indexOf(COMMENT_MARKER);
        if (index >= 0) {
          line = line.substring(0, index);
        }

        StringTokenizer ret = new StringTokenizer(line);
        if (ret.hasMoreTokens()) return ret;
        line = this.in.readLine();
      }
      return null;
    }
   
    private String nextToken() throws IOException {
      if (curLine != null && curLine.hasMoreTokens()) {
        return curLine.nextToken();
      } else {
        curLine = findNonemptyLine();
        return curLine == null ? null : curLine.nextToken();
      }
    }
   
    public boolean hasNext() throws IOException {
      if (leftCount > 0) {
        return true;
      } else if (curLine != null && curLine.hasMoreTokens()) {
        return true;
      } else {
        curLine = findNonemptyLine();
        return curLine != null;
      }
    }
   
    public int[] next() throws IOException {
      int pos = 0;
      if (leftCount > 0) {
        int n = (int) Math.min(data.length - pos, leftCount);
        if (n == 1) {
          data[pos] = (int) leftValue;
          pos++;
          leftCount--;
        } else {
          Arrays.fill(data, pos, pos + n, (int) leftValue);
          pos += n;
          leftCount -= n;
        }
      }
      if (pos >= data.length) return data;
       
      for (String tok = nextToken(); tok != null; tok = nextToken()) {
        try {
          int star = tok.indexOf("*");
          if (star < 0) {
            leftCount = 1;
            leftValue = Long.parseLong(tok, 16);
          } else {
            leftCount = Long.parseLong(tok.substring(0, star));
            leftValue = Long.parseLong(tok.substring(star + 1), 16);
          }
        } catch (NumberFormatException e) {
          throw new IOException(Strings.get("hexNumberFormatError"));
        }
       
        int n = (int) Math.min(data.length - pos, leftCount);
        if (n == 1) {
          data[pos] = (int) leftValue;
          pos++;
          leftCount--;
        } else {
          Arrays.fill(data, pos, pos + n, (int) leftValue);
          pos += n;
          leftCount -= n;
        }
        if (pos >= data.length) return data;
      }
     
      if (pos >= data.length) {
        return data;
      } else {
        int[] ret = new int[pos];
        System.arraycopy(data, 0, ret, 0, pos);
        return ret;
      }
    }
  }

  public static void save(Writer out, HexModel src) throws IOException {
    long first = src.getFirstOffset();
    long last = src.getLastOffset();
    while (last > first && src.get(last) == 0) last--;
    int tokens = 0;
    long cur = 0;
    while (cur <= last) {
      int val = src.get(cur);
      long start = cur;
      cur++;
      while (cur <= last && src.get(cur) == val) cur++;
      long len = cur - start;
      if (len < 4) { cur = start + 1; len = 1; }
      try {
        if (tokens > 0) out.write(tokens % 8 == 0 ? '\n' : ' ');
        if (cur != start + 1) out.write((cur - start) + "*");
        out.write(Integer.toHexString(val));
      } catch (IOException e) {
        throw new IOException(Strings.get("hexFileWriteError"));
      }
      tokens++;
    }
    if (tokens > 0) out.write('\n');
  }
 
  public static void open(HexModel dst, Reader in) throws IOException {
    HexReader reader = new HexReader(new BufferedReader(in));
    long offs = dst.getFirstOffset();
    while (reader.hasNext()) {
      int[] values = reader.next();
      if (offs + values.length - 1 > dst.getLastOffset()) {
        throw new IOException(Strings.get("hexFileSizeError"));
      }
      dst.set(offs, values);
      offs += values.length;
    }
    dst.fill(offs, dst.getLastOffset() - offs + 1, 0);
  }
 
  public static int[] parse(Reader in) throws IOException {
    HexReader reader = new HexReader(new BufferedReader(in));
    int cur = 0;
    int[] data = new int[4096];
    while (reader.hasNext()) {
      int[] values = reader.next();
      if (cur + values.length > data.length) {
        int[] oldData = data;
        data = new int[Math.max(cur + values.length, 3 * data.length / 2)];
        System.arraycopy(oldData, 0, data, 0, cur);
      }
      System.arraycopy(values, 0, data, cur, values.length);
      cur += values.length;
    }
    if (cur != data.length) {
      int[] oldData = data;
      data = new int[cur];
      System.arraycopy(oldData, 0, data, 0, cur);
    }
    return data;
  }

  public static void open(HexModel dst, File src) throws IOException {
    BufferedReader in;
    try {
      in = new BufferedReader(new FileReader(src));
    } catch (IOException e) {
      throw new IOException(Strings.get("hexFileOpenError"));
    }
    try {
      String header = in.readLine();
      if (!header.equals(RAW_IMAGE_HEADER)) {
        throw new IOException(Strings.get("hexHeaderFormatError"));
      }
      open(dst, in);
      try {
        BufferedReader oldIn = in;
        in = null;
        oldIn.close();
      } catch (IOException e) {
        throw new IOException(Strings.get("hexFileReadError"));
      }
    } finally {
      try {
        if (in != null) in.close();
      } catch (IOException e) { }
    }
  }

  public static void save(File dst, HexModel src) throws IOException {
    FileWriter out;
    try {
      out = new FileWriter(dst);
    } catch (IOException e) {
      throw new IOException(Strings.get("hexFileOpenError"));
    }
    try {
      try {
        out.write(RAW_IMAGE_HEADER + "\n");
      } catch (IOException e) {
        throw new IOException(Strings.get("hexFileWriteError"));
      }
      save(out, src);
    } finally {
      try {
        out.close();
      } catch (IOException e) {
        throw new IOException(Strings.get("hexFileWriteError"));
      }
    }
  }
}
TOP

Related Classes of com.cburch.logisim.gui.hex.HexFile$HexReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.