package com.bytezone.diskbrowser.wizardry; import java.util.ArrayList; import java.util.List; import com.bytezone.diskbrowser.applefile.AbstractFile; import com.bytezone.diskbrowser.utilities.HexFormatter; // -----------------------------------------------------------------------------------// class MessageDataBlock extends AbstractFile // -----------------------------------------------------------------------------------// { final int firstMessageNo; final int lastMessageNo; private final int groupCount; private final List messages = new ArrayList<> (); private final Huffman huffman; // ---------------------------------------------------------------------------------// MessageDataBlock (String name, byte[] buffer, int firstMessageNo, Huffman huffman) // ---------------------------------------------------------------------------------// { super (name, buffer); this.firstMessageNo = firstMessageNo; this.huffman = huffman; int ptr = 0x1FF; // last byte in block groupCount = buffer[ptr--] & 0xFF; int currentMessageNo = firstMessageNo; int totalMessageBytes = firstMessageNo == 1 ? 4 : 0; for (int i = 0, max = groupCount - 1; i < groupCount; i++, max--) { int huffBytes = buffer[ptr]; for (int j = 0; j < huffBytes; j++) { int messageLength = buffer[ptr - j - 1] & 0xFF; totalMessageBytes += messageLength; Message message = new Message (currentMessageNo + j, totalMessageBytes - messageLength, messageLength); messages.add (message); } ptr -= huffBytes; currentMessageNo += huffBytes; ptr--; if (max > 0) { byte gap = buffer[ptr--]; int skip = gap & 0xFF; if ((gap & 0x80) != 0) // is high bit set? { gap &= 0x7F; int gap2 = buffer[ptr--] & 0xFF; skip = gap * 256 + gap2; } skip--; currentMessageNo += skip; } } if (currentMessageNo > firstMessageNo) { lastMessageNo = currentMessageNo - 1; // this.name += " - " + (currentMessageNo - 1); } else lastMessageNo = firstMessageNo; // this.name += " - " + lastMessageNo; setName (getName () + " - " + lastMessageNo); } // ---------------------------------------------------------------------------------// byte[] getMessage (int messageNo) // ---------------------------------------------------------------------------------// { for (Message message : messages) if (message.msgNo == messageNo) { byte[] returnMessage = new byte[message.length]; System.arraycopy (buffer, message.offset, returnMessage, 0, message.length); return returnMessage; } return null; } // ---------------------------------------------------------------------------------// String getText (int messageNo) // ---------------------------------------------------------------------------------// { for (Message message : messages) if (message.msgNo == messageNo) { byte[] returnMessage = new byte[message.length]; System.arraycopy (buffer, message.offset, returnMessage, 0, message.length); return huffman.decodeMessage (returnMessage); } return null; } // ---------------------------------------------------------------------------------// @Override public String getText () // ---------------------------------------------------------------------------------// { if (messages.size () == 0) return "No Messages"; if (huffman == null) return toString (); StringBuilder text = new StringBuilder (); int lastMessageNo = messages.get (0).msgNo - 1; for (Message message : messages) { if (message.msgNo != lastMessageNo + 1) text.append ("\n"); lastMessageNo = message.msgNo; byte[] returnMessage = new byte[message.length]; System.arraycopy (buffer, message.offset, returnMessage, 0, message.length); text.append (String.format ("%5d %s%n", message.msgNo, huffman.decodeMessage (returnMessage))); } if (text.length () > 0) text.deleteCharAt (text.length () - 1); return text.toString (); } // ---------------------------------------------------------------------------------// @Override public String toString () // ---------------------------------------------------------------------------------// { StringBuilder text = new StringBuilder (); for (Message message : messages) { text.append (message); text.append ("\n"); } if (text.length () > 0) text.deleteCharAt (text.length () - 1); return text.toString (); } // ---------------------------------------------------------------------------------// class Message // ---------------------------------------------------------------------------------// { final int msgNo; final int offset; final int length; public Message (int msgNo, int offset, int length) { this.msgNo = msgNo; this.offset = offset; this.length = length; } @Override public String toString () { StringBuilder text = new StringBuilder (); String data = HexFormatter.format (buffer, offset, length); text.append (String.format ("%5d: %03X %02X : %s", msgNo, offset, length, data)); return text.toString (); } } }