This commit is contained in:
Denis Molony 2016-03-04 16:27:14 +11:00
parent e017f9121d
commit 932fc03d14
4 changed files with 65 additions and 62 deletions

View File

@ -2,6 +2,9 @@ package com.bytezone.diskbrowser.visicalc;
class Address implements Comparable<Address>
{
private static final int MAX_ROWS = 255;
private static final int MAX_COLUMNS = 64;
int row, column;
int sortValue;
String text;
@ -13,11 +16,11 @@ class Address implements Comparable<Address>
public Address (int column, int row)
{
assert column <= 64;
assert row <= 255;
assert column <= MAX_COLUMNS;
assert row <= MAX_ROWS;
this.row = row;
this.column = column;
sortValue = row * 64 + column;
sortValue = row * MAX_COLUMNS + column;
int col1 = column / 26;
int col2 = column % 26;
@ -36,7 +39,6 @@ class Address implements Comparable<Address>
private void set (String sCol, String sRow)
{
// System.out.printf ("Set: %s, %s%n", sCol, sRow);
if (sCol.length () == 1)
column = sCol.charAt (0) - 'A';
else if (sCol.length () == 2)
@ -47,7 +49,7 @@ class Address implements Comparable<Address>
try
{
row = Integer.parseInt (sRow) - 1;
sortValue = row * 64 + column;
sortValue = row * MAX_COLUMNS + column;
text = sCol + sRow;
}
catch (NumberFormatException e)
@ -56,13 +58,13 @@ class Address implements Comparable<Address>
}
}
public Address nextRow ()
Address nextRow ()
{
Address next = new Address (column, row + 1);
return next;
}
public Address nextColumn ()
Address nextColumn ()
{
Address next = new Address (column + 1, row);
return next;

View File

@ -36,10 +36,7 @@ class Range implements Iterable<Address>
public Range (String[] cells)
{
for (String s : cells)
{
// System.out.println (s);
range.add (new Address (s));
}
}
@Override

View File

@ -16,7 +16,7 @@ class VisicalcCell implements Comparable<VisicalcCell>
private String formula;
private char format;
private int width;
private int columnWidth;
// private int columnWidth;
private char repeatingChar;
private String repeat = "";
private boolean valid;
@ -27,39 +27,45 @@ class VisicalcCell implements Comparable<VisicalcCell>
this.address = address;
}
public void doCommand (String command)
void doCommand (String command)
{
if (command.startsWith ("/"))
switch (command.charAt (0))
{
if (command.charAt (1) == 'F') // format cell
{
format = command.charAt (2);
if (command.length () > 3 && command.charAt (3) == '"')
label = command.substring (4);
}
else if (command.charAt (1) == '-') // repeating label
{
repeatingChar = command.charAt (2);
for (int i = 0; i < 20; i++)
repeat += repeatingChar;
}
else
System.out.println ("Unknown command: " + command);
case '/':
if (command.charAt (1) == 'F') // format cell
{
format = command.charAt (2);
if (command.length () > 3 && command.charAt (3) == '"')
label = command.substring (4);
}
else if (command.charAt (1) == '-') // repeating label
{
repeatingChar = command.charAt (2);
for (int i = 0; i < 20; i++)
repeat += repeatingChar;
}
else
System.out.println ("Unknown command: " + command);
break;
case '"':
label = command.substring (1);
break;
default:
if (command.matches ("^[0-9.]+$")) // contains only numbers or .
this.value = Float.parseFloat (command);
else
formula = command;
}
else if (command.startsWith ("\"")) // starts with a quote
label = command.substring (1);
else if (command.matches ("^[0-9.]+$")) // contains only numbers or .
this.value = Float.parseFloat (command);
else
formula = command;
}
public boolean hasValue ()
boolean hasValue ()
{
return label == null && repeatingChar == 0;
}
public double getValue ()
double getValue ()
{
if (valid || formula == null)
return value;
@ -108,7 +114,7 @@ class VisicalcCell implements Comparable<VisicalcCell>
return value;
}
public String value ()
String value ()
{
if (label != null)
return label;
@ -130,9 +136,8 @@ class VisicalcCell implements Comparable<VisicalcCell>
: ", Label: " + label : ", Rpeat: " + repeatingChar;
String format = this.format == 0 ? "" : ", Format: " + this.format;
String width = this.width == 0 ? "" : ", Width: " + this.width;
String columnWidth = this.columnWidth == 0 ? "" : ", Col Width: " + this.columnWidth;
return String.format ("[Cell:%5s%s%s%s%s]", address, format, width, columnWidth,
value);
// String columnWidth = this.columnWidth == 0 ? "" : ", Col Width: " + this.columnWidth;
return String.format ("[Cell:%5s%s%s%s]", address, format, width, value);
}
@Override

View File

@ -11,8 +11,6 @@ public class VisicalcSpreadsheet implements Iterable<VisicalcCell>
{
private static final Pattern addressPattern =
Pattern.compile ("([A-B]?[A-Z])([0-9]{1,3}):");
private static final Pattern cellContents =
Pattern.compile ("([-+/*]?)(([A-Z]{1,2}[0-9]{1,3})|([0-9.]+)|(@[^-+/*]+))");
private static final Pattern functionPattern = Pattern
.compile ("\\(([A-B]?[A-Z])([0-9]{1,3})\\.\\.\\.([A-B]?[A-Z])([0-9]{1,3})\\)?");
private static final Pattern addressList = Pattern.compile ("\\(([^,]+(,[^,]+)*)\\)");
@ -21,11 +19,12 @@ public class VisicalcSpreadsheet implements Iterable<VisicalcCell>
private final Map<String, Double> functions = new HashMap<String, Double> ();
final List<String> lines = new ArrayList<String> ();
private final Map<Integer, Integer> columnWidths = new TreeMap<Integer, Integer> ();
VisicalcCell currentCell = null;
int columnWidth = 12;
char defaultFormat;
private final Map<Integer, Integer> columnWidths = new TreeMap<Integer, Integer> ();
int columnWidth = 12;
// Maximum cell = BK254
//Commands:
@ -132,26 +131,34 @@ public class VisicalcSpreadsheet implements Iterable<VisicalcCell>
public VisicalcSpreadsheet (byte[] buffer)
{
int last = buffer.length;
while (buffer[--last] == 0)
;
int ptr = 0;
int last = buffer.length - 1;
while (buffer[last] == 0)
last--;
while (ptr <= last)
{
int endPtr = findEndPtr (buffer, ptr);
String s = HexFormatter.getString (buffer, ptr, endPtr - ptr);
add (s);
add (HexFormatter.getString (buffer, ptr, endPtr - ptr));
ptr = endPtr + 1;
}
if (false)
{
for (VisicalcCell cell : sheet.values ())
System.out.println (cell);
// for (Map.Entry<Integer, Integer> entry : columnWidths.entrySet ())
// System.out.printf ("Width of column %3d: %d%n", entry.getKey (), entry.getValue ());
for (Map.Entry<Integer, Integer> entry : columnWidths.entrySet ())
System.out.printf ("Width of column %3d: %d%n", entry.getKey (),
entry.getValue ());
}
}
private int findEndPtr (byte[] buffer, int ptr)
{
while (buffer[ptr] != (byte) 0x8D)
ptr++;
return ptr;
}
private void add (String command)
@ -159,16 +166,15 @@ public class VisicalcSpreadsheet implements Iterable<VisicalcCell>
// NB no closing bracket: [>K11:@SUM(J11...F11]
lines.add (command);
String data;
if (command.startsWith (">")) // GOTO cell
{
int pos = command.indexOf (':'); // end of cell address
Matcher m = addressPattern.matcher (command);
if (m.find ())
{
Address address = new Address (m.group (1), m.group (2));
VisicalcCell cell = sheet.get (address.sortValue);
int pos = command.indexOf (':'); // end of cell address
command = command.substring (pos + 1);
if (cell == null)
@ -186,7 +192,7 @@ public class VisicalcSpreadsheet implements Iterable<VisicalcCell>
if (command.startsWith ("/")) // command
{
data = command.substring (1);
String data = command.substring (1);
char subCommand = command.charAt (1);
switch (subCommand)
{
@ -250,13 +256,6 @@ public class VisicalcSpreadsheet implements Iterable<VisicalcCell>
currentCell.doCommand (command); // formula
}
private int findEndPtr (byte[] buffer, int ptr)
{
while (buffer[ptr] != (byte) 0x8D)
ptr++;
return ptr;
}
double evaluateFunction (String function)
{
if (functions.containsKey (function))