package com.bytezone.diskbrowser.applefile; import static com.bytezone.diskbrowser.utilities.Utility.ASCII_BACKSPACE; import static com.bytezone.diskbrowser.utilities.Utility.ASCII_CR; import static com.bytezone.diskbrowser.utilities.Utility.ASCII_LF; import static com.bytezone.diskbrowser.utilities.Utility.getIndent; import static com.bytezone.diskbrowser.utilities.Utility.isHighBitSet; import static com.bytezone.diskbrowser.utilities.Utility.unsignedShort; import com.bytezone.diskbrowser.gui.BasicPreferences; // -----------------------------------------------------------------------------------// public class AppleBasicFormatter extends BasicFormatter // -----------------------------------------------------------------------------------// { private static final int LEFT_MARGIN = 5; private static final int RIGHT_MARGIN = 33; // ---------------------------------------------------------------------------------// public AppleBasicFormatter (ApplesoftBasicProgram program, BasicPreferences basicPreferences) // ---------------------------------------------------------------------------------// { super (program, basicPreferences); } // ---------------------------------------------------------------------------------// @Override public void append (StringBuilder fullText) // ---------------------------------------------------------------------------------// { int loadAddress = getLoadAddress (); int ptr = 0; int linkField; StringBuilder currentLine = new StringBuilder (); while ((linkField = unsignedShort (buffer, ptr)) != 0) { int lineNumber = unsignedShort (buffer, ptr + 2); currentLine.append (String.format (" %d ", lineNumber)); ptr += 4; if (basicPreferences.appleLineWrap) ptr = wrapLine (currentLine, ptr); else ptr = flatLine (currentLine, ptr); if (ptr != (linkField - loadAddress)) System.out.printf ("%s: ptr: %04X, nextLine: %04X%n", program.name, ptr + loadAddress, linkField); currentLine.append (NEWLINE); fullText.append (currentLine); currentLine.setLength (0); } } // ---------------------------------------------------------------------------------// private int flatLine (StringBuilder currentLine, int ptr) // ---------------------------------------------------------------------------------// { byte b; while ((b = buffer[ptr++]) != 0) if (isHighBitSet (b)) { String token = String.format (" %s ", ApplesoftConstants.tokens[b & 0x7F]); currentLine.append (token); } else switch (b) { case ASCII_CR: currentLine.append (NEWLINE); break; case ASCII_BACKSPACE: if (currentLine.length () > 0) currentLine.deleteCharAt (currentLine.length () - 1); break; case ASCII_LF: int indent = getIndent (currentLine); currentLine.append ("\n"); for (int i = 0; i < indent; i++) currentLine.append (" "); break; default: currentLine.append ((char) b); } return ptr; } // ---------------------------------------------------------------------------------// private int wrapLine (StringBuilder currentLine, int ptr) // ---------------------------------------------------------------------------------// { byte b; int cursor = currentLine.length (); while ((b = buffer[ptr++]) != 0) if (isHighBitSet (b)) { String token = String.format (" %s ", ApplesoftConstants.tokens[b & 0x7F]); currentLine.append (token); cursor = incrementCursor (currentLine, cursor, token.length ()); } else switch (b) { case ASCII_CR: currentLine.append (NEWLINE); cursor = 0; break; case ASCII_BACKSPACE: if (cursor > 0) { currentLine.deleteCharAt (currentLine.length () - 1); --cursor; } break; case ASCII_LF: currentLine.append ("\n"); for (int i = 0; i < cursor; i++) currentLine.append (" "); break; default: currentLine.append ((char) b); cursor = incrementCursor (currentLine, cursor, 1); } return ptr; } // ---------------------------------------------------------------------------------// private int incrementCursor (StringBuilder currentLine, int cursor, int size) // ---------------------------------------------------------------------------------// { assert size <= 9; // longest token possible (7 plus 2 spaces) cursor += size; if ((cursor) >= RIGHT_MARGIN) { cursor = cursor >= 40 ? cursor - 40 : LEFT_MARGIN; currentLine.append ("\n ".substring (0, cursor + 1)); } return cursor; } }