Package com.slytechs.utils.format

Source Code of com.slytechs.utils.format.NumberUtils

/**
* $Id$
*
* Copyright (C) 2006 Mark Bednarczyk, Sly Technologies, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place,
* Suite 330, Boston,
* MA 02111-1307 USA
*
*/
package com.slytechs.utils.format;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Timestamp;
import java.util.Enumeration;

import com.slytechs.utils.net.Address;
import com.slytechs.utils.net.IpAddress;
import com.slytechs.utils.net.MacAddress;

/**
* Utility class with various number formating routines.
*
* @author Mark Bednarczyk
* @author Sly Technologies, Inc.
*/
public class NumberUtils {
  public static final String NONPRINTABLE_CHAR = ".";
  public static final String NEWLINE_CHAR = "\n";
  public static final String SPACE_CHAR = " "; // Could be different in the future

  public static final String space =
    "                                                                           "
    + "                                                                           "
    + "                                                                           "
    + "                                                                           ";


  /**
   * String padding routine
   */
  public static String pad(String s, int count) {
    if (s.length() < count) {
      return (s + space.substring(0, count - s.length()));
    }

    return s;
  }

  /**
   * String padding routine
   */
  public static String padSuffix(String s, int count) {
    if (s.length() < count) {
      return (space.substring(0, count - s.length()) + s);
    }

    return s;
  }


  /******************************************************
   ***    number parsing
   ******************************************************/

  public static long longValue(byte[] b) {

    long v = 0L;

    for(int i = 0; i < b.length & i < 8; i ++)
      v |= (b[i] < 0 ? (long)b[i] + 256 : (long)b[i]) << ((b.length - i -1) * 8);

    return(v);
  }

  public static Address parseAddress(String word) {

    Address r = null;
    /**
     * Try parsing Ipv4 address.
     */
    String[] c;
    if ( (c = word.split("\\.")).length == 4) {
      r = new IpAddress(parseIntoArray(new byte[4], c, 10));

    } else if ( (c = word.split(":")).length == 16) {
      r = new IpAddress(parseIntoArray(new byte[16], c, 16));

    } else if ( (c = word.split("-")).length == 6 || (c = word.split(":")).length == 6) {
      r = new MacAddress(parseIntoArray(new byte[6], c, 16));

    } else if (c.length > 1) { // Catch all. Allow any type of address separated :
      r = new Address(parseIntoArray(new byte[c.length], c, 16));
    }
    else
      return null;
    
    return r;
  }

  public static byte[] parseIntoArray(byte[] r, String[] c, int radix) {
    try {
      for(int i = 0; i < r.length; i ++)
        r[i] = (byte)Integer.parseInt(c[i], radix);
    }
    catch(NumberFormatException n) {
      return null;
    }

    return r;
  }

  public static Number parseNumber(String word) {

    if(word == null || word.length() == 0)
      return(null);

    int sign = 1;
    int radix = 10;
    Number number = null;
    char last;

    /**
     * Check for negative number.
     */
    if(word.charAt(0) == '-') {
      sign = -1;
      word = word.substring(1);
    }

    if(word.length() == 0)
      return(null);


    /**
     * Check for positive number
     */
    if(word.charAt(0) == '+') {
      sign = 1;
      word = word.substring(1);
    }

    if(word.length() == 0)
      return(null);

    /**
     * Now make sure we might have a number.
     */
    if(Character.isDigit(word.charAt(0)) == false)
      return(null);

    if(word.charAt(0) == '0' && word.length() > 1) {
      if(word.charAt(1) == 'x')
        radix = 16;

      else if(word.charAt(1) == 'o')
        radix = 8;

      else if(word.charAt(1) == 'b')
        radix = 2;

      if(radix != 10)
        word = word.substring(2);

      if(word.length() == 0)
        return(null);

    }



    /**
     * Check for floating point.
     */
    else if(word.indexOf('.') != -1 || word.indexOf('f') != -1 || word.indexOf('e') != -1) {
      last = word.charAt(word.length()-1);

      /**
       * Check for float
       */
      if(last == 'f' || last == 'F') {
        word = word.substring(0, word.length() - 1);

        if(word.length() == 0)
          return(null);


        try { return(number = new Float(Float.parseFloat(word) * sign)); }
        catch(NumberFormatException n) {
          return(null);
        }

      }

      try { number = new Double(Double.parseDouble(word) * sign); }
      catch(NumberFormatException n) {
        return(null);
      }

      return(number);

    }

    last = word.charAt(word.length()-1);
    if(last == 'l' || last == 'L') {
      word = word.substring(0, word.length() - 1);

      if(word.length() == 0)
        return(null);


      try { return(number = new Long(Long.parseLong(word, radix) * sign)); }
      catch(NumberFormatException n) {
        return(null);
      }
    }

    try { return(number = new Integer(Integer.parseInt(word, radix) * sign)); }
    catch(NumberFormatException n) {
      return(null);
    }
  }



