dmolony-DiskBrowser/src/com/bytezone/diskbrowser/applefile/TextFile.java

189 lines
5.1 KiB
Java
Raw Normal View History

2015-06-01 09:35:51 +00:00
package com.bytezone.diskbrowser.applefile;
import java.util.List;
2016-02-24 21:11:14 +00:00
import com.bytezone.diskbrowser.utilities.HexFormatter;
2015-06-01 09:35:51 +00:00
public class TextFile extends AbstractFile
{
2017-02-01 21:15:30 +00:00
private int recordLength; // prodos aux
private List<TextBuffer> buffers; // only used if it is a Prodos text file
2015-06-01 09:35:51 +00:00
private int eof;
2017-02-01 21:15:30 +00:00
private boolean prodosFile;
2015-06-01 09:35:51 +00:00
public TextFile (String name, byte[] buffer)
{
super (name, buffer);
}
2017-02-01 21:15:30 +00:00
public TextFile (String name, byte[] buffer, int auxType, int eof)
2015-06-01 09:35:51 +00:00
{
this (name, buffer);
this.eof = eof;
2017-02-01 21:15:30 +00:00
recordLength = auxType;
prodosFile = true;
2015-06-01 09:35:51 +00:00
}
2017-02-01 21:15:30 +00:00
public TextFile (String name, List<TextBuffer> buffers, int auxType, int eof)
2015-06-01 09:35:51 +00:00
{
super (name, null);
this.buffers = buffers;
this.eof = eof;
2017-02-01 21:15:30 +00:00
recordLength = auxType;
prodosFile = true;
2015-06-01 09:35:51 +00:00
}
@Override
public String getHexDump ()
{
if (buffers == null)
return (super.getHexDump ());
StringBuilder text = new StringBuilder ();
for (TextBuffer tb : buffers)
{
for (int i = 0, rec = 0; i < tb.buffer.length; i += tb.reclen, rec++)
{
text.append ("\nRecord #" + (tb.firstRecNo + rec) + "\n");
text.append (HexFormatter.format (tb.buffer, i, tb.reclen) + "\n");
}
}
return text.toString ();
}
@Override
public String getText ()
{
StringBuilder text = new StringBuilder ();
text.append ("Name : " + name + "\n");
2017-02-01 21:15:30 +00:00
if (prodosFile)
2015-06-01 09:35:51 +00:00
{
text.append (String.format ("Record length : %,8d%n", recordLength));
text.append (String.format ("End of file : %,8d%n", eof));
}
else
text.append (String.format ("End of file : %,8d%n", buffer.length));
text.append ("\n");
// check whether file is spread over multiple buffers
if (buffers != null)
2017-04-26 08:04:48 +00:00
return treeFileText (text); // calls knownLength()
2015-06-01 09:35:51 +00:00
// check whether the record length is known
if (recordLength == 0)
return unknownLength (text);
2017-04-26 08:04:48 +00:00
text.append ("Offset Record# Text values\n");
2017-02-01 21:15:30 +00:00
text.append (
"------ ------- -------------------------------------------------------\n");
2015-06-01 09:35:51 +00:00
return knownLength (text, 0).toString ();
}
private String treeFileText (StringBuilder text)
{
2017-04-26 08:04:48 +00:00
text.append (" Offset Record# Text values\n");
text.append (
"---------- ------- -------------------------------------------------------\n");
2015-06-01 09:35:51 +00:00
for (TextBuffer tb : buffers)
{
2017-04-26 08:04:48 +00:00
buffer = tb.buffer;
2017-07-09 09:26:13 +00:00
text = knownLength (text, tb.firstRecNo);
2015-06-01 09:35:51 +00:00
}
return text.toString ();
}
private StringBuilder knownLength (StringBuilder text, int recNo)
{
for (int ptr = 0; ptr < buffer.length; ptr += recordLength)
{
if (buffer[ptr] == 0)
{
recNo++;
continue;
}
2017-07-09 09:26:13 +00:00
2015-06-01 09:35:51 +00:00
int len = buffer.length - ptr;
int bytes = len < recordLength ? len : recordLength;
while (buffer[ptr + bytes - 1] == 0)
bytes--;
2017-04-26 08:04:48 +00:00
if ((buffer[ptr + bytes - 1] & 0x7F) == 0x0D) // ignore CR
bytes--;
2017-07-09 09:26:13 +00:00
String line = HexFormatter.getString (buffer, ptr, bytes);
line = line.replaceAll ("\\n", "\n ");
text.append (
String.format ("%,10d %,8d %s%n", recNo * recordLength, recNo++, line));
2015-06-01 09:35:51 +00:00
}
2017-07-09 09:26:13 +00:00
2015-06-01 09:35:51 +00:00
return text;
}
private String unknownLength (StringBuilder text)
{
int nulls = 0;
int ptr = 0;
int size = buffer.length;
int lastVal = 0;
boolean newFormat = true;
2017-04-26 08:04:48 +00:00
boolean showAllOffsets = true;
2015-06-01 09:35:51 +00:00
if (newFormat)
{
2017-04-26 08:04:48 +00:00
text.append (" Offset Text values\n");
text.append ("---------- -------------------------------------------------------"
2017-02-01 21:15:30 +00:00
+ "-------------------\n");
2017-04-26 08:04:48 +00:00
if (buffer.length == 0)
2015-06-01 09:35:51 +00:00
return text.toString ();
2017-04-26 08:04:48 +00:00
if (buffer[0] != 0)
text.append (String.format ("%,10d ", ptr));
2015-06-01 09:35:51 +00:00
}
2017-04-26 08:04:48 +00:00
int gcd = 0;
2015-06-01 09:35:51 +00:00
while (ptr < size)
{
2017-03-17 11:03:56 +00:00
int val = buffer[ptr++] & 0x7F; // strip hi-order bit
2015-06-01 09:35:51 +00:00
if (val == 0)
++nulls;
2017-03-17 11:03:56 +00:00
else if (val == 0x0D) // carriage return
2015-06-01 09:35:51 +00:00
text.append ("\n");
else
{
if (nulls > 0)
{
if (newFormat)
2017-04-26 08:04:48 +00:00
text.append (String.format ("%,10d ", ptr - 1));
2015-06-01 09:35:51 +00:00
else
text.append ("\nNew record at : " + (ptr - 1) + "\n");
nulls = 0;
2017-04-26 08:04:48 +00:00
gcd = gcd == 0 ? ptr - 1 : gcd (gcd, ptr - 1);
2015-06-01 09:35:51 +00:00
}
else if (lastVal == 0x0D && newFormat)
2017-03-17 11:03:56 +00:00
if (showAllOffsets)
2017-04-26 08:04:48 +00:00
text.append (String.format ("%,10d ", ptr - 1));
2017-03-17 11:03:56 +00:00
else
2017-04-26 08:04:48 +00:00
text.append (" ");
2015-06-01 09:35:51 +00:00
text.append ((char) val);
}
lastVal = val;
}
2017-04-26 08:04:48 +00:00
if (gcd > 0)
2017-06-22 23:13:37 +00:00
text.append (String.format ("%nGCD: %,d", gcd));
2017-04-26 08:04:48 +00:00
else if (text.length () > 0 && text.charAt (text.length () - 1) == '\n')
2015-06-01 09:35:51 +00:00
text.deleteCharAt (text.length () - 1);
return text.toString ();
}
2017-04-26 08:04:48 +00:00
private int gcd (int a, int b)
{
return a == 0 ? b : gcd (b % a, a);
}
2015-06-01 09:35:51 +00:00
}