/** * Saves an image as a gif. Currently this uses ImageMagick's "convert" (Windows or Linux) because * it does the best job at color reduction (and is fast and is cross-platform). This will * overwrite an existing file. * * @param bi * @param fullGifName but without the .gif at the end * @throws Exception if trouble */ public static void saveAsGif(BufferedImage bi, String fullGifName) throws Exception { // POLICY: because this procedure may be used in more than one thread, // do work on unique temp files names using randomInt, then rename to proper file name. // If procedure fails half way through, there won't be a half-finished file. int randomInt = Math2.random(Integer.MAX_VALUE); // save as .bmp (note: doesn't support transparent pixels) long time = System.currentTimeMillis(); if (verbose) String2.log("SgtUtil.saveAsGif"); ImageIO.write(bi, "bmp", new File(fullGifName + randomInt + ".bmp")); if (verbose) String2.log(" make .bmp done. time=" + (System.currentTimeMillis() - time)); // "convert" to .gif SSR.dosOrCShell( "convert " + fullGifName + randomInt + ".bmp" + " " + fullGifName + randomInt + ".gif", 30); File2.delete(fullGifName + randomInt + ".bmp"); // try fancy color reduction algorithms // Image2.saveAsGif(Image2.reduceTo216Colors(bi), fullGifName + randomInt + ".gif"); // try dithering // Image2.saveAsGif216(bi, fullGifName + randomInt + ".gif", true); // last step: rename to final gif name File2.rename(fullGifName + randomInt + ".gif", fullGifName + ".gif"); if (verbose) String2.log( "SgtUtil.saveAsGif done. TOTAL TIME=" + (System.currentTimeMillis() - time) + "\n"); }
private void printToBoth(String s) throws IOException { String2.log(s); String2.flushLog(); outFile.write(s); outFile.write('\n'); outFile.flush(); }
/** * This class is designed to be a stand-alone program to validate that the DataSet.properties file * contains valid information for all datasets listed by validDataSets in DataSet.properties. * Don't run this on the coastwatch computer. * * @param args is ignored */ public static void main(String args[]) throws Exception { String2.log("ValidatDataSetProperties (testing DataSet.properties validDataSets"); // find a browser properties file (e.g., CWBrowser.properties) String contextDirectory = SSR.getContextDirectory(); // with / separator and / at the end String[] propList = RegexFilenameFilter.list( contextDirectory + "WEB-INF/classes/gov/noaa/pfel/coastwatch/", ".+\\.properties"); int which = -1; for (int i = 0; i < propList.length; i++) { if (!propList[i].equals("DataSet.properties")) { which = i; break; } } Test.ensureNotEqual( which, -1, String2.ERROR + ": No non-DataSet.properties properties files found in\n" + contextDirectory + "WEB-INF/classes/gov/noaa/pfel/coastwatch/.\n" + ".properties files=" + String2.toCSSVString(propList)); FileNameUtility fnu = new FileNameUtility( "gov.noaa.pfel.coastwatch." + File2.getNameNoExtension(propList[which])); ResourceBundle2 dataSetRB2 = new ResourceBundle2("gov.noaa.pfel.coastwatch.DataSet"); String infoUrlBaseUrl = dataSetRB2.getString("infoUrlBaseUrl", null); String tDataSetList[] = String2.split(dataSetRB2.getString("validDataSets", null), '`'); int nDataSets = tDataSetList.length; // Test.ensureEqual(nDataSets, 228, "nDataSets"); //useful to me, but Dave can't add dataset // without recompiling this String2.log(" testing " + nDataSets + " data sets"); boolean excessivelyStrict = true; for (int i = OneOf.N_DUMMY_GRID_DATASETS; i < nDataSets; i++) { // "2" in order to skip 0=OneOf.NO_DATA, 1=BATHYMETRY String seven = tDataSetList[i]; Test.ensureTrue(seven != null && seven.length() > 0, " tDataSetList[" + i + "] is ''."); fnu.ensureValidDataSetProperties(seven, excessivelyStrict); String infoUrl = dataSetRB2.getString(seven + "InfoUrl", null); Test.ensureNotNull(infoUrl, seven + "InfoUrl is null."); SSR.getUrlResponse( infoUrlBaseUrl + infoUrl); // on all computers except coastwatch, all are accessible as urls } String2.log( " ValidatDataSetProperties successfully tested n=" + nDataSets + " last=" + tDataSetList[nDataSets - 1]); }
/** This gets the i'th value from args, or prompts the user. */ private String get(String args[], int i, String prompt, String def) throws Throwable { if (args.length > i) { String2.log(prompt + "? " + args[i]); return args[i]; } String s = String2.getStringFromSystemIn(prompt + " (default=\"" + def + "\")? "); if (s == null) // null if ^C return s; if (s.equals("\"\"")) s = ""; else if (s.length() == 0) s = def; return s; }
/** * This writes any end-of-file info to the stream and flushes the stream. * * @throws Throwable if trouble (e.g., MustBe.THERE_IS_NO_DATA if there is no data) */ public void finish() throws Throwable { // check for MustBe.THERE_IS_NO_DATA if (writer == null) throw new SimpleException(MustBe.THERE_IS_NO_DATA + " (nRows = 0)"); // end of big array writer.write( "\n" + // for end line (no comma) of last coordinate or feature "\n" + // gap " ],\n" + // end of features array " \"bbox\": [" + minLon + ", " + minLat + (altColumn >= 0 ? ", " + minAlt : "") + ", " + maxLon + ", " + maxLat + (altColumn >= 0 ? ", " + maxAlt : "") + "]\n" + // 2009-07-31 removed ',' after ] "}\n"); // end of features collection if (jsonp != null) writer.write(")"); writer.flush(); // essential // diagnostic if (verbose) String2.log("TableWriterGeoJson done. TIME=" + (System.currentTimeMillis() - time) + "\n"); }
/** Bob Simons added this to avoid memory leak problems. */ public void releaseResources() throws Exception { try { xloc_ = null; yloc_ = null; tloc_ = null; keyTitle_ = null; xMetaData_ = null; yMetaData_ = null; associatedData_ = null; xRange_ = null; yRange_ = null; changes_ = null; if (JPane.debug) String2.log("sgt.dm.SimpleLine.releaseResources() finished"); } catch (Throwable t) { String2.log(MustBe.throwableToString(t)); if (JPane.debug) String2.pressEnterToContinue(); } }
/** * This writes a string value to the file The string UTF-8 encoded then stored, so the * byteArray.length may be greater than s.length(), so make the column wider to be safe. * * @param s a String. If s is too long, it is truncated. If too short, it is space-padded at the * end. * @param length * @return the corresponding byte[] (or null if s is null) */ public void writeString(int col, int row, String s) throws IOException { int colWidth = columnWidths[col]; if (s.length() > colWidth) s = s.substring(0, colWidth); byte ar[] = String2.getUTF8Bytes(s); // truncating is tricky because don't want to have 1/2 of a 2-byte char while (ar.length > colWidth) { if (reallyVerbose) String2.log("s=" + String2.annotatedString(s) + " will be shortened by 1 char."); s = s.substring(0, s.length() - 1); // remove last byte ar = String2.getUTF8Bytes(s); } if (ar.length < colWidth) { byte tar[] = new byte[colWidth]; System.arraycopy(ar, 0, tar, 0, ar.length); Arrays.fill(tar, ar.length, colWidth, (byte) ' '); ar = tar; } write(col, row, ar); }
/** * This closes the pdf file created by createPDF, after you have written things to g2D. * * @param oar the object[] returned from createPdf * @throwsException if trouble */ public static void closePdf(Object oar[]) throws Exception { Graphics2D g2D = (Graphics2D) oar[0]; Document document = (Document) oar[1]; PdfContentByte pdfContentByte = (PdfContentByte) oar[2]; PdfTemplate pdfTemplate = (PdfTemplate) oar[3]; g2D.dispose(); // center it if (verbose) String2.log( "SgtUtil.closePdf" + " left=" + document.left() + " right=" + document.right() + " bottom=" + document.bottom() + " top=" + document.top() + " template.width=" + pdfTemplate.getWidth() + " template.height=" + pdfTemplate.getHeight()); // x device = ax user + by user + e // y device = cx user + dy user + f pdfContentByte.addTemplate( pdfTemplate, // a,b,c,d,e,f //x,y location in points 0.5f, 0, 0, 0.5f, document.left() + (document.right() - document.left() - pdfTemplate.getWidth() / 2) / 2, document.bottom() + (document.top() - document.bottom() - pdfTemplate.getHeight() / 2) / 2); /* //if boundingBox is small, center it //if boundingBox is large, shrink and center it //document.left/right/top/bottom include 1/2" margins float xScale = (document.right() - document.left()) / pdfTemplate.getWidth(); float yScale = (document.top() - document.bottom()) / pdfTemplate.getHeight(); float scale = Math.min(Math.min(xScale, yScale), 1); float xSize = pdfTemplate.getWidth() / scale; float ySize = pdfTemplate.getHeight() / scale; //x device = ax user + by user + e //y device = cx user + dy user + f pdfContentByte.addTemplate(pdfTemplate, //a,b,c,d,e,f scale, 0, 0, scale, document.left() + (document.right() - document.left() - xSize) / 2, document.bottom() + (document.top() - document.bottom() - ySize) / 2); */ document.close(); }
/** * This creates a font and throws exception if font family not available * * @param fontFamily * @throws Exception if fontFamily not available */ public static Font getFont(String fontFamily) { // minor or major failures return a default font ("Dialog"!) Font font = new Font(fontFamily, Font.PLAIN, 10); // Font.ITALIC if (!font.getFamily().equals(fontFamily)) Test.error( String2.ERROR + " in SgtUtil.getFont: " + fontFamily + " not available.\n" + String2.javaInfo() + "\n" + "Fonts available: " + String2.noLongLinesAtSpace( String2.toCSSVString( GraphicsEnvironment.getLocalGraphicsEnvironment() .getAvailableFontFamilyNames()), 80, " ")); return font; }
/** * Given a bufferedImage with a legend near the bottom (entire width of image), this replaces the * legend with white. * * @param bufferedImage * @return a bufferedImage without the legend. If trouble, this returns the original image. */ public static BufferedImage removeLegend(BufferedImage bufferedImage) { try { int lh[] = findLegendLH(bufferedImage); if (lh[0] == 0 && lh[1] == 0) return bufferedImage; Graphics g = bufferedImage.getGraphics(); g.setColor(Color.white); // white g.fillRect(0, lh[0], bufferedImage.getWidth(), lh[1] - lh[0] + 1); } catch (Throwable t) { String2.log(MustBe.throwableToString(t)); } return bufferedImage; }
/** * This returns a message indicating if graphics operations on bufferedImages are hardware * accelerated. */ public static String isBufferedImageAccelerated() { if (isBufferedImageAccelerated == null) { try { BufferedImage bi = getBufferedImage(10, 10); ImageCapabilities imCap = bi.getCapabilities(null); isBufferedImageAccelerated = "bufferedImage isAccelerated=" + (imCap == null ? "[unknown]" : imCap.isAccelerated()); } catch (Throwable t) { String2.log(MustBe.throwableToString(t)); isBufferedImageAccelerated = "bufferedImage isAccelerated=[unknown]"; } } return isBufferedImageAccelerated; }
/** Run CWDataBrowserReset */ void runCWDataBrowserReset() { // is there already a reset thread? if (resetThread != null) { String2.log(String2.ERROR + " in runCWDataBrowserReset: resetThread!=null"); return; } // create a lower priority thread and run cwDataBrowserReset timeOfLastReset = System.currentTimeMillis(); cwDataBrowserReset = new CWDataBrowserReset(); resetThread = new Thread(cwDataBrowserReset); resetThread.setPriority(Thread.currentThread().getPriority() - 2); // -2 because some adjacent priorities map to the same OS priority resetThread.start(); }
/** * Given a bufferedImage, this removes any whitespace more than 10 lines at the bottom. * * @param bufferedImage * @param borderWidth in pixels * @return a trimmed bufferedImage. If trouble, this returns the original image. */ public static BufferedImage trimBottom(BufferedImage bufferedImage, int borderWidth) { try { if (borderWidth < 0) borderWidth = 0; if (borderWidth > 1000) return bufferedImage; // find the first non-white pixel above bottom edge int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight(); int y; Y_LOOP: for (y = height - 1; y >= 0; y--) { for (int x = 0; x < width; x++) { if (bufferedImage.getRGB(x, y) != 0xFFFFFFFF) break Y_LOOP; } } // if (verbose) String2.log("trimBottom y=" + y + " height=" + height); int newHeight = y + borderWidth + 1; if (y < 0 || newHeight >= height) return bufferedImage; BufferedImage newBI = getBufferedImage(width, newHeight); Graphics g = newBI.getGraphics(); g.drawImage( bufferedImage, 0, 0, width, newHeight, // dest params are exclusive 0, 0, width, newHeight, // source null); // documentation differs, but I think it blocks till finished if no observer return newBI; } catch (Throwable t) { String2.log(MustBe.throwableToString(t)); } return bufferedImage; }
/** * The constructor. * * @param fullFileName if it exists, the data will be used. If not, it will be created. * @param mode This must be one of * <ul> * <li>"r" Open for reading only. Invoking any of the write methods of the resulting object * will cause an IOException to be thrown. * <li>"rw" Open for reading and writing. If the file does not already exist then an attempt * will be made to create it. * <li>"rws" Open for reading and writing, as with "rw", and also require that every update * to the file's content or metadata be written synchronously to the underlying storage * device. * <li>"rwd" Open for reading and writing, as with "rw", and also require that every update * to the file's content be written synchronously to the underlying storage device. * </ul> * See http://download.oracle.com/javase/1.4.2/docs/api/java/io/RandomAccessFile.html#mode * <br> * Reading data is equally fast in all modes. <br> * Writing data in "rw" is 10X to 40X faster than "rws" and "rwd" modes. <br> * For writing data in "rw" mode, text and binary methods are equally fast (text is perhaps * slightly faster!). <br> * For writing data in "rws" and "rwd" modes, text is 5X to 10X FASTER than binary (!!!). <br> * String read/write is surprisingly fast in all modes. <br> * Using "rw" and flush() after each group of writes is slower than rw, but faster than rws * and rwd, and closest to making groups of action atomic. <br> * Advice: if file integrity is very important, use "rw"+flush or "rws". * @param columnWidths (in bytes) For numeric columns, use the XXX_LENGTH constants. <br> * For Strings, use whatever value you want. Strings are always converted to utf-8 then * stored, so reserve extra space if chars above #128 expected. */ public PersistentTable(String fullFileName, String mode, int columnWidths[]) throws IOException { this.fullFileName = fullFileName; this.columnWidths = columnWidths; columnStartAt = new int[columnWidths.length]; nBytesPerRow = 0; for (int c = 0; c < columnWidths.length; c++) { columnStartAt[c] = nBytesPerRow; nBytesPerRow += columnWidths[c]; } nBytesPerRow++; // for newline automatically added to end of row // open the file; raf = new RandomAccessFile(fullFileName, mode); long longNRows = raf.length() / nBytesPerRow; // integer division causes partial row at end to be ignored EDStatic.ensureArraySizeOkay(longNRows, "PersistentTable"); nRows = (int) longNRows; // save since checked above if (verbose) String2.log( "PersistentTable " + fullFileName + " is open.\n mode=" + mode + " nRows=" + nRows); }
/** * Saves an image as a png. This will overwrite an existing file. * * @param bi * @param transparent the color to be made transparent (or null if none) * @param outputStream (it is flushed at the end) * @throws Exception if trouble */ public static void saveAsTransparentPng( BufferedImage bi, Color transparent, OutputStream outputStream) throws Exception { // convert transparent color to be transparent long time = System.currentTimeMillis(); if (transparent != null) { Image image = Image2.makeImageBackgroundTransparent(bi, transparent, 10000); // convert image back to bufferedImage bi = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics g = bi.getGraphics(); g.drawImage(image, 0, 0, bi.getWidth(), bi.getHeight(), null); } // save as png ImageIO.write(bi, "png", outputStream); outputStream.flush(); if (verbose) String2.log("SgtUtil.saveAsPng TIME=" + (System.currentTimeMillis() - time) + "\n"); }
/** * Saves an image as a gif. Currently this uses ImageMagick's "convert" (Windows or Linux) because * it does the best job at color reduction (and is fast and is cross-platform). This will * overwrite an existing file. * * @param bi * @param transparent the color to be made transparent * @param fullGifName but without the .gif at the end * @throws Exception if trouble */ public static void saveAsTransparentGif(BufferedImage bi, Color transparent, String fullGifName) throws Exception { // POLICY: because this procedure may be used in more than one thread, // do work on unique temp files names using randomInt, then rename to proper file name. // If procedure fails half way through, there won't be a half-finished file. int randomInt = Math2.random(Integer.MAX_VALUE); // convert transparent color to be transparent long time = System.currentTimeMillis(); Image image = Image2.makeImageBackgroundTransparent(bi, transparent, 10000); // convert image back to bufferedImage bi = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics g = bi.getGraphics(); g.drawImage(image, 0, 0, bi.getWidth(), bi.getHeight(), null); image = null; // encourage garbage collection // save as png int random = Math2.random(Integer.MAX_VALUE); ImageIO.write(bi, "png", new File(fullGifName + randomInt + ".png")); // "convert" to .gif SSR.dosOrCShell( "convert " + fullGifName + randomInt + ".png" + " " + fullGifName + randomInt + ".gif", 30); File2.delete(fullGifName + randomInt + ".png"); // try fancy color reduction algorithms // Image2.saveAsGif(Image2.reduceTo216Colors(bi), fullGifName + randomInt + ".gif"); // try dithering // Image2.saveAsGif216(bi, fullGifName + randomInt + ".gif", true); // last step: rename to final gif name File2.rename(fullGifName + randomInt + ".gif", fullGifName + ".gif"); if (verbose) String2.log( "SgtUtil.saveAsTransparentGif TIME=" + (System.currentTimeMillis() - time) + "\n"); }
/** This reads a long from the file (or Long.MAX_VALUE if trouble). */ public long readLong(int col, int row) throws IOException { return String2.parseLong(readString(col, row)); }
/** This reads an int from the file (or Integer.MAX_VALUE if trouble). */ public int readInt(int col, int row) throws IOException { return String2.parseInt(readString(col, row)); }
/** This reads a short from the file (or Short.MAX_VALUE if trouble). */ public short readShort(int col, int row) throws IOException { return Math2.narrowToShort(String2.parseInt(readString(col, row))); }
/** This reads a byte from the file (or Byte.MAX_VALUE if trouble). */ public byte readByte(int col, int row) throws IOException { return Math2.narrowToByte(String2.parseInt(readString(col, row))); }
/** * This converts the double to text and then to byte[DOUBLE_LENGTH] then writes it to the file. * Later, use readDouble to read the value from the file. */ public void writeDouble(int col, int row, double d) throws IOException { write(col, row, String2.toByteArray(String2.right("" + d, DOUBLE_LENGTH))); }
/** * This converts the float to text and then to byte[FLOAT_LENGTH] then writes it to the file. * Later, use readFloat to read the value from the file. */ public void writeFloat(int col, int row, float f) throws IOException { write(col, row, String2.toByteArray(String2.right("" + f, FLOAT_LENGTH))); }
/** * This tests this class. * * @throws Throwable if trouble. */ public static void test() throws Throwable { String2.log("\nPersistentTable.test()"); verbose = true; reallyVerbose = true; int n; long time; // find longest FLOAT_LENGTH String s = ("" + Float.MIN_VALUE * -4f / 3f); int longest = s.length(); String longestS = s; for (int i = 0; i < 1000; i++) { s = "" + ((float) Math.random() / -1e10f); if (s.length() > longest) { longest = s.length(); longestS = s; } } String2.log("float longestS=" + longestS + " length=" + longest); Test.ensureTrue(longest <= 15, ""); // find longest DOUBLE_LENGTH s = ("" + Double.MIN_VALUE * -4.0 / 3.0); longest = s.length(); longestS = s; for (int i = 0; i < 1000; i++) { s = "" + (Math.random() / -1e150); if (s.length() > longest) { longest = s.length(); longestS = s; } } String2.log("double longestS=" + longestS + " length=" + longest); Test.ensureTrue(longest <= 24, ""); // make a new table String name = EDStatic.fullTestCacheDirectory + "testPersistentTable.txt"; File2.delete(name); int widths[] = { BOOLEAN_LENGTH, BYTE_LENGTH, BINARY_BYTE_LENGTH, BINARY_CHAR_LENGTH, SHORT_LENGTH, BINARY_SHORT_LENGTH, INT_LENGTH, BINARY_INT_LENGTH, LONG_LENGTH, BINARY_LONG_LENGTH, FLOAT_LENGTH, BINARY_FLOAT_LENGTH, DOUBLE_LENGTH, BINARY_DOUBLE_LENGTH, 20 }; PersistentTable pt = new PersistentTable(name, "rw", widths); Test.ensureEqual(pt.nRows(), 0, ""); Test.ensureEqual(pt.addRows(2), 2, ""); String testS = "Now is the time f\u0F22r all good countrymen to come ..."; pt.writeBoolean(0, 0, true); pt.writeBoolean(0, 1, false); pt.writeByte(1, 0, Byte.MIN_VALUE); pt.writeByte(1, 1, Byte.MAX_VALUE); pt.writeBinaryByte(2, 0, Byte.MIN_VALUE); pt.writeBinaryByte(2, 1, Byte.MAX_VALUE); pt.writeBinaryChar(3, 0, ' '); // hard because read will trim it to "" pt.writeBinaryChar(3, 1, '\u0F22'); pt.writeShort(4, 0, Short.MIN_VALUE); pt.writeShort(4, 1, Short.MAX_VALUE); pt.writeBinaryShort(5, 0, Short.MIN_VALUE); pt.writeBinaryShort(5, 1, Short.MAX_VALUE); pt.writeInt(6, 0, Integer.MIN_VALUE); pt.writeInt(6, 1, Integer.MAX_VALUE); pt.writeBinaryInt(7, 0, Integer.MIN_VALUE); pt.writeBinaryInt(7, 1, Integer.MAX_VALUE); pt.writeLong(8, 0, Long.MIN_VALUE); pt.writeLong(8, 1, Long.MAX_VALUE); pt.writeBinaryLong(9, 0, Long.MIN_VALUE); pt.writeBinaryLong(9, 1, Long.MAX_VALUE); pt.writeFloat(10, 0, -Float.MAX_VALUE); pt.writeFloat(10, 1, Float.NaN); pt.writeBinaryFloat(11, 0, -Float.MAX_VALUE); pt.writeBinaryFloat(11, 1, Float.NaN); pt.writeDouble(12, 0, -Double.MAX_VALUE); pt.writeDouble(12, 1, Double.NaN); pt.writeBinaryDouble(13, 0, -Double.MAX_VALUE); pt.writeBinaryDouble(13, 1, Double.NaN); pt.writeString(14, 0, ""); pt.writeString(14, 1, testS); Test.ensureEqual(pt.readBoolean(0, 0), true, ""); Test.ensureEqual(pt.readBoolean(0, 1), false, ""); Test.ensureEqual(pt.readByte(1, 0), Byte.MIN_VALUE, ""); Test.ensureEqual(pt.readByte(1, 1), Byte.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryByte(2, 0), Byte.MIN_VALUE, ""); Test.ensureEqual(pt.readBinaryByte(2, 1), Byte.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryChar(3, 0), ' ', ""); Test.ensureEqual(pt.readBinaryChar(3, 1), '\u0F22', ""); Test.ensureEqual(pt.readShort(4, 0), Short.MIN_VALUE, ""); Test.ensureEqual(pt.readShort(4, 1), Short.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryShort(5, 0), Short.MIN_VALUE, ""); Test.ensureEqual(pt.readBinaryShort(5, 1), Short.MAX_VALUE, ""); Test.ensureEqual(pt.readInt(6, 0), Integer.MIN_VALUE, ""); Test.ensureEqual(pt.readInt(6, 1), Integer.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryInt(7, 0), Integer.MIN_VALUE, ""); Test.ensureEqual(pt.readBinaryInt(7, 1), Integer.MAX_VALUE, ""); Test.ensureEqual(pt.readLong(8, 0), Long.MIN_VALUE, ""); Test.ensureEqual(pt.readLong(8, 1), Long.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryLong(9, 0), Long.MIN_VALUE, ""); Test.ensureEqual(pt.readBinaryLong(9, 1), Long.MAX_VALUE, ""); Test.ensureEqual(pt.readFloat(10, 0), -Float.MAX_VALUE, ""); Test.ensureEqual(pt.readFloat(10, 1), Float.NaN, ""); Test.ensureEqual(pt.readBinaryFloat(11, 0), -Float.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryFloat(11, 1), Float.NaN, ""); Test.ensureEqual(pt.readDouble(12, 0), -Double.MAX_VALUE, ""); Test.ensureEqual(pt.readDouble(12, 1), Double.NaN, ""); Test.ensureEqual(pt.readBinaryDouble(13, 0), -Double.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryDouble(13, 1), Double.NaN, ""); Test.ensureEqual(pt.readString(14, 0), "", ""); // only 18 char returned because one takes 3 bytes in UTF-8 Test.ensureEqual(pt.readString(14, 1), testS.substring(0, 18), ""); pt.close(); // reopen the file data still there? pt = new PersistentTable(name, "rw", widths); Test.ensureEqual(pt.nRows(), 2, ""); Test.ensureEqual(pt.readBoolean(0, 0), true, ""); Test.ensureEqual(pt.readBoolean(0, 1), false, ""); Test.ensureEqual(pt.readByte(1, 0), Byte.MIN_VALUE, ""); Test.ensureEqual(pt.readByte(1, 1), Byte.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryByte(2, 0), Byte.MIN_VALUE, ""); Test.ensureEqual(pt.readBinaryByte(2, 1), Byte.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryChar(3, 0), ' ', ""); Test.ensureEqual(pt.readBinaryChar(3, 1), '\u0F22', ""); Test.ensureEqual(pt.readShort(4, 0), Short.MIN_VALUE, ""); Test.ensureEqual(pt.readShort(4, 1), Short.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryShort(5, 0), Short.MIN_VALUE, ""); Test.ensureEqual(pt.readBinaryShort(5, 1), Short.MAX_VALUE, ""); Test.ensureEqual(pt.readInt(6, 0), Integer.MIN_VALUE, ""); Test.ensureEqual(pt.readInt(6, 1), Integer.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryInt(7, 0), Integer.MIN_VALUE, ""); Test.ensureEqual(pt.readBinaryInt(7, 1), Integer.MAX_VALUE, ""); Test.ensureEqual(pt.readLong(8, 0), Long.MIN_VALUE, ""); Test.ensureEqual(pt.readLong(8, 1), Long.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryLong(9, 0), Long.MIN_VALUE, ""); Test.ensureEqual(pt.readBinaryLong(9, 1), Long.MAX_VALUE, ""); Test.ensureEqual(pt.readFloat(10, 0), -Float.MAX_VALUE, ""); Test.ensureEqual(pt.readFloat(10, 1), Float.NaN, ""); Test.ensureEqual(pt.readBinaryFloat(11, 0), -Float.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryFloat(11, 1), Float.NaN, ""); Test.ensureEqual(pt.readDouble(12, 0), -Double.MAX_VALUE, ""); Test.ensureEqual(pt.readDouble(12, 1), Double.NaN, ""); Test.ensureEqual(pt.readBinaryDouble(13, 0), -Double.MAX_VALUE, ""); Test.ensureEqual(pt.readBinaryDouble(13, 1), Double.NaN, ""); Test.ensureEqual(pt.readString(14, 0), "", ""); // only 18 char returned because one takes 3 bytes in UTF-8 Test.ensureEqual(pt.readString(14, 1), testS.substring(0, 18), ""); pt.close(); String modes[] = {"rw", "rw", "rws", "rwd"}; n = 1000; for (int mode = 0; mode < modes.length; mode++) { File2.delete(name); pt = new PersistentTable( name, modes[mode], new int[] {80, BINARY_DOUBLE_LENGTH, DOUBLE_LENGTH, BINARY_INT_LENGTH, INT_LENGTH}); pt.addRows(n); if (mode == 1) String2.log("*** Note: 2nd rw test uses flush()"); // string speed test time = System.currentTimeMillis(); long modeTime = System.currentTimeMillis(); for (int i = 0; i < n; i++) pt.writeString(0, i, testS + i); if (mode == 1) pt.flush(); time = System.currentTimeMillis(); String2.log( "\n" + modes[mode] + " time to write " + n + " Strings=" + (System.currentTimeMillis() - time) + " (" + new int[] {0, 0, 0, 0}[mode] + "ms)"); // java 1.6 0,0,0,0 for (int i = 0; i < n; i++) { int tRow = Math2.random(n); Test.ensureEqual(pt.readString(0, tRow), testS + tRow, ""); } String2.log( modes[mode] + " time to read " + n + " Strings=" + (System.currentTimeMillis() - time) + " (" + new int[] {15, 16, 47, 15}[mode]
/** This reads a float from the file (or Float.NaN if trouble). */ public float readFloat(int col, int row) throws IOException { return String2.parseFloat(readString(col, row)); }
/** This reads a double from the file (or Double.NaN if trouble). */ public double readDouble(int col, int row) throws IOException { return String2.parseDouble(readString(col, row)); }
/** * This converts the int to text and then to byte[INT_LENGTH] then writes it to the file. Later, * use readInt to read the value from the file. */ public void writeInt(int col, int row, int i) throws IOException { write(col, row, String2.toByteArray(String2.right("" + i, INT_LENGTH))); }
/** * This converts the byte to text and then to byte[BYTE_LENGTH] then writes it to the file. Later, * use readByte to read the value from the file. */ public void writeByte(int col, int row, byte b) throws IOException { write(col, row, String2.toByteArray(String2.right("" + b, BYTE_LENGTH))); }
/** * This converts the long to text and then to byte[LONG_LENGTH] then writes it to the file. Later, * use readLong to read the value from the file. */ public void writeLong(int col, int row, long i) throws IOException { write(col, row, String2.toByteArray(String2.right("" + i, LONG_LENGTH))); }
/** * This is used when called from within a program. If args is null or args.length is 0, this * loops; otherwise it returns when done. * * @param args if args has values, they are used to answer the questions. * @returns the contents of outFileName (will be "" if trouble) */ public String doIt(String args[], boolean loop) throws Throwable { File2.safeRename(logFileName, logFileName + ".previous"); if (File2.isFile(outFileName)) { try { File2.rename(outFileName, outFileName + ".previous"); } catch (Throwable t) { File2.delete(outFileName); } } String2.setupLog( true, false, // toSystemOut, toSystemErr logFileName, false, // logToStringBuffer true, 20000000); // append String2.log( "*** Starting DasDds " + Calendar2.getCurrentISODateTimeStringLocal() + "\n" + "logFile=" + String2.logFileName() + "\n" + String2.standardHelpAboutMessage()); outFile = new FileWriter(outFileName); // default charset // delete the old log files (pre 1.48 names) File2.delete(EDStatic.fullLogsDirectory + "DasDdsLog.txt"); File2.delete(EDStatic.fullLogsDirectory + "DasDdsLog.txt.previous"); String datasetID = ""; if (args == null) args = new String[0]; // look for -verbose (and remove it) boolean verbose = false; // actually controls reallyVerbose int vi = String2.indexOf(args, "-verbose"); if (vi >= 0) { String2.log("verbose=true"); verbose = true; StringArray sa = new StringArray(args); sa.remove(vi); args = sa.toArray(); } do { // get the EDD type // EDD.reallyVerbose = false; //sometimes while testing datasetID = get( args, 0, "\n*** DasDds ***\n" + "This generates the DAS and DDS for a dataset and puts it in\n" + outFileName + "\n" + "Press ^D or ^C to exit at any time.\n\n" + "Which datasetID", datasetID); if (datasetID == null) { String2.flushLog(); outFile.flush(); outFile.close(); return String2.readFromFile(outFileName)[1]; } // delete the datasetInfo files for this datasetID (in case incorrect info) try { String dir = EDD.datasetDir(datasetID); String2.log( "dataset dir=" + dir + "\n" + "dataset n files not deleted = " + RegexFilenameFilter.regexDelete(dir, ".*", false)); } catch (Throwable t) { String2.log( "\n*** An error occurred while deleting the old info for " + datasetID + ":\n" + MustBe.throwableToString(t)); } try { printToBoth(EDD.testDasDds(datasetID, verbose)); } catch (Throwable t) { String2.log( "\n*** An error occurred while trying to load " + datasetID + ":\n" + MustBe.throwableToString(t)); } String2.flushLog(); } while (loop && args.length == 0); outFile.flush(); outFile.close(); String ret = String2.readFromFile(outFileName)[1]; String2.returnLoggingToSystemOut(); return ret; }
/** * This converts the short to text and then to byte[SHORT_LENGTH] then writes it to the file. * Later, use readShort to read the value from the file. */ public void writeShort(int col, int row, short s) throws IOException { write(col, row, String2.toByteArray(String2.right("" + s, SHORT_LENGTH))); }