  /******************************************************
   ***    HEXDUMP methods.
   ******************************************************/

  public static Enumeration hexdumpEnumerator(byte[] data) {
    return(hexdumpEnumerator(data, "", true, 0, 0));
  }
  public static Enumeration hexdumpEnumerator(byte[] data, String prefix, boolean indentFirstLine) {
    return(hexdumpEnumerator(data, prefix, indentFirstLine, 0, 0));
  }
  public static Enumeration hexdumpEnumerator(byte[] data, String prefix, boolean indentFirstLine, int addressOffset, int dataOffset) {
    return(new HexdumpEnumerator(data, prefix, indentFirstLine, addressOffset, dataOffset));
  }

  public static String hexdump(byte[] a) {
    return(hexdump(a, "", true, 0, 0));
  }

  public static String hexdump(byte[] a, String prefix, boolean indentFirstLine) {
    return(hexdump(a, prefix, indentFirstLine, 0, 0));
  }

  private static String hexdump(byte[] a, String prefix, boolean indentFirstLine, int addressOffset, int dataOffset) {
    String s = "";

    for(int i = 0; i + dataOffset < a.length; i += 16) {
      if(i == 0 && indentFirstLine == false)
        s += hexLine(a, "", i + addressOffset, i + dataOffset);
      else
        s += hexLine(a, prefix, i + addressOffset, i + dataOffset);

      if( i + dataOffset +16 < a.length)
        s += NEWLINE_CHAR;
    }

    return(s);
  }

  public static String hexLine(byte[] a, String prefix, int address, int i) {
    String s = "";

    s += prefix;
    s += hexLineAddress(address);
    s += ":" + SPACE_CHAR;

    s += hexLineData(a, i);
    s += SPACE_CHAR;
    s += SPACE_CHAR;
    s += SPACE_CHAR;

    s += hexLineText(a, i);

    return(s);
  }


  public static String hexLineText(byte[] data, int offset) {

    String s = "";

    int i;
    for(i = 0; i + offset < data.length && i < 16; i ++) {
      s += table[data[i + offset] & 0xFF];

//      if(Character.isLetterOrDigit(table[data[i + offset] & 0xFF]) ||
//         (table[data[i + offset] & 0xFF]) == ' ')
//        s += " " + table[data[i + offset] & 0xFF];
//      else
//        s += " " + NONPRINTABLE_CHAR;
    }

    /**
     * Continue the loop and fill in any missing
     * data less than 16 bytes.
     */
    for(; i < 16; i ++) {
      s += SPACE_CHAR;
    }

    return(s);
  }

  public static String hexLineAddress(int address) {
    String s = "";
     
    s = Integer.toHexString(address);

    for(int i = s.length(); i < 4; i ++)
      s = "0" + s;

    return(s);
  }

  public static String hexLineData(byte[] data, int offset) {
    String s = "";

    int i = 0;
    for(i = 0; i + offset < data.length && i < 16; i ++) {

      /**
       * Insert a space every 4 characaters.
       */
      if(i % 4 == 0 && i != 0)
        s += SPACE_CHAR;

      s += toHexString(data[i + offset]);
    }

    /**
     * Continue the loop and append spaces to fill in
     * the missing data.
     */
    for(; i < 16; i ++) {
      /**
       * Insert a space every 4 characaters.
       */
      if(i % 4 == 0 && i != 0)
        s += SPACE_CHAR;

      s += SPACE_CHAR + SPACE_CHAR;
    }

    return(s);
  }


  public static String toHexString(byte b) {
    String s = Integer.toHexString(((int)b) & 0xFF);

    if(s.length() == 1)
      return("0" + s);

    return(s);
  }

