Java source code of 'jhplot.io.PFile'

package jhplot.io;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import java.util.*;
import promc.io.PBufFile;
import promc.io.PBufFile.*;
import jhplot.*;
import jhplot.gui.HelpBrowser;

/**
 * 
 * Write or read objects in sequential order using Google's Prototype Buffer
 * scheme. Each record inside files is compressed on-fly. The file size are
 * smaller than when using HFile class. All graphical attributes are
 * lost (use HFile class  for this).   You can unzip the file to see its structure.
 * Normally, files should extension "jpbu". Files can be viewed using BrowserPFile.
 * Unlike the usual XML, the file size is small. At this moment,
 * the following objects are supported: a string,P0I, P0D, P1D, PND, PNI, F1D,F2D, FND,PRN,
 * H1D, H2D.
 * A protocol Buffers file is provided which can be used for C++ input.
 * This I/O is mainly for "named" objects (which implement the method setTitle() or setName().
 * Use CBook package to create such files in C++.
 *  

* * Use this approach for storing P0D, P0I, P1D, H1D, H2D, F1D, F2D objects. * * @author S.Chekanov * */ public class PFile { private FileOutputStream oof = null; private FileInputStream iif = null; private int nev = 0; static final private int FILE_VERSION = 1; private ZipOutputStream zout; static final int BUFFER = 2048; private byte data[]; private ZipInputStream zin; private ZipFile zipFile; private Map map=null; private ArrayList entries=null; /** * Open a file to write/read objects to/from a file in sequential * order. If "w" option is set, the old file will be removed. Use close() to * flash the buffer and close the file. You can set buffer size for I/O . * Make it larger for a heavy I/O. It is best to use buffer sizes that are * multiples of 1024 bytes. That works best with most built-in buffering in * hard disks * * @param file * File name * @param option * Option to create the file. If "w" - write a file (or read) * file, if "r" only read created file. * @param mapnames * set to true (slower) to make association between object name and its position in the record. * In this case, one can read objects as read(name). If file is large and you run over records * sequentially using ID, call with "false" for fast load. * */ public PFile(String file, String option, boolean mapNames) { nev = 0; map=null; entries=null; if (option.equalsIgnoreCase("w")) { try { (new File(file)).delete(); oof = new FileOutputStream(file); zout = new ZipOutputStream(new BufferedOutputStream(oof)); data = new byte[BUFFER]; zipFile = null; // write file version ZipEntry entry = new ZipEntry("info"); zout.putNextEntry(entry); String a = new String(Integer.toString(FILE_VERSION)); byte[] theByteArray = a.getBytes(); entry.setSize(theByteArray.length); zout.write(theByteArray); zout.closeEntry(); } catch (IOException e) { e.printStackTrace(); } } else if (option.equalsIgnoreCase("r")) { try { zipFile = new ZipFile(file); iif = new FileInputStream(file); zin = new ZipInputStream(iif); if (mapNames) mapNames(); } catch (IOException e) { e.printStackTrace(); } } else { ErrorMessage("Wrong option!. Only \"r\" or \"w\" is allowed"); } }; /** * Generate an association between record number and object name. * Call this method only if the constructor was called without map option. * * @return false if something is wrong * */ public boolean mapNames() { if (zin == null || zipFile == null) return false; //it exits! if (map != null || entries != null) return false; map = new HashMap(); // hash table entries=new ArrayList(); try { ZipEntry ze; while ((ze = zin.getNextEntry()) != null) { String a=ze.getName(); if (!a.equals("info")) { promc.io.PBufFile.Record record=null; try { InputStream zz = zipFile.getInputStream(ze); record = PBufFile.Record.parseFrom(zz); String title=""; if (record == null ) return false; if (record.hasName()) { title = record.getName(); } else if (record.hasF1D()) { title = record.getF1D().getName(); } else if (record.hasF2D()) { title = record.getF2D().getName(); } else if (record.hasFND()) { title = record.getFND().getName(); } else if (record.hasFPR()) { title = record.getFPR().getName(); } else if (record.hasP0I()) { title = record.getP0I().getName(); } else if (record.hasP0D()) { title = record.getP0D().getName(); }else if (record.hasPXY()) { // P1D in 2 dimensions title = record.getPXY().getName(); }else if (record.hasPXYZ()) { // P1D in 2 dimensions title = record.getPXYZ().getName(); }else if (record.hasP1D()) { // P1D in 2 dimensions title = record.getP1D().getName(); }else if (record.hasH1D()) { // P1D in 2 dimensions title = record.getH1D().getName(); }else if (record.hasPND()) { // P1D in 2 dimensions title = record.getPND().getName(); }else if (record.hasPNI()) { // P1D in 2 dimensions title = record.getPNI().getName(); }else if (record.hasH2D()) { // P1D in 2 dimensions title = record.getH2D().getName(); } else { title=""; } map.put(title, new Integer(a.toString())); entries.add(new FileEntry(title,new Integer(a.toString()),ze.getCompressedSize(),record.getSerializedSize())); zin.closeEntry(); } catch (IOException e) { e.printStackTrace(); return false; } } } } catch (FileNotFoundException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } return true; } /** * Get version of the input file. The version is an integer * written as an additional entry in the file "version". * Check this by unzipping the file. * @return version of the created file. */ public int getVersion() { String tmp="0"; if (zipFile == null) return 0; ZipEntry ze = zipFile.getEntry("info"); long size = ze.getSize(); if (size > 0) { // System.out.println("Length is " + size); BufferedReader br; try { br = new BufferedReader( new InputStreamReader(zipFile.getInputStream(ze))); String line; while ((line = br.readLine()) != null) { tmp=line; } br.close(); } catch (IOException e) { e.printStackTrace(); } } return Integer.parseInt(tmp); } /** * Open file for reading objects from a serialized file in sequential order. * This constructor maps names automatically. * * @param file * File name */ public PFile(String file) { this(file, "r", true); }; /** * Open file for reading objects from a serialized file in sequential order. * This constructor maps names automatically in the read mode. * * @param option * set "r" to read and "w" to write. * * @param file * File name */ public PFile(String file, String option) { this(file,option, true); }; /** * Add an object to a file. Can be P1D, P0D,H1D,PND, etc. i.e. any jHplot array * * @param ob * Object * * @return true if success */ public boolean write(Object ob) { boolean success = true; promc.io.PBufFile.Record.Builder record = promc.io.PBufFile.Record.newBuilder(); if (ob instanceof java.lang.String) { record.setName((String) ob); success=true; } else if (ob instanceof jhplot.F1D) { F1D f1d = (jhplot.F1D)ob; promc.io.PBufFile.Record.F1D.Builder p = promc.io.PBufFile.Record.F1D.newBuilder().setName(f1d.getTitle()); p.setDefinition(f1d.getName() ); p.setMax(f1d.getMax()); p.setMin(f1d.getMin()); success=true; } else if (ob instanceof jhplot.FND) { FND fnd = (jhplot.FND)ob; promc.io.PBufFile.Record.FND.Builder p = promc.io.PBufFile.Record.FND.newBuilder().setName(fnd.getTitle()); p.setDefinition(fnd.getName()); p.setVars(fnd.getVarString()); success=true; } else if (ob instanceof jhplot.F2D) { F2D f2d = (jhplot.F2D)ob; promc.io.PBufFile.Record.F2D.Builder p = promc.io.PBufFile.Record.F2D.newBuilder().setName(f2d.getTitle()); p.setDefinition(f2d.getName() ); p.setMaxX(f2d.getMaxX()); p.setMinX(f2d.getMinX()); p.setMaxY(f2d.getMaxY()); p.setMinY(f2d.getMinY()); success=true; } else if (ob instanceof jhplot.FPR) { FPR fpr = (jhplot.FPR)ob; promc.io.PBufFile.Record.FPR.Builder p = promc.io.PBufFile.Record.FPR.newBuilder().setName(fpr.getTitle()); p.setDefinition(fpr.getName() ); p.setDivU(fpr.getDivU()); p.setDivV(fpr.getDivV()); success=true; } else if (ob instanceof jhplot.P0I) { promc.io.PBufFile.Record.P0I.Builder p0i = promc.io.PBufFile.Record.P0I.newBuilder().setName( ((jhplot.P0I) ob).getTitle()); for (int i = 0; i < ((jhplot.P0I) ob).size(); i++) p0i.addValue(((jhplot.P0I) ob).get(i)); record.setP0I(p0i); success=true; } else if (ob instanceof jhplot.P0D) { promc.io.PBufFile.Record.P0D.Builder p0d = promc.io.PBufFile.Record.P0D.newBuilder().setName( ((jhplot.P0D) ob).getTitle()); for (int i = 0; i < ((jhplot.P0D) ob).size(); i++) p0d.addValue(((jhplot.P0D) ob).get(i)); record.setP0D(p0d); success=true; }else if (ob instanceof jhplot.P2D) { P2D p2d = (jhplot.P2D) ob; promc.io.PBufFile.Record.PXYZ.Builder p = promc.io.PBufFile.Record.PXYZ.newBuilder().setName(p2d.getTitle()); for (int i = 0; i < ((jhplot.P2D) ob).size(); i++) { p.addX(p2d.getX(i)); p.addY(p2d.getY(i)); p.addZ(p2d.getZ(i));} record.setPXYZ(p); success=true; }else if (ob instanceof jhplot.PND) { PND pnd = (jhplot.PND) ob; promc.io.PBufFile.Record.PND.Builder p = promc.io.PBufFile.Record.PND.newBuilder().setName(pnd.getTitle()); int n=pnd.getDimension(); p.setDimension(n); for (int i=0; i " + a.getName()+" --> "+s1 + " --> "+s2+"\n"; } return tmp; } /** * Get object from a file using its index. * * @param index * of the object * @return Object extracted object (or null) */ public Object read(int index) { Object ob = null; if (zipFile == null) return ob; ZipEntry entry = zipFile.getEntry(Integer.toString(index)); if (entry == null) return ob; InputStream zz = null; promc.io.PBufFile.Record record = null; try { zz = zipFile.getInputStream(entry); record = PBufFile.Record.parseFrom(zz); } catch (IOException e) { e.printStackTrace(); return ob; } if (record == null) return ob; if (record.hasName()) { return record.getName(); } else if (record.hasF1D()) { promc.io.PBufFile.Record.F1D f1d = record.getF1D(); F1D p = new F1D(f1d.getName(), f1d.getDefinition(), f1d.getMin(), f1d.getMax() ); return p; } else if (record.hasF2D()) { promc.io.PBufFile.Record.F2D f2d = record.getF2D(); F2D p = new F2D(f2d.getName(), f2d.getDefinition(),f2d.getMinX(), f2d.getMaxX(), f2d.getMinY(), f2d.getMaxY() ); return p; } else if (record.hasFND()) { promc.io.PBufFile.Record.FND fnd = record.getFND(); FND p = new FND(fnd.getName(), fnd.getDefinition(), fnd.getVars() ); return p; } else if (record.hasFPR()) { promc.io.PBufFile.Record.FPR f1d = record.getFPR(); F1D p = new F1D(f1d.getName(), f1d.getDefinition(), f1d.getDivU(), f1d.getDivV() ); return p; } else if (record.hasP0I()) { promc.io.PBufFile.Record.P0I p0i = record.getP0I(); P0I p = new P0I(p0i.getName()); for (int i = 0; i < p0i.getValueCount(); i++) p.add((int) p0i.getValue(i)); return p; } else if (record.hasP0D()) { promc.io.PBufFile.Record.P0D p0d = record.getP0D(); P0D p = new P0D(p0d.getName()); for (int i = 0; i < p0d.getValueCount(); i++) p.add((double) p0d.getValue(i)); return p; } else if (record.hasPND()) { promc.io.PBufFile.Record.PND pnd = record.getPND(); PND p = new PND(pnd.getName()); P0D pp=new P0D("row"); int nn=0; for (int i=0; i