Java tutorial
import java.math.BigDecimal; /* * Dump.java * * Projeto ECFbabel * * Copyright 2005-2007 Daniel "Spanazzi" Gonalves * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Fornece mtodos para produo de dumps hexadecimais a partir de arrays de bytes ou * de inteiros (inteiros representando bytes sem sinal, entre 0 e 255). Um dump * hexadecimal produzido pelo mtodo <code>dump(byte[])</code> parecido com o * seguinte exemplo: * * <pre> * Titulo do dump aqui * 000000 38 19 4A 14 F9 12 91 52-73 89 BA F9 F3 2E 00 CC 8.J....Rs....... * 000010 FB 37 7A 88 35 87 30 47-39 C1 DD D6 C9 F5 1F 11 .7z.5.0G9....... * 000020 E6 A6 C1 7D 4E 27 C1 A6-55 17 99 34 19 17 30 C9 ...}N'..U..4..0. * 000030 CC 68 C4 2B 74 2B 83 9D-59 15 3B 86 B9 F1 9D 07 .h.+t+..Y.;..... * 000040 9F 14 99 AE C6 A2 C6 40-EC 27 2C 55 61 F7 2A 63 .......@.',Ua.*c * 000050 8C AD 82 22 68 11 CE 24-41 9C 8B 93 DA AA 62 3C ..."h..$A.....b< * 000060 C5 17 BD 49 6F 19 E4 F7-9D 3B 4C 33 14 15 81 66 ...Io....;L3...f * 000070 97 BA A4 29 70 B2 81 04-35 08 AA 6D 8D 6E 6F 54 ...)p...5..m.noT * 000080 9C DA 6A 28 F6 B4 C2 D7-BD 01 D0 6C D7 CC 8D 04 ..j(.......l.... * 000090 29 BA 0F 87 21 B2 99 52-7B E5 19 5C 4D F7 6A 32 )...!..R{..\M.j2 * 0000A0 36 A4 77 58 33 67 54 EF-C0 62 3F 19 29 D6 A7 A2 6.wX3gT..b?.)... * 0000B0 77 54 B0 3E DE 3E 83 1B-FE 22 4E EF 8C F7 99 88 wT.>.>..."N..... * 0000C0 55 6B CE 9E 75 A3 50 B7-FA A5 59 2A 41 34 7D 56 Uk..u.P...Y*A4}V * 0000D0 FA E6 FD 0A 77 36 C5 52-C4 E3 ....w6.R.. * Dump: 218 byte(s) * </pre> * * <p>Tambm fornece diversos mtodos convenientes para log de dumps hexadecimais.</p> * * @since Outubro/2007 * * @version $Id: Dump.java,v 1.1.1.1 2008/03/12 03:29:34 rawfosgod Exp $ * * @author Daniel Gonalves */ public final class Dump { /** * Constri um buffer string contendo um <em>dumping</em> hexadecimal do array de * inteiros. * * @param data array de inteiros. Cada elemento do array dever ser um valor * que represente um byte sem sinal, entre 0 e 255, inclusive. */ public static String dump(final int[] data) { return dump(ByteUtils.itob(data)); } /** * Constri um buffer string contendo um <em>dumping</em> hexadecimal do array de * bytes especificado. * * @param data array de dados. * * @return buffer string contendo o dump hexadecimal. */ public static String dump(final byte[] data) { String eol = System.getProperty("line.separator"); StringBuilder buffer = new StringBuilder(); int offset = 0; int column = 0; StringBuilder hexDump = new StringBuilder(); StringBuilder chrDump = new StringBuilder(); for (int pos = 0; pos < data.length; pos++) { hexDump.append(hex((int) (data[pos] & 0xff), 2)); chrDump.append(chr((int) (data[pos] & 0xff))); column++; if (column > 15) { buffer.append(" ").append(hex(offset, 6)).append(" ").append(hexDump).append(" ").append(chrDump) .append(eol); column = 0; offset += 16; hexDump = new StringBuilder(); chrDump = new StringBuilder(); } else { if (column == 8) { // inclui um separador "-" entre a 8a. e 9a. colunas hexDump.append("-"); } else { // separa com 1 espao os valores hexadecimais dos bytes hexDump.append(" "); } } } if ((column != 0) && (column < 15)) { // completa a linha com espaos at a 16a. posio while (column < 16) { hexDump.append(" "); // 3 espaos chrDump.append(" "); // 1 espao column++; } // remove o ltimo espao da sequncia hexDump.deleteCharAt(hexDump.length() - 1); buffer.append(" ").append(hex(offset, 6)).append(" ").append(hexDump).append(" ").append(chrDump) .append(eol); } // inclui o rodap, indicando o total de bytes no dump buffer.append(" Dump: ").append(data.length).append(" byte(s).").append(eol); return buffer.toString(); } // dump(byte[]) /** * Retorna uma string de tamanho fixo, contendo a representao hexadecimal do valor. * * @param value valor inteiro, de base 10, a ser convertido para base 16. * * @param length comprimento total desejado. * * @return Representao hexadecimal do valor com o comprimento especificado. * A string resultante ser completada com zeros esquerda at que o * comprimento total desejado seja atingido. * Se a representao hexadecimal do valor resultar em um comprimento maior * que o especificado, a string resultante ser formada de asteriscos, * indicando que o comprimento especificado no foi suficiente para o valor. */ public static String hex(final int value, final int length) { StringBuilder str = new StringBuilder(Integer.toString(value, 16).toUpperCase()); if (str.length() < length) { int falta = (length - str.length()); for (int i = 1; i <= falta; i++) { str.insert(0, "0"); } } else if (str.length() > length) { str = new StringBuilder(); for (int i = 1; i <= length; i++) { str.append("*"); } } return str.toString(); } private static String chr(final int value) { if ((value < 32) || (value > 127)) { return "."; } return new String(new byte[] { (byte) (value & 0xff) }); } } // {{{ Dump }}} /* * ByteUtils.java * * Projeto ECFbabel * * Copyright 2005-2007 Daniel "Spanazzi" Gonalves * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * TODO: documentar! * * @since Setembro/2007 * * @version $Id: ByteUtils.java,v 1.1.1.1 2008/03/12 03:29:33 rawfosgod Exp $ * * @author Daniel Gonalves */ final class ByteUtils { private ByteUtils() { } /** * Retorna o byte de baixa ordem a partir de um valor inteiro. * * @param value valor inteiro (at 65535). * * @return byte de baixa ordem do valor. Por exemplo, o byte de * baixa ordem para o valor 1234 210. */ public static int lo(final int value) { int low = value; if (value > 255) low = Math.abs(value % 256); return low; } /** * Retorna o byte de alta ordem a partir de um valor inteiro. * * @param value valor inteiro (at 65535). * * @return byte de alta ordem do valor. Por exemplo, o byte de * alta ordem para o valor 1234 4. */ public static int hi(final int value) { int high = 0; if (value > 255) high = Math.abs((int) (value / 256)); return high; } /** * Converte 2 bytes sem sinal no formato Intel Low/High para um inteiro. * Como no exemplo: * * <pre> * int valor = 1234; // '100 1101 0010' * int hi = ByteUtils.hi(valor); // resulta: 4 '100' * int lo = ByteUtils.lo(valor); // resulta: 210 '1101 0010' * int test = ByteUtils.hilo2int(hi, lo) // resulta: 1234 '100 1101 0010' * </pre> * * @param high byte de alta ordem (deve ser um valor entre 0 e 255 inclusive). * @param low byte de baixa ordem (deve ser um valor entre 0 e 255 inclusive). * * @return valor inteiro at 65535 representados pelos bytes de alta e baixa ordem. */ public static int hilo2int(int high, int low) { return (low | (high << 8)); } public static byte[] itob(int[] ints) { byte[] bytes = new byte[ints.length]; for (int i = 0; i < ints.length; i++) bytes[i] = (byte) (ints[i] & 0xff); return bytes; } public static int[] btoi(byte[] bytes) { int[] ints = new int[bytes.length]; for (int i = 0; i < bytes.length; i++) ints[i] = (int) (bytes[i] & 0xff); return ints; } /** * Extrai o valor ASCII de um determinado caracter de uma string. Por exemplo: * * <pre> * ByteUtils.ascval("ABC", 0); // resulta: 65 * ByteUtils.ascval("ABC", 1); // resulta: 66 * ByteUtils.ascval("ABC", 2); // resulta: 67 * </pre> * * @param s a string alvo. * * @param pos a posio a ser extrado o valor ASCII. * * @return o valor ASCII do caracter na posio <code>pos</code> da string * <code>s</code>. * * @throws IndexOutOfBoundsException se a posio indicada for menor que zero ou * maior que o tamanho da string <code>s.length() - 1</code>. */ public static int ascval(String s, int pos) { return (int) ((((byte) (s.charAt(pos))) & 0xff)); } /** * Converte uma string contendo uma sequncia decimal codificada em BCD * (<em>Binary-Coded Decimal</em> ?). Esta implementao foi obtida a partir da * descrio da codificao BCD encontrada no manual de programao das * impressoras fiscais Bematech® MP-20 FI II. * * <p>Se os valores ASCII dos caracteres de uma string forem <code>0x12, 0x34 e * 0x56</code>, ento <code>bcd(s, 2)</code> resultar no valor decimal * <code>1234.56</code>.</p> * * @param s a string contendo a sequncia BCD. * * @param scale o nmero de casas decimais a serem considerados. Se este * argumento for menor ou igual a zero, ser considerado um valor * inteiro. * * @return um objeto <code>java.math.BigDecimal</code> contendo o valor * decimal decodificado. * * @throws NumberFormatException se a string <code>s</code> no representar * uma sequncia BCD vlida. */ public static BigDecimal bcd(final String s, final int scale) { StringBuilder hexval = new StringBuilder(); // converte os valores ASCII da string para hexadecimal for (int i = 0; i < s.length(); i++) { StringBuilder hex = new StringBuilder(Integer.toString(ascval(s, i), 16)); if (hex.length() != 2) hex.insert(0, "0"); hexval.append(hex); } if (scale > 0) { if (scale > hexval.length()) { // completa com zeros antes da posio de insero do ponto decimal int count = scale - hexval.length(); for (int i = 1; i <= count; i++) hexval.insert(0, "0"); } // insere um ponto decimal na posio indicada hexval.insert(hexval.length() - scale, "."); } return new BigDecimal(hexval.toString()); } } // {{{ ByteUtils }}}