  static String[] table = new String[256];
  static {

    for(int i = 0; i < 31; i ++) {
      table[i] = "\\" + Integer.toHexString(i);
      if(table[i].length() == 2) table[i] += " ";
    }

    for(int i = 31; i < 127; i ++)
      table[i] = new String(new byte[] { (byte)i, ' ', ' ' });

    for(int i = 127; i < 256; i ++) {
      table[i] = "\\" + Integer.toHexString(i);
      if(table[i].length() == 2) table[i] += " ";
    }

    table[0] = "\\0 ";
    table[7] = "\\a ";
    table[11] = "\\v ";
    table['\b'] = "\\b ";
    table['\t'] = "\\t ";
    table['\n'] = "\\n ";
    table['\f'] = "\\f ";
    table['\r'] = "\\r ";
  }


  /**
   * Test function for NumberUtils
   * @param args command line arguments
   */
  public static void main(String [] args) {

    System.out.println(parseAddress(args[0]));

    if(true)
      return;

    Number number = parseNumber(args[0]);

    System.out.println("number=" + number);

    if(true)
      return;

    byte[] a = new byte[256];
    byte[] b = new byte[8];

    for(int i = 0; i < a.length; i ++) {
      a[i] = (byte)(i + 'A');
      if(i < 8)
        b[i] = (byte)(i + 'A');
    }

    byte[] c = new byte[32];
    InputStream in = null;
    try {
      in = new FileInputStream("abc");
//      in.read(c, 0, c.length);
    }
    catch(FileNotFoundException f) {
      f.printStackTrace();
    }





//    System.out.println("hexLineAddress=" + hexLineAddress(32));
//    System.out.println("hexLineData=" + hexLineData(a, 8));
//    System.out.println("hexLineText=" + hexLineText(a, 8));

//    System.out.println(hexLineAddress(32) + ": " + hexLineData(a, 8) + " " + hexLineText(a, 8));
//    System.out.println(hexLineAddress(0) + ": " + hexLineData(b, 4) + " " + hexLineText(b, 4));

//    System.out.println(hexdump(c));

//    Enumeration h = hexdumpEnumerator(c);
//    while(h.hasMoreElements()) {
//      System.out.println(h.nextElement());
//    }

      try {
      int i = 0;
      while( in.read(c, 0, c.length) != -1) {
        System.out.println(hexLine(c, "", i, 0));

        i += 16;
      }
      }
      catch(IOException ioe) {
        ioe.printStackTrace();
      }
  }

  /**
   * Utility class that manipulates Timestamps
   *
   * @return micros (10e6) seconds as the delta betwen t2 to and t1.
   */
  public static long timestampSubtract(Timestamp t1, Timestamp t2) {
    long milli1 = t1.getTime();
    int nano1 = t1.getNanos();

    long milli2 = t2.getTime();
    int nano2 = t2.getNanos();

    long microDelta = (((milli2 / 1000) - (milli1 / 1000)) * 1000000);

    microDelta += ((nano2 / 1000) - (nano1 / 1000));

    return(microDelta);
  }

  public static String timestampDeltaFormat(Timestamp t1, Timestamp t2) {
    return(timestampDeltaFormat(timestampSubtract(t1, t2)));
  }

  public static String timestampDeltaFormat(long micros) {
   
    if (micros < 0) {
      return "out-of-range";
    }
    String s = "";

    long secs = micros / 1000000;
    s += "" + (micros - (secs * 1000000));

    for(; s.length() < 6; s = "0" + s);

    s = "" + (secs) + "." + s;

    return(s);
  }


} /* END OF: NumberUtils */


/**
* Supporting top-level class to do Enumeration
* Enumerating through long lists of byte[] prevents
* huge strings since formated data is returned as strings.
*
*/
class HexdumpEnumerator implements Enumeration {
  private byte[] data = null;

  private int i = 0;
  private String prefix = "";
  private int addressOffset = 0;
  private int dataOffset = 0;
  private boolean indentFirstLine = true;

  protected HexdumpEnumerator(byte[] data, String prefix, boolean indentFirstLine, int addressOffset, int dataOffset) {
    this.data = data;
    this.prefix = prefix;
    this.addressOffset = addressOffset;
    this.dataOffset = dataOffset;
  }

  public boolean hasMoreElements() {
    return(i + dataOffset < data.length);
  }

  public Object nextElement() {

    String s = "";

    if(i == 0 && indentFirstLine == false)
      s += NumberUtils.hexLine(data, "", i + addressOffset, i + dataOffset);
    else
      s += NumberUtils.hexLine(data, prefix, i + addressOffset, i + dataOffset);

    i += 16;

    return(s);
  }
};
TOP

Related Classes of com.slytechs.utils.format.NumberUtils

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.