package com.bytezone.diskbrowser.applefile; import com.bytezone.diskbrowser.HexFormatter; public class ShapeTable extends AbstractFile { private static final int SIZE = 400; public ShapeTable (String name, byte[] buffer) { super (name, buffer); } @Override public String getText () { StringBuffer text = new StringBuffer (); int totalShapes = buffer[0] & 0xFF; int startPos = SIZE / 2; for (int i = 0; i < totalShapes; i++) { int offset = HexFormatter.intValue (buffer[i * 2 + 2], buffer[i * 2 + 3]); int[][] grid = new int[SIZE][SIZE]; int row = startPos; int col = row; if (i > 0) text.append ("\n"); text.append ("Shape " + i + " :\n"); while (buffer[offset] != 0) { int value = buffer[offset++] & 0xFF; int v1 = value >> 6; int v2 = (value & 0x38) >> 3; int v3 = value & 0x07; // System.out.printf ("%02X %02X %02X %02X%n", value, v1, v2, v3); if (v3 >= 4) { grid[row][col] = 1; grid[0][col]++; grid[row][0]++; } if (v3 == 0 || v3 == 4) row--; else if (v3 == 1 || v3 == 5) col++; else if (v3 == 2 || v3 == 6) row++; else col--; if (v2 >= 4) { grid[row][col] = 1; grid[0][col]++; grid[row][0]++; } if (v2 == 0 && v1 != 0) row--; else if (v2 == 4) row--; else if (v2 == 1 || v2 == 5) col++; else if (v2 == 2 || v2 == 6) row++; else if (v2 == 3 || v2 == 7) col--; if (v1 == 1) col++; else if (v1 == 2) row++; else if (v1 == 3) col--; } text.append ("\n"); int minRow = startPos, maxRow = startPos; int minCol = startPos, maxCol = startPos; for (row = 1; row < grid.length; row++) { if (grid[row][0] > 0) { if (row < minRow) minRow = row; if (row > maxRow) maxRow = row; } } for (col = 1; col < grid[0].length; col++) { if (grid[0][col] > 0) { if (col < minCol) minCol = col; if (col > maxCol) maxCol = col; } } for (row = minRow; row <= maxRow; row++) { for (col = minCol; col <= maxCol; col++) { if (col == startPos && row == startPos) text.append (grid[row][col] > 0 ? " @" : " ."); else if (grid[row][col] == 0) text.append (" "); else text.append (" X"); } text.append ("\n"); } } text.deleteCharAt (text.length () - 1); return text.toString (); } public static boolean isShapeTable (byte[] buffer) { if (buffer.length == 0 || buffer[buffer.length - 1] != 0) return false; int totalShapes = buffer[0] & 0xFF; if (totalShapes == 0) return false; int lastOffset = 0; for (int i = 0; i < totalShapes; i++) { // check index table entry is inside the file int ptr = i * 2 + 2; if (ptr >= buffer.length - 1) return false; // check index points inside the file int offset = HexFormatter.intValue (buffer[ptr], buffer[ptr + 1]); if (offset == 0 || offset < lastOffset || offset >= buffer.length) return false; lastOffset = offset; } return true; } }