Make first real commit: copy of CaRMetal 4.2.8
This commit is contained in:
parent
002acfc88e
commit
c312811084
1120 changed files with 226843 additions and 1 deletions
281
rene/util/FileList.java
Normal file
281
rene/util/FileList.java
Normal file
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Enumeration;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
|
||||
import rene.util.sort.SortObject;
|
||||
import rene.util.sort.Sorter;
|
||||
|
||||
class SortFile extends File implements SortObject {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
String S;
|
||||
static int SortBy = 0;
|
||||
final public static int NAME = 0, DATE = 1;
|
||||
|
||||
public SortFile(final File dir, final String name) {
|
||||
super(dir, name);
|
||||
try {
|
||||
S = getCanonicalPath().toUpperCase();
|
||||
} catch (final Exception e) {
|
||||
S = "";
|
||||
}
|
||||
}
|
||||
|
||||
public int compare(final SortObject o) {
|
||||
final SortFile f = (SortFile) o;
|
||||
if (SortBy == DATE) {
|
||||
final long n = f.lastModified();
|
||||
final long m = lastModified();
|
||||
if (n < m)
|
||||
return -1;
|
||||
if (n > m)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
return -f.S.compareTo(S);
|
||||
}
|
||||
}
|
||||
|
||||
class FileFilter {
|
||||
char F[][];
|
||||
|
||||
public FileFilter(final String s) {
|
||||
final StringTokenizer t = new StringTokenizer(s);
|
||||
final int n = t.countTokens();
|
||||
F = new char[n][];
|
||||
for (int i = 0; i < n; i++) {
|
||||
F[i] = t.nextToken().toCharArray();
|
||||
}
|
||||
}
|
||||
|
||||
public char[] filter(final int i) {
|
||||
return F[i];
|
||||
}
|
||||
|
||||
public int filterCount() {
|
||||
return F.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class parses a subtree for files that match a pattern. The pattern may
|
||||
* contain one or more * and ? as usual. The class delivers an enumerator for
|
||||
* the files, or may be subclassed to handle the files directly. The routines
|
||||
* directory and file can be used to return, if more scanning is necessary.
|
||||
*/
|
||||
|
||||
public class FileList {
|
||||
Vector V = new Vector(), Vdir = new Vector();
|
||||
boolean Stop;
|
||||
boolean Recurse;
|
||||
String Dir, Filter;
|
||||
boolean UseCase = false;
|
||||
|
||||
public FileList(final String dir, final String filter, final boolean recurse) {
|
||||
Stop = false;
|
||||
Recurse = recurse;
|
||||
Dir = dir;
|
||||
Filter = filter;
|
||||
if (Dir.equals("-")) {
|
||||
Dir = ".";
|
||||
Recurse = false;
|
||||
} else if (Dir.startsWith("-")) {
|
||||
Dir = Dir.substring(1);
|
||||
Recurse = false;
|
||||
}
|
||||
}
|
||||
|
||||
public FileList(final String dir, final String filter) {
|
||||
this(dir, filter, true);
|
||||
}
|
||||
|
||||
public FileList(final String dir) {
|
||||
this(dir, "*", true);
|
||||
}
|
||||
|
||||
public void setCase(final boolean usecase) {
|
||||
UseCase = usecase;
|
||||
}
|
||||
|
||||
public void search() {
|
||||
Stop = false;
|
||||
final File file = new File(Dir);
|
||||
if (!UseCase)
|
||||
Filter = Filter.toLowerCase();
|
||||
if (file.isDirectory())
|
||||
find(file, new FileFilter(Filter));
|
||||
}
|
||||
|
||||
void find(final File dir, final FileFilter filter) {
|
||||
if (!directory(dir))
|
||||
return;
|
||||
final String list[] = dir.list();
|
||||
loop: for (int i = 0; i < list.length; i++) {
|
||||
final SortFile file = new SortFile(dir, list[i]);
|
||||
if (file.isDirectory()) {
|
||||
Vdir.addElement(file);
|
||||
if (Recurse)
|
||||
find(file, filter);
|
||||
} else {
|
||||
String filename = file.getName();
|
||||
if (!UseCase)
|
||||
filename = filename.toLowerCase();
|
||||
final char fn[] = filename.toCharArray();
|
||||
for (int j = 0; j < filter.filterCount(); j++) {
|
||||
if (match(fn, 0, filter.filter(j), 0)) {
|
||||
Stop = !file(file);
|
||||
if (Stop)
|
||||
break loop;
|
||||
V.addElement(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Stop)
|
||||
break;
|
||||
}
|
||||
parsed(dir);
|
||||
}
|
||||
|
||||
boolean match(final char filename[], final int n, final char filter[],
|
||||
final int m) {
|
||||
if (filter == null)
|
||||
return true;
|
||||
if (m >= filter.length)
|
||||
return n >= filename.length;
|
||||
if (n >= filename.length)
|
||||
return m == filter.length - 1 && filter[m] == '*';
|
||||
if (filter[m] == '?') {
|
||||
return match(filename, n + 1, filter, m + 1);
|
||||
}
|
||||
if (filter[m] == '*') {
|
||||
if (m == filter.length - 1)
|
||||
return true;
|
||||
for (int i = n; i < filename.length; i++) {
|
||||
if (match(filename, i, filter, m + 1))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (filter[m] == filename[n])
|
||||
return match(filename, n + 1, filter, m + 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an Enumeration with the files.
|
||||
*/
|
||||
public Enumeration files() {
|
||||
return V.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an Enumeration with the directories.
|
||||
*/
|
||||
public Enumeration dirs() {
|
||||
return Vdir.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of files found.
|
||||
*/
|
||||
public int size() {
|
||||
return V.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the result.
|
||||
*/
|
||||
public void sort() {
|
||||
int i, n = V.size();
|
||||
SortObject v[] = new SortObject[n];
|
||||
for (i = 0; i < n; i++)
|
||||
v[i] = (SortFile) V.elementAt(i);
|
||||
Sorter.sort(v);
|
||||
for (i = 0; i < n; i++)
|
||||
V.setElementAt(v[i], i);
|
||||
n = Vdir.size();
|
||||
v = new SortObject[n];
|
||||
for (i = 0; i < n; i++)
|
||||
v[i] = (SortFile) Vdir.elementAt(i);
|
||||
Sorter.sort(v);
|
||||
for (i = 0; i < n; i++)
|
||||
Vdir.setElementAt(v[i], i);
|
||||
}
|
||||
|
||||
public void sort(final int type) {
|
||||
SortFile.SortBy = type;
|
||||
sort();
|
||||
SortFile.SortBy = SortFile.NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file
|
||||
* The directory that has been found.
|
||||
* @return false if recursion should stop here. (i.e. that directory needs
|
||||
* not be parsed).
|
||||
*/
|
||||
protected boolean directory(final File dir) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file
|
||||
* The file that has been found.
|
||||
* @return false if you need no more file at all.
|
||||
*/
|
||||
protected boolean file(final File file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parsed
|
||||
* The directory that has been parsed.
|
||||
*/
|
||||
protected void parsed(final File dir) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This stops the search from other threads.
|
||||
*/
|
||||
public void stopIt() {
|
||||
Stop = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a canonical version of the directory
|
||||
*/
|
||||
public String getDir() {
|
||||
final File dir = new File(Dir);
|
||||
try {
|
||||
return (dir.getCanonicalPath());
|
||||
} catch (final Exception e) {
|
||||
return "Dir does not exist!";
|
||||
}
|
||||
}
|
||||
}
|
206
rene/util/FileName.java
Normal file
206
rene/util/FileName.java
Normal file
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* This is a static class to determine extensions etc. from a file name.
|
||||
*/
|
||||
|
||||
public class FileName {
|
||||
static public int ChopLength = 48;
|
||||
|
||||
static public String purefilename(final String filename) {
|
||||
final char a[] = filename.toCharArray();
|
||||
int i = a.length - 1;
|
||||
final char fs = File.separatorChar;
|
||||
while (i >= 0) {
|
||||
if (a[i] == fs || a[i] == '/' || i == 0) {
|
||||
if (i == 0)
|
||||
i = -1;
|
||||
if (i < a.length - 1) {
|
||||
int j = a.length - 1;
|
||||
while (j > i && a[j] != '.')
|
||||
j--;
|
||||
if (j > i + 1)
|
||||
return new String(a, i + 1, j - i - 1);
|
||||
else
|
||||
return "";
|
||||
} else
|
||||
return "";
|
||||
}
|
||||
i--;
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
static public String path(final String filename) {
|
||||
final char a[] = filename.toCharArray();
|
||||
int i = a.length - 1;
|
||||
final char fs = File.separatorChar;
|
||||
while (i > 0) {
|
||||
if (a[i] == fs || a[i] == '/') {
|
||||
return new String(a, 0, i);
|
||||
}
|
||||
i--;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static public String pathAndSeparator(final String filename) {
|
||||
final char a[] = filename.toCharArray();
|
||||
int i = a.length - 1;
|
||||
final char fs = File.separatorChar;
|
||||
while (i > 0) {
|
||||
if (a[i] == fs || a[i] == '/') {
|
||||
return new String(a, 0, i + 1);
|
||||
}
|
||||
i--;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static public String filename(final String filename) {
|
||||
final char a[] = filename.toCharArray();
|
||||
int i = a.length - 1;
|
||||
final char fs = File.separatorChar;
|
||||
while (i > 0) {
|
||||
if (a[i] == fs || a[i] == '/') {
|
||||
if (i + 1 < a.length)
|
||||
return new String(a, i + 1, a.length - i - 1);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
i--;
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
static public String extension(final String filename) {
|
||||
final char a[] = filename.toCharArray();
|
||||
int i = a.length - 1;
|
||||
final char fs = File.separatorChar;
|
||||
while (i > 0) {
|
||||
if (a[i] == '.') {
|
||||
if (i + 1 < a.length)
|
||||
return new String(a, i + 1, a.length - i - 1);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
if (a[i] == fs || a[i] == '/')
|
||||
break;
|
||||
i--;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static public String chop(String filename, final int chop)
|
||||
// chop the filename to 32 characters
|
||||
{
|
||||
if (filename.length() > chop) {
|
||||
filename = "... " + filename.substring(filename.length() - chop);
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
static public String chop(final String filename) {
|
||||
return chop(filename, ChopLength);
|
||||
}
|
||||
|
||||
static public String chop(final int start, String filename, final int chop)
|
||||
// chop the filename.substring(start) to 32 characters
|
||||
{
|
||||
if (filename.length() > start + chop) {
|
||||
filename = filename.substring(0, start) + " ... "
|
||||
+ filename.substring(filename.length() - chop);
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
static public String chop(final int start, final String filename) {
|
||||
return chop(start, filename, ChopLength);
|
||||
}
|
||||
|
||||
static public String relative(String dir, final String filename) {
|
||||
dir = dir + System.getProperty("file.separator");
|
||||
if (filename.startsWith(dir)) {
|
||||
return filename.substring(dir.length());
|
||||
} else
|
||||
return filename;
|
||||
}
|
||||
|
||||
static public String canonical(final String filename) {
|
||||
final File f = new File(filename);
|
||||
try {
|
||||
String s = f.getCanonicalPath();
|
||||
if (s.length() > 2 && s.charAt(1) == ':')
|
||||
s = s.substring(0, 2).toLowerCase() + s.substring(2);
|
||||
return s;
|
||||
} catch (final Exception e) {
|
||||
return f.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
static public String toURL(final String filename) {
|
||||
final int n = filename.indexOf(' ');
|
||||
if (n >= 0)
|
||||
return filename.substring(0, n) + "%20"
|
||||
+ toURL(filename.substring(n + 1));
|
||||
else
|
||||
return filename;
|
||||
}
|
||||
|
||||
static boolean match(final char filename[], final int n,
|
||||
final char filter[], final int m) {
|
||||
if (filter == null)
|
||||
return true;
|
||||
if (m >= filter.length)
|
||||
return n >= filename.length;
|
||||
if (n >= filename.length)
|
||||
return m == filter.length - 1 && filter[m] == '*';
|
||||
if (filter[m] == '?') {
|
||||
return match(filename, n + 1, filter, m + 1);
|
||||
}
|
||||
if (filter[m] == '*') {
|
||||
if (m == filter.length - 1)
|
||||
return true;
|
||||
for (int i = n; i < filename.length; i++) {
|
||||
if (match(filename, i, filter, m + 1))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (filter[m] == filename[n])
|
||||
return match(filename, n + 1, filter, m + 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean match(final String filename, final String filter) {
|
||||
final char fn[] = filename.toCharArray(), f[] = filter.toCharArray();
|
||||
return match(fn, 0, f, 0);
|
||||
}
|
||||
|
||||
public static void main(final String args[]) {
|
||||
System.out.println("-" + toURL(" test test test ") + "-");
|
||||
}
|
||||
}
|
61
rene/util/ImageSelection.java
Normal file
61
rene/util/ImageSelection.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author unknown Class to hold an image for the clipboad, implements the
|
||||
* Transferable class properly.
|
||||
*/
|
||||
public class ImageSelection implements Transferable {
|
||||
// the Image object which will be housed by the ImageSelection
|
||||
private final Image image;
|
||||
|
||||
public ImageSelection(final Image image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
// Returns the supported flavors of our implementation
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return new DataFlavor[] { DataFlavor.imageFlavor };
|
||||
}
|
||||
|
||||
// Returns true if flavor is supported
|
||||
public boolean isDataFlavorSupported(final DataFlavor flavor) {
|
||||
return DataFlavor.imageFlavor.equals(flavor);
|
||||
}
|
||||
|
||||
// Returns Image object housed by Transferable object
|
||||
public Object getTransferData(final DataFlavor flavor)
|
||||
throws UnsupportedFlavorException, IOException {
|
||||
if (!DataFlavor.imageFlavor.equals(flavor)) {
|
||||
throw new UnsupportedFlavorException(flavor);
|
||||
}
|
||||
// else return the payload
|
||||
return image;
|
||||
}
|
||||
}
|
325
rene/util/MyVector.java
Normal file
325
rene/util/MyVector.java
Normal file
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util;
|
||||
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* This is a more effective replacement of the Vector class. It is based on a
|
||||
* growing array. If an object is removed, it is replaced by null. The class
|
||||
* knows about the first null object (the gap). Searching for elements or other
|
||||
* operations automatically compress the array by copying the elements upwards,
|
||||
* but only as far as they need to go anyway.
|
||||
*
|
||||
* Accessing an element is very effective, at least the second time. If you want
|
||||
* to make sure, it is always effective, compress first. The most effective way
|
||||
* is to get the object array itself.
|
||||
*
|
||||
* The objects can be enumerated. The object returned by nextElement() is found
|
||||
* very rapidly. E.g. it can be deleted at once.
|
||||
*
|
||||
* Enumeration is not reentrant. Do it only once each time.
|
||||
*
|
||||
* Nothing in this class is synchronized!
|
||||
**/
|
||||
|
||||
public class MyVector implements Enumeration {
|
||||
Object O[];
|
||||
int OSize, ON, OLast, Gap;
|
||||
int EN = 0;
|
||||
|
||||
public MyVector(final int initsize) {
|
||||
O = new Object[initsize];
|
||||
OSize = initsize;
|
||||
OLast = ON = 0;
|
||||
Gap = -1;
|
||||
}
|
||||
|
||||
public MyVector() {
|
||||
this(8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an element. Extend the array, if necessary.
|
||||
*/
|
||||
public void addElement(final Object o) {
|
||||
if (OLast >= OSize)
|
||||
extend();
|
||||
O[OLast++] = o;
|
||||
ON++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the array, or get space by compressing it.
|
||||
*/
|
||||
public void extend() {
|
||||
if (ON < OLast / 2) {
|
||||
compress();
|
||||
return;
|
||||
}
|
||||
final Object o[] = new Object[2 * OSize];
|
||||
System.arraycopy(O, 0, o, 0, OLast);
|
||||
OSize *= 2;
|
||||
O = o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the array.
|
||||
*/
|
||||
public void compress() {
|
||||
if (Gap < 0)
|
||||
return;
|
||||
int k = Gap;
|
||||
for (int i = Gap; i < OLast; i++) {
|
||||
if (O[i] == null)
|
||||
continue;
|
||||
O[k++] = O[i];
|
||||
}
|
||||
ON = k;
|
||||
for (int i = k; i < OLast; i++)
|
||||
O[i] = null;
|
||||
Gap = -1;
|
||||
OLast = ON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an enumeration of this array.
|
||||
*/
|
||||
public Enumeration elements() {
|
||||
compress();
|
||||
EN = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for Enumeration.
|
||||
*/
|
||||
public boolean hasMoreElements() {
|
||||
while (EN < OLast && O[EN] == null)
|
||||
EN++;
|
||||
return EN < OLast;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for Enumeration.
|
||||
*/
|
||||
public Object nextElement() {
|
||||
if (!hasMoreElements())
|
||||
throw new ArrayIndexOutOfBoundsException(OLast);
|
||||
return O[EN++];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear this array, but keep its memory!
|
||||
*/
|
||||
public void removeAllElements() {
|
||||
for (int i = 0; i < OLast; i++)
|
||||
O[i] = null;
|
||||
ON = OLast = 0;
|
||||
Gap = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a single element. This will also compress the part below the
|
||||
* element, or all, if it is not found.
|
||||
*/
|
||||
public void removeElement(final Object o) {
|
||||
final int i = indexOf(o);
|
||||
if (i < 0)
|
||||
return;
|
||||
O[i] = null;
|
||||
ON--;
|
||||
if (Gap < 0 || Gap > i)
|
||||
Gap = i;
|
||||
if (i == OLast - 1)
|
||||
OLast--;
|
||||
while (OLast > 0 && O[OLast - 1] == null)
|
||||
OLast--;
|
||||
if (Gap >= OLast)
|
||||
Gap = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an element. Compress on the way. Check for the last element,
|
||||
* returned by nextElement() first. Equality is checked with the equal()
|
||||
* function.
|
||||
*
|
||||
* @return -1, if not found.
|
||||
*/
|
||||
public int indexOf(final Object o) {
|
||||
if (EN > 0 && EN <= OLast && O[EN - 1].equals(o))
|
||||
return EN - 1;
|
||||
if (Gap < 0) {
|
||||
for (int i = 0; i < OLast; i++) {
|
||||
if (O[i].equals(o))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < Gap; i++) {
|
||||
if (O[i].equals(o))
|
||||
return i;
|
||||
}
|
||||
int k = Gap;
|
||||
for (int i = Gap; i < OLast; i++) {
|
||||
if (O[i] == null)
|
||||
continue;
|
||||
if (O[i].equals(o)) {
|
||||
Gap = k;
|
||||
return i;
|
||||
}
|
||||
O[k++] = O[i];
|
||||
O[i] = null;
|
||||
}
|
||||
ON = k;
|
||||
for (int i = k; i < OLast; i++)
|
||||
O[i] = null;
|
||||
Gap = -1;
|
||||
OLast = ON;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of objects in the vector.
|
||||
*/
|
||||
public int size() {
|
||||
return ON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element at a given position. Second access will always be
|
||||
* effective. First access compresses. Throws an exception, if the index is
|
||||
* invalid.
|
||||
*/
|
||||
public Object elementAt(final int n) {
|
||||
if (n < 0 || n >= ON)
|
||||
throw new ArrayIndexOutOfBoundsException(n);
|
||||
if (Gap < 0 || n < Gap)
|
||||
return O[n];
|
||||
int k = Gap;
|
||||
for (int i = Gap; i < OLast; i++) {
|
||||
if (O[i] == null)
|
||||
continue;
|
||||
O[k] = O[i];
|
||||
O[i] = null;
|
||||
if (k == n) {
|
||||
final Object ret = O[k];
|
||||
k++;
|
||||
Gap = k;
|
||||
if (Gap >= ON) {
|
||||
for (int j = Gap; j < OLast; j++)
|
||||
O[j] = null;
|
||||
OLast = ON;
|
||||
Gap = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
// never happens
|
||||
throw new ArrayIndexOutOfBoundsException(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array itself (compressed). Make sure, you also use size() to
|
||||
* determine the true length of the array. Do not change objects beyond the
|
||||
* size! Do not set objects to null!
|
||||
*/
|
||||
public Object[] getArray() {
|
||||
compress();
|
||||
return O;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the array into an object array of at least the same size.
|
||||
*/
|
||||
public void copyInto(final Object o[]) {
|
||||
compress();
|
||||
System.arraycopy(O, 0, o, 0, ON);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for equality with another vector, using equals.
|
||||
*/
|
||||
public boolean equals(final MyVector V) {
|
||||
if (V.ON != ON)
|
||||
return false;
|
||||
V.compress();
|
||||
compress();
|
||||
for (int i = 0; i < ON; i++) {
|
||||
if (!V.O[i].equals(O[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for equality with another vector, using object equality.
|
||||
*/
|
||||
public boolean equalsIdentical(final MyVector V) {
|
||||
if (V.ON != ON)
|
||||
return false;
|
||||
V.compress();
|
||||
compress();
|
||||
for (int i = 0; i < ON; i++) {
|
||||
if (V.O[i] != O[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trancate the vector to n elements, if it has more.
|
||||
*/
|
||||
public void truncate(final int n) {
|
||||
if (n >= ON)
|
||||
return;
|
||||
compress();
|
||||
for (int i = n; i < OLast; i++)
|
||||
O[i] = null;
|
||||
OLast = ON = n;
|
||||
}
|
||||
|
||||
public static void main(final String args[]) {
|
||||
final MyVector V = new MyVector();
|
||||
for (int i = 1; i <= 10; i++)
|
||||
V.addElement("Element " + i);
|
||||
for (int i = 4; i <= 9; i++)
|
||||
V.removeElement("Element " + i);
|
||||
System.out.println("--> " + V.elementAt(3));
|
||||
System.out.println(V.ON + " elements, " + V.OLast + " used, " + V.Gap
|
||||
+ " gap.");
|
||||
System.out.println("--> " + V.elementAt(3));
|
||||
System.out.println(V.ON + " elements, " + V.OLast + " used, " + V.Gap
|
||||
+ " gap.");
|
||||
for (int i = 11; i <= 20; i++)
|
||||
V.addElement("Element " + i);
|
||||
System.out.println(V.ON + " elements, " + V.OLast + " used ," + V.Gap
|
||||
+ " gap.");
|
||||
final Enumeration E = V.elements();
|
||||
while (E.hasMoreElements()) {
|
||||
System.out.println((String) E.nextElement());
|
||||
}
|
||||
System.out.println(V.ON + " elements, " + V.OLast + " used, " + V.Gap
|
||||
+ " gap.");
|
||||
}
|
||||
}
|
647
rene/util/PngEncoder.java
Normal file
647
rene/util/PngEncoder.java
Normal file
|
@ -0,0 +1,647 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util;
|
||||
|
||||
/**
|
||||
* PngEncoder takes a Java Image object and creates a byte string which can be saved as a PNG file.
|
||||
* The Image is presumed to use the DirectColorModel.
|
||||
*
|
||||
* Thanks to Jay Denny at KeyPoint Software
|
||||
* http://www.keypoint.com/
|
||||
* who let me develop this code on company time.
|
||||
*
|
||||
* You may contact me with (probably very-much-needed) improvements,
|
||||
* comments, and bug fixes at:
|
||||
*
|
||||
* david@catcode.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* A copy of the GNU LGPL may be found at
|
||||
* http://www.gnu.org/copyleft/lesser.html,
|
||||
*
|
||||
* @author J. David Eisenberg
|
||||
* @version 1.4, 31 March 2000
|
||||
*/
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.PixelGrabber;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.CRC32;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
|
||||
public class PngEncoder extends Object {
|
||||
/** Constant specifying that alpha channel should be encoded. */
|
||||
public static final boolean ENCODE_ALPHA = true;
|
||||
/** Constant specifying that alpha channel should not be encoded. */
|
||||
public static final boolean NO_ALPHA = false;
|
||||
/** Constants for filters */
|
||||
public static final int FILTER_NONE = 0;
|
||||
public static final int FILTER_SUB = 1;
|
||||
public static final int FILTER_UP = 2;
|
||||
public static final int FILTER_LAST = 2;
|
||||
|
||||
protected byte[] pngBytes;
|
||||
protected byte[] priorRow;
|
||||
protected byte[] leftBytes;
|
||||
protected Image image;
|
||||
protected int width, height;
|
||||
protected int bytePos, maxPos;
|
||||
protected int hdrPos, dataPos, endPos;
|
||||
protected CRC32 crc = new CRC32();
|
||||
protected long crcValue;
|
||||
protected boolean encodeAlpha;
|
||||
protected int filter;
|
||||
protected int bytesPerPixel;
|
||||
protected int compressionLevel;
|
||||
protected double DPI = 300;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
*/
|
||||
public PngEncoder() {
|
||||
this(null, false, FILTER_NONE, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor specifying Image to encode, with no alpha channel
|
||||
* encoding.
|
||||
*
|
||||
* @param image
|
||||
* A Java Image object which uses the DirectColorModel
|
||||
* @see java.awt.Image
|
||||
*/
|
||||
public PngEncoder(final Image image) {
|
||||
this(image, false, FILTER_NONE, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor specifying Image to encode, and whether to encode
|
||||
* alpha.
|
||||
*
|
||||
* @param image
|
||||
* A Java Image object which uses the DirectColorModel
|
||||
* @param encodeAlpha
|
||||
* Encode the alpha channel? false=no; true=yes
|
||||
* @see java.awt.Image
|
||||
*/
|
||||
public PngEncoder(final Image image, final boolean encodeAlpha) {
|
||||
this(image, encodeAlpha, FILTER_NONE, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor specifying Image to encode, whether to encode alpha,
|
||||
* and filter to use.
|
||||
*
|
||||
* @param image
|
||||
* A Java Image object which uses the DirectColorModel
|
||||
* @param encodeAlpha
|
||||
* Encode the alpha channel? false=no; true=yes
|
||||
* @param whichFilter
|
||||
* 0=none, 1=sub, 2=up
|
||||
* @see java.awt.Image
|
||||
*/
|
||||
public PngEncoder(final Image image, final boolean encodeAlpha,
|
||||
final int whichFilter) {
|
||||
this(image, encodeAlpha, whichFilter, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor specifying Image source to encode, whether to encode
|
||||
* alpha, filter to use, and compression level.
|
||||
*
|
||||
* @param image
|
||||
* A Java Image object
|
||||
* @param encodeAlpha
|
||||
* Encode the alpha channel? false=no; true=yes
|
||||
* @param whichFilter
|
||||
* 0=none, 1=sub, 2=up
|
||||
* @param compLevel
|
||||
* 0..9
|
||||
* @see java.awt.Image
|
||||
*/
|
||||
public PngEncoder(final Image image, final boolean encodeAlpha,
|
||||
final int whichFilter, final int compLevel) {
|
||||
this.image = image;
|
||||
this.encodeAlpha = encodeAlpha;
|
||||
setFilter(whichFilter);
|
||||
if (compLevel >= 0 && compLevel <= 9) {
|
||||
this.compressionLevel = compLevel;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the image to be encoded
|
||||
*
|
||||
* @param image
|
||||
* A Java Image object which uses the DirectColorModel
|
||||
* @see java.awt.Image
|
||||
* @see java.awt.image.DirectColorModel
|
||||
*/
|
||||
public void setImage(final Image image) {
|
||||
this.image = image;
|
||||
pngBytes = null;
|
||||
}
|
||||
|
||||
public void setDPI(final double dpi) {
|
||||
DPI = dpi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of bytes that is the PNG equivalent of the current
|
||||
* image, specifying whether to encode alpha or not.
|
||||
*
|
||||
* @param encodeAlpha
|
||||
* boolean false=no alpha, true=encode alpha
|
||||
* @return an array of bytes, or null if there was a problem
|
||||
*/
|
||||
public byte[] pngEncode(final boolean encodeAlpha) {
|
||||
final byte[] pngIdBytes = { -119, 80, 78, 71, 13, 10, 26, 10 };
|
||||
if (image == null) {
|
||||
return null;
|
||||
}
|
||||
width = image.getWidth(null);
|
||||
height = image.getHeight(null);
|
||||
|
||||
/*
|
||||
* start with an array that is big enough to hold all the pixels (plus
|
||||
* filter bytes), and an extra 200 bytes for header info
|
||||
*/
|
||||
pngBytes = new byte[((width + 1) * height * 3) + 200];
|
||||
|
||||
/*
|
||||
* keep track of largest byte written to the array
|
||||
*/
|
||||
maxPos = 0;
|
||||
|
||||
bytePos = writeBytes(pngIdBytes, 0);
|
||||
hdrPos = bytePos;
|
||||
writeHeader();
|
||||
writePhys();
|
||||
dataPos = bytePos;
|
||||
if (writeImageData()) {
|
||||
writeEnd();
|
||||
pngBytes = resizeByteArray(pngBytes, maxPos);
|
||||
} else {
|
||||
pngBytes = null;
|
||||
}
|
||||
return pngBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of bytes that is the PNG equivalent of the current
|
||||
* image. Alpha encoding is determined by its setting in the constructor.
|
||||
*
|
||||
* @return an array of bytes, or null if there was a problem
|
||||
*/
|
||||
public byte[] pngEncode() {
|
||||
return pngEncode(encodeAlpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the alpha encoding on or off.
|
||||
*
|
||||
* @param encodeAlpha
|
||||
* false=no, true=yes
|
||||
*/
|
||||
public void setEncodeAlpha(final boolean encodeAlpha) {
|
||||
this.encodeAlpha = encodeAlpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve alpha encoding status.
|
||||
*
|
||||
* @return boolean false=no, true=yes
|
||||
*/
|
||||
public boolean getEncodeAlpha() {
|
||||
return encodeAlpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filter to use
|
||||
*
|
||||
* @param whichFilter
|
||||
* from constant list
|
||||
*/
|
||||
public void setFilter(final int whichFilter) {
|
||||
this.filter = FILTER_NONE;
|
||||
if (whichFilter <= FILTER_LAST) {
|
||||
this.filter = whichFilter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve filtering scheme
|
||||
*
|
||||
* @return int (see constant list)
|
||||
*/
|
||||
public int getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the compression level to use
|
||||
*
|
||||
* @param level
|
||||
* 0 through 9
|
||||
*/
|
||||
public void setCompressionLevel(final int level) {
|
||||
if (level >= 0 && level <= 9) {
|
||||
this.compressionLevel = level;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve compression level
|
||||
*
|
||||
* @return int in range 0-9
|
||||
*/
|
||||
public int getCompressionLevel() {
|
||||
return compressionLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase or decrease the length of a byte array.
|
||||
*
|
||||
* @param array
|
||||
* The original array.
|
||||
* @param newLength
|
||||
* The length you wish the new array to have.
|
||||
* @return Array of newly desired length. If shorter than the original, the
|
||||
* trailing elements are truncated.
|
||||
*/
|
||||
protected byte[] resizeByteArray(final byte[] array, final int newLength) {
|
||||
final byte[] newArray = new byte[newLength];
|
||||
final int oldLength = array.length;
|
||||
|
||||
System.arraycopy(array, 0, newArray, 0, Math.min(oldLength, newLength));
|
||||
return newArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an array of bytes into the pngBytes array. Note: This routine has
|
||||
* the side effect of updating maxPos, the largest element written in the
|
||||
* array. The array is resized by 1000 bytes or the length of the data to be
|
||||
* written, whichever is larger.
|
||||
*
|
||||
* @param data
|
||||
* The data to be written into pngBytes.
|
||||
* @param offset
|
||||
* The starting point to write to.
|
||||
* @return The next place to be written to in the pngBytes array.
|
||||
*/
|
||||
protected int writeBytes(final byte[] data, final int offset) {
|
||||
maxPos = Math.max(maxPos, offset + data.length);
|
||||
if (data.length + offset > pngBytes.length) {
|
||||
pngBytes = resizeByteArray(pngBytes, pngBytes.length
|
||||
+ Math.max(1000, data.length));
|
||||
}
|
||||
System.arraycopy(data, 0, pngBytes, offset, data.length);
|
||||
return offset + data.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an array of bytes into the pngBytes array, specifying number of
|
||||
* bytes to write. Note: This routine has the side effect of updating
|
||||
* maxPos, the largest element written in the array. The array is resized by
|
||||
* 1000 bytes or the length of the data to be written, whichever is larger.
|
||||
*
|
||||
* @param data
|
||||
* The data to be written into pngBytes.
|
||||
* @param nBytes
|
||||
* The number of bytes to be written.
|
||||
* @param offset
|
||||
* The starting point to write to.
|
||||
* @return The next place to be written to in the pngBytes array.
|
||||
*/
|
||||
protected int writeBytes(final byte[] data, final int nBytes,
|
||||
final int offset) {
|
||||
maxPos = Math.max(maxPos, offset + nBytes);
|
||||
if (nBytes + offset > pngBytes.length) {
|
||||
pngBytes = resizeByteArray(pngBytes, pngBytes.length
|
||||
+ Math.max(1000, nBytes));
|
||||
}
|
||||
System.arraycopy(data, 0, pngBytes, offset, nBytes);
|
||||
return offset + nBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a two-byte integer into the pngBytes array at a given position.
|
||||
*
|
||||
* @param n
|
||||
* The integer to be written into pngBytes.
|
||||
* @param offset
|
||||
* The starting point to write to.
|
||||
* @return The next place to be written to in the pngBytes array.
|
||||
*/
|
||||
protected int writeInt2(final int n, final int offset) {
|
||||
final byte[] temp = { (byte) ((n >> 8) & 0xff), (byte) (n & 0xff) };
|
||||
return writeBytes(temp, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a four-byte integer into the pngBytes array at a given position.
|
||||
*
|
||||
* @param n
|
||||
* The integer to be written into pngBytes.
|
||||
* @param offset
|
||||
* The starting point to write to.
|
||||
* @return The next place to be written to in the pngBytes array.
|
||||
*/
|
||||
protected int writeInt4(final int n, final int offset) {
|
||||
final byte[] temp = { (byte) ((n >> 24) & 0xff),
|
||||
(byte) ((n >> 16) & 0xff), (byte) ((n >> 8) & 0xff),
|
||||
(byte) (n & 0xff) };
|
||||
return writeBytes(temp, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a single byte into the pngBytes array at a given position.
|
||||
*
|
||||
* @param n
|
||||
* The integer to be written into pngBytes.
|
||||
* @param offset
|
||||
* The starting point to write to.
|
||||
* @return The next place to be written to in the pngBytes array.
|
||||
*/
|
||||
protected int writeByte(final int b, final int offset) {
|
||||
final byte[] temp = { (byte) b };
|
||||
return writeBytes(temp, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string into the pngBytes array at a given position. This uses the
|
||||
* getBytes method, so the encoding used will be its default.
|
||||
*
|
||||
* @param n
|
||||
* The integer to be written into pngBytes.
|
||||
* @param offset
|
||||
* The starting point to write to.
|
||||
* @return The next place to be written to in the pngBytes array.
|
||||
* @see java.lang.String#getBytes()
|
||||
*/
|
||||
protected int writeString(final String s, final int offset) {
|
||||
return writeBytes(s.getBytes(), offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a PNG "IHDR" chunk into the pngBytes array.
|
||||
*/
|
||||
protected void writeHeader() {
|
||||
int startPos;
|
||||
|
||||
startPos = bytePos = writeInt4(13, bytePos);
|
||||
bytePos = writeString("IHDR", bytePos);
|
||||
width = image.getWidth(null);
|
||||
height = image.getHeight(null);
|
||||
bytePos = writeInt4(width, bytePos);
|
||||
bytePos = writeInt4(height, bytePos);
|
||||
bytePos = writeByte(8, bytePos); // bit depth
|
||||
bytePos = writeByte((encodeAlpha) ? 6 : 2, bytePos); // direct model
|
||||
bytePos = writeByte(0, bytePos); // compression method
|
||||
bytePos = writeByte(0, bytePos); // filter method
|
||||
bytePos = writeByte(0, bytePos); // no interlace
|
||||
crc.reset();
|
||||
crc.update(pngBytes, startPos, bytePos - startPos);
|
||||
crcValue = crc.getValue();
|
||||
bytePos = writeInt4((int) crcValue, bytePos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a PNG "pHYs" chunk into the pngBytes array.
|
||||
*/
|
||||
protected void writePhys() {
|
||||
int startPos;
|
||||
|
||||
startPos = bytePos = writeInt4(9, bytePos);
|
||||
bytePos = writeString("pHYs", bytePos);
|
||||
final int dots = (int) (DPI * 39.37);
|
||||
bytePos = writeInt4(dots, bytePos);
|
||||
bytePos = writeInt4(dots, bytePos);
|
||||
bytePos = writeByte(1, bytePos); // bit depth
|
||||
crc.reset();
|
||||
crc.update(pngBytes, startPos, bytePos - startPos);
|
||||
crcValue = crc.getValue();
|
||||
bytePos = writeInt4((int) crcValue, bytePos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform "sub" filtering on the given row. Uses temporary array leftBytes
|
||||
* to store the original values of the previous pixels. The array is 16
|
||||
* bytes long, which will easily hold two-byte samples plus two-byte alpha.
|
||||
*
|
||||
* @param pixels
|
||||
* The array holding the scan lines being built
|
||||
* @param startPos
|
||||
* Starting position within pixels of bytes to be filtered.
|
||||
* @param width
|
||||
* Width of a scanline in pixels.
|
||||
*/
|
||||
protected void filterSub(final byte[] pixels, final int startPos,
|
||||
final int width) {
|
||||
int i;
|
||||
final int offset = bytesPerPixel;
|
||||
final int actualStart = startPos + offset;
|
||||
final int nBytes = width * bytesPerPixel;
|
||||
int leftInsert = offset;
|
||||
int leftExtract = 0;
|
||||
for (i = actualStart; i < startPos + nBytes; i++) {
|
||||
leftBytes[leftInsert] = pixels[i];
|
||||
pixels[i] = (byte) ((pixels[i] - leftBytes[leftExtract]) % 256);
|
||||
leftInsert = (leftInsert + 1) % 0x0f;
|
||||
leftExtract = (leftExtract + 1) % 0x0f;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform "up" filtering on the given row. Side effect: refills the prior
|
||||
* row with current row
|
||||
*
|
||||
* @param pixels
|
||||
* The array holding the scan lines being built
|
||||
* @param startPos
|
||||
* Starting position within pixels of bytes to be filtered.
|
||||
* @param width
|
||||
* Width of a scanline in pixels.
|
||||
*/
|
||||
protected void filterUp(final byte[] pixels, final int startPos,
|
||||
final int width) {
|
||||
int i, nBytes;
|
||||
byte current_byte;
|
||||
|
||||
nBytes = width * bytesPerPixel;
|
||||
|
||||
for (i = 0; i < nBytes; i++) {
|
||||
current_byte = pixels[startPos + i];
|
||||
pixels[startPos + i] = (byte) ((pixels[startPos + i] - priorRow[i]) % 256);
|
||||
priorRow[i] = current_byte;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the image data into the pngBytes array. This will write one or more
|
||||
* PNG "IDAT" chunks. In order to conserve memory, this method grabs as many
|
||||
* rows as will fit into 32K bytes, or the whole image; whichever is less.
|
||||
*
|
||||
*
|
||||
* @return true if no errors; false if error grabbing pixels
|
||||
*/
|
||||
protected boolean writeImageData() {
|
||||
int rowsLeft = height; // number of rows remaining to write
|
||||
int startRow = 0; // starting row to process this time through
|
||||
int nRows; // how many rows to grab at a time
|
||||
|
||||
byte[] scanLines; // the scan lines to be compressed
|
||||
int scanPos; // where we are in the scan lines
|
||||
int startPos; // where this line's actual pixels start (used for
|
||||
// filtering)
|
||||
|
||||
byte[] compressedLines; // the resultant compressed lines
|
||||
int nCompressed; // how big is the compressed area?
|
||||
|
||||
PixelGrabber pg;
|
||||
|
||||
bytesPerPixel = (encodeAlpha) ? 4 : 3;
|
||||
|
||||
final Deflater scrunch = new Deflater(compressionLevel);
|
||||
final ByteArrayOutputStream outBytes = new ByteArrayOutputStream(1024);
|
||||
|
||||
final DeflaterOutputStream compBytes = new DeflaterOutputStream(
|
||||
outBytes, scrunch);
|
||||
try {
|
||||
nRows = (64 * 32768 - 1) / (width * (bytesPerPixel + 1));
|
||||
|
||||
final int[] pixels = new int[width * nRows];
|
||||
|
||||
while (rowsLeft > 0) {
|
||||
if (nRows >= rowsLeft)
|
||||
nRows = rowsLeft;
|
||||
|
||||
pg = new PixelGrabber(image, 0, startRow, width, nRows, pixels,
|
||||
0, width);
|
||||
try {
|
||||
pg.grabPixels();
|
||||
} catch (final Exception e) {
|
||||
System.err.println("interrupted waiting for pixels!");
|
||||
return false;
|
||||
}
|
||||
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
|
||||
System.err.println("image fetch aborted or errored");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a data chunk. scanLines adds "nRows" for the filter
|
||||
* bytes.
|
||||
*/
|
||||
scanLines = new byte[width * nRows * bytesPerPixel + nRows];
|
||||
|
||||
if (filter == FILTER_SUB) {
|
||||
leftBytes = new byte[16];
|
||||
}
|
||||
if (filter == FILTER_UP) {
|
||||
priorRow = new byte[width * bytesPerPixel];
|
||||
}
|
||||
|
||||
scanPos = 0;
|
||||
startPos = 1;
|
||||
for (int i = 0; i < width * nRows; i++) {
|
||||
if (i % width == 0) {
|
||||
scanLines[scanPos++] = (byte) filter;
|
||||
startPos = scanPos;
|
||||
}
|
||||
scanLines[scanPos++] = (byte) ((pixels[i] >> 16) & 0xff);
|
||||
scanLines[scanPos++] = (byte) ((pixels[i] >> 8) & 0xff);
|
||||
scanLines[scanPos++] = (byte) ((pixels[i]) & 0xff);
|
||||
if (encodeAlpha) {
|
||||
scanLines[scanPos++] = (byte) ((pixels[i] >> 24) & 0xff);
|
||||
}
|
||||
if ((i % width == width - 1) && (filter != FILTER_NONE)) {
|
||||
if (filter == FILTER_SUB) {
|
||||
filterSub(scanLines, startPos, width);
|
||||
}
|
||||
if (filter == FILTER_UP) {
|
||||
filterUp(scanLines, startPos, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write these lines to the output area
|
||||
*/
|
||||
compBytes.write(scanLines, 0, scanPos);
|
||||
|
||||
startRow += nRows;
|
||||
rowsLeft -= nRows;
|
||||
}
|
||||
compBytes.close();
|
||||
|
||||
/*
|
||||
* Write the compressed bytes
|
||||
*/
|
||||
compressedLines = outBytes.toByteArray();
|
||||
nCompressed = compressedLines.length;
|
||||
|
||||
crc.reset();
|
||||
bytePos = writeInt4(nCompressed, bytePos);
|
||||
bytePos = writeString("IDAT", bytePos);
|
||||
crc.update("IDAT".getBytes());
|
||||
bytePos = writeBytes(compressedLines, nCompressed, bytePos);
|
||||
crc.update(compressedLines, 0, nCompressed);
|
||||
|
||||
crcValue = crc.getValue();
|
||||
bytePos = writeInt4((int) crcValue, bytePos);
|
||||
scrunch.finish();
|
||||
return true;
|
||||
} catch (final IOException e) {
|
||||
System.err.println(e.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a PNG "IEND" chunk into the pngBytes array.
|
||||
*/
|
||||
protected void writeEnd() {
|
||||
bytePos = writeInt4(0, bytePos);
|
||||
bytePos = writeString("IEND", bytePos);
|
||||
crc.reset();
|
||||
crc.update("IEND".getBytes());
|
||||
crcValue = crc.getValue();
|
||||
bytePos = writeInt4((int) crcValue, bytePos);
|
||||
}
|
||||
}
|
71
rene/util/SimpleByteBuffer.java
Normal file
71
rene/util/SimpleByteBuffer.java
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util;
|
||||
|
||||
public class SimpleByteBuffer {
|
||||
private int Size, N;
|
||||
private byte Buf[];
|
||||
|
||||
public SimpleByteBuffer(final int size) {
|
||||
Size = size;
|
||||
Buf = new byte[size];
|
||||
N = 0;
|
||||
}
|
||||
|
||||
public SimpleByteBuffer(final byte b[]) {
|
||||
Size = b.length;
|
||||
Buf = b;
|
||||
N = 0;
|
||||
}
|
||||
|
||||
public void append(final byte c) {
|
||||
if (N < Size)
|
||||
Buf[N++] = c;
|
||||
else {
|
||||
Size = 2 * Size;
|
||||
final byte NewBuf[] = new byte[Size];
|
||||
for (int i = 0; i < N; i++)
|
||||
NewBuf[i] = Buf[i];
|
||||
Buf = NewBuf;
|
||||
Buf[N++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
N = 0;
|
||||
}
|
||||
|
||||
public byte[] getBuffer() {
|
||||
return Buf;
|
||||
}
|
||||
|
||||
public byte[] getByteArray() {
|
||||
final byte b[] = new byte[N];
|
||||
for (int i = 0; i < N; i++)
|
||||
b[i] = Buf[i];
|
||||
return b;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return N;
|
||||
}
|
||||
}
|
69
rene/util/SimpleStringBuffer.java
Normal file
69
rene/util/SimpleStringBuffer.java
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util;
|
||||
|
||||
public class SimpleStringBuffer {
|
||||
private int Size, N;
|
||||
private char Buf[];
|
||||
|
||||
public SimpleStringBuffer(final int size) {
|
||||
Size = size;
|
||||
Buf = new char[size];
|
||||
N = 0;
|
||||
}
|
||||
|
||||
public SimpleStringBuffer(final char b[]) {
|
||||
Size = b.length;
|
||||
Buf = b;
|
||||
N = 0;
|
||||
}
|
||||
|
||||
public void append(final char c) {
|
||||
if (N < Size)
|
||||
Buf[N++] = c;
|
||||
else {
|
||||
Size = 2 * Size;
|
||||
final char NewBuf[] = new char[Size];
|
||||
for (int i = 0; i < N; i++)
|
||||
NewBuf[i] = Buf[i];
|
||||
Buf = NewBuf;
|
||||
Buf[N++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
public void append(final String s) {
|
||||
final int n = s.length();
|
||||
for (int i = 0; i < n; i++)
|
||||
append(s.charAt(i));
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
N = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (N == 0)
|
||||
return "";
|
||||
return new String(Buf, 0, N);
|
||||
}
|
||||
}
|
302
rene/util/TestEncoder.java
Normal file
302
rene/util/TestEncoder.java
Normal file
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.MemoryImageSource;
|
||||
import java.awt.image.PixelGrabber;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* TestEncoder creates a PNG file that shows an analog clock displaying the
|
||||
* current time of day, optionally with an alpha channel, and with the specified
|
||||
* filter.
|
||||
*
|
||||
* The file name is in the format:
|
||||
*
|
||||
* clockHHMM_fNC alphaclockDHHMM_fNC
|
||||
*
|
||||
* HH = hours (24-hour clock), MM = minutes,
|
||||
*
|
||||
* N = filter level (0, 1, or 2) C = compression level (0 to 9)
|
||||
*
|
||||
* "alpha" is prefixed to the name if alpha encoding was used.
|
||||
*
|
||||
* This test program was written in a burning hurry, so it is not a model of
|
||||
* efficient, or even good, code. Comments and bug fixes should be directed to:
|
||||
*
|
||||
* david@catcode.com
|
||||
*
|
||||
* @author J. David Eisenberg
|
||||
* @version 1.3, 6 April 2000
|
||||
*/
|
||||
|
||||
public class TestEncoder extends Frame {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
String message;
|
||||
String timeStr;
|
||||
Image clockImage = null;
|
||||
int hour, minute;
|
||||
boolean encodeAlpha;
|
||||
int filter;
|
||||
int compressionLevel;
|
||||
int pixelDepth;
|
||||
String filename;
|
||||
boolean fileSaved = false;
|
||||
|
||||
public TestEncoder(final String s) {
|
||||
super(s);
|
||||
setSize(200, 200);
|
||||
}
|
||||
|
||||
public void drawClockImage(int hour, final int minute) {
|
||||
// variables used for drawing hands of clock
|
||||
Graphics g;
|
||||
final Font smallFont = new Font("Helvetica", Font.PLAIN, 9);
|
||||
FontMetrics fm;
|
||||
|
||||
int x0, y0, x1, y1;
|
||||
double angle;
|
||||
|
||||
g = clockImage.getGraphics();
|
||||
g.setFont(smallFont);
|
||||
fm = g.getFontMetrics();
|
||||
|
||||
// draw the clock face; yellow for AM, blue for PM
|
||||
if (hour < 12) {
|
||||
g.setColor(new Color(255, 255, 192));
|
||||
} else {
|
||||
g.setColor(new Color(192, 192, 255));
|
||||
}
|
||||
g.fillOval(10, 10, 80, 80);
|
||||
g.setColor(Color.black);
|
||||
g.drawOval(10, 10, 80, 80);
|
||||
g.drawOval(48, 48, 4, 4);
|
||||
|
||||
/* draw the 12 / 3 / 6/ 9 numerals */
|
||||
g.setFont(smallFont);
|
||||
g.drawString("12", 50 - fm.stringWidth("12") / 2, 11 + fm.getAscent());
|
||||
g.drawString("3", 88 - fm.stringWidth("3"), 50 + fm.getAscent() / 2);
|
||||
g.drawString("6", 50 - fm.stringWidth("6") / 2, 88);
|
||||
g.drawString("9", 12, 50 + fm.getAscent() / 2);
|
||||
|
||||
x0 = 50;
|
||||
y0 = 50;
|
||||
|
||||
/* draw the hour hand */
|
||||
hour %= 12;
|
||||
angle = -(hour * 30 + minute / 2) + 90;
|
||||
angle = angle * (Math.PI / 180.0);
|
||||
|
||||
x1 = (int) (x0 + 28 * (Math.cos(angle)));
|
||||
y1 = (int) (y0 - 28 * (Math.sin(angle)));
|
||||
g.drawLine(x0, y0, x1, y1);
|
||||
|
||||
/* and the minute hand */
|
||||
angle = -(minute * 6) + 90;
|
||||
angle = angle * Math.PI / 180.0;
|
||||
x1 = (int) (x0 + 35 * (Math.cos(angle)));
|
||||
y1 = (int) (y0 - 35 * (Math.sin(angle)));
|
||||
g.drawLine(x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
public void addAlphaToImage() {
|
||||
final int width = 100;
|
||||
final int height = 100;
|
||||
int alphaMask = 0;
|
||||
final int[] pixels = new int[width * height];
|
||||
|
||||
final PixelGrabber pg = new PixelGrabber(clockImage, 0, 0, width,
|
||||
height, pixels, 0, width);
|
||||
try {
|
||||
pg.grabPixels();
|
||||
} catch (final InterruptedException e) {
|
||||
System.err.println("interrupted waiting for pixels!");
|
||||
return;
|
||||
}
|
||||
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
|
||||
System.err.println("image fetch aborted or errored");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
if ((i % width) == 0) {
|
||||
alphaMask = (alphaMask >> 24) & 0xff;
|
||||
alphaMask += 2;
|
||||
if (alphaMask > 255) {
|
||||
alphaMask = 255;
|
||||
}
|
||||
alphaMask = (alphaMask << 24) & 0xff000000;
|
||||
}
|
||||
pixels[i] = (pixels[i] & 0xffffff) | alphaMask;
|
||||
}
|
||||
clockImage = createImage(new MemoryImageSource(width, height, pixels,
|
||||
0, width));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(final Graphics g) {
|
||||
if (clockImage == null) {
|
||||
clockImage = createImage(100, 100);
|
||||
}
|
||||
if (clockImage != null) {
|
||||
if (!fileSaved) {
|
||||
drawClockImage(hour, minute);
|
||||
if (encodeAlpha) {
|
||||
addAlphaToImage();
|
||||
}
|
||||
saveClockImage();
|
||||
fileSaved = true;
|
||||
}
|
||||
g.drawImage(clockImage, 50, 20, null);
|
||||
}
|
||||
if (message != null) {
|
||||
g.drawString(message, 10, 140);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void usage() {
|
||||
System.out.print("Usage: TestEncoder -alpha -filter n -compress c");
|
||||
System.out.println("-alpha means to use alpha encoding (default none)");
|
||||
System.out.println("n is filter number 0=none (default), 1=sub, 2=up");
|
||||
System.out.println("c is compression factor (0-9); 1 default");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public static void main(final String[] args) {
|
||||
int i;
|
||||
|
||||
final TestEncoder te = new TestEncoder("Test PNG Alpha/Filter Encoder");
|
||||
i = 0;
|
||||
te.encodeAlpha = false;
|
||||
te.filter = 0;
|
||||
te.pixelDepth = 24;
|
||||
te.compressionLevel = 1;
|
||||
while (i < args.length) {
|
||||
if (args[i].equals("-alpha")) {
|
||||
te.encodeAlpha = true;
|
||||
i++;
|
||||
} else if (args[i].equals("-filter")) {
|
||||
if (i != args.length - 1) {
|
||||
try {
|
||||
te.filter = Integer.parseInt(args[i + 1]);
|
||||
} catch (final Exception e) {
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
i += 2;
|
||||
} else if (args[i].equals("-compress")) {
|
||||
if (i != args.length - 1) {
|
||||
try {
|
||||
te.compressionLevel = Integer.parseInt(args[i + 1]);
|
||||
} catch (final Exception e) {
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
i += 2;
|
||||
} else {
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (te.pixelDepth == 8) {
|
||||
te.encodeAlpha = false;
|
||||
}
|
||||
te.doYourThing();
|
||||
}
|
||||
|
||||
public void doYourThing() {
|
||||
final Calendar cal = Calendar.getInstance();
|
||||
|
||||
hour = cal.get(Calendar.HOUR);
|
||||
if (cal.get(Calendar.AM_PM) == 1) {
|
||||
hour += 12;
|
||||
}
|
||||
hour %= 24;
|
||||
minute = cal.get(Calendar.MINUTE);
|
||||
|
||||
/*
|
||||
* format the time to a string of the form hhmm for use in the filename
|
||||
*/
|
||||
|
||||
timeStr = Integer.toString(minute);
|
||||
if (minute < 10) {
|
||||
timeStr = "0" + timeStr;
|
||||
}
|
||||
timeStr = Integer.toString(hour) + timeStr;
|
||||
if (hour < 10) {
|
||||
timeStr = "0" + timeStr;
|
||||
}
|
||||
|
||||
filename = (encodeAlpha) ? "alphaclock" : "clock";
|
||||
filename += timeStr + "_f" + filter + compressionLevel + ".png";
|
||||
|
||||
message = "File: " + filename;
|
||||
|
||||
final WindowListener l = new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(final WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
};
|
||||
addWindowListener(l);
|
||||
setVisible(true);
|
||||
// show();
|
||||
}
|
||||
|
||||
public void saveClockImage() {
|
||||
byte[] pngbytes;
|
||||
final PngEncoder png = new PngEncoder(clockImage,
|
||||
(encodeAlpha) ? PngEncoder.ENCODE_ALPHA : PngEncoder.NO_ALPHA,
|
||||
filter, compressionLevel);
|
||||
|
||||
try {
|
||||
final FileOutputStream outfile = new FileOutputStream(filename);
|
||||
pngbytes = png.pngEncode();
|
||||
if (pngbytes == null) {
|
||||
System.out.println("Null image");
|
||||
} else {
|
||||
outfile.write(pngbytes);
|
||||
}
|
||||
outfile.flush();
|
||||
outfile.close();
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
166
rene/util/list/ListClass.java
Normal file
166
rene/util/list/ListClass.java
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.list;
|
||||
|
||||
/**
|
||||
* A class for a list of things. The list is forward and backward chained.
|
||||
*
|
||||
* @see rene.list.ListElement
|
||||
*/
|
||||
|
||||
public class ListClass {
|
||||
ListElement First, Last; // Pointer to start and end of list.
|
||||
|
||||
/**
|
||||
* Generate an empty list.
|
||||
*/
|
||||
public ListClass() {
|
||||
First = null;
|
||||
Last = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a node to the list
|
||||
*/
|
||||
public void append(final ListElement l) {
|
||||
if (Last == null)
|
||||
init(l);
|
||||
else {
|
||||
Last.next(l);
|
||||
l.previous(Last);
|
||||
Last = l;
|
||||
l.next(null);
|
||||
l.list(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void prepend(final ListElement l)
|
||||
// prepend a node to the list
|
||||
{
|
||||
if (First == null)
|
||||
init(l);
|
||||
else {
|
||||
First.previous(l);
|
||||
l.next(First);
|
||||
First = l;
|
||||
l.previous(null);
|
||||
l.list(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @param l ListElement to be inserted.
|
||||
*
|
||||
* @param after If null, it works like prepend.
|
||||
*/
|
||||
public void insert(final ListElement l, final ListElement after) {
|
||||
if (after == Last)
|
||||
append(l);
|
||||
else if (after == null)
|
||||
prepend(l);
|
||||
else {
|
||||
after.next().previous(l);
|
||||
l.next(after.next());
|
||||
after.next(l);
|
||||
l.previous(after);
|
||||
l.list(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize the list with a single element.
|
||||
*/
|
||||
public void init(final ListElement l) {
|
||||
Last = First = l;
|
||||
l.previous(null);
|
||||
l.next(null);
|
||||
l.list(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a node from the list. The node really should be in the list, which
|
||||
* is not checked.
|
||||
*/
|
||||
public void remove(final ListElement l) {
|
||||
if (First == l) {
|
||||
First = l.next();
|
||||
if (First != null)
|
||||
First.previous(null);
|
||||
else
|
||||
Last = null;
|
||||
} else if (Last == l) {
|
||||
Last = l.previous();
|
||||
if (Last != null)
|
||||
Last.next(null);
|
||||
else
|
||||
First = null;
|
||||
} else {
|
||||
l.previous().next(l.next());
|
||||
l.next().previous(l.previous());
|
||||
}
|
||||
l.next(null);
|
||||
l.previous(null);
|
||||
l.list(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty the list.
|
||||
*/
|
||||
public void removeall() {
|
||||
First = null;
|
||||
Last = null;
|
||||
}
|
||||
|
||||
/** remove everything after e */
|
||||
public void removeAfter(final ListElement e) {
|
||||
e.next(null);
|
||||
Last = e;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return First ListElement.
|
||||
*/
|
||||
public ListElement first() {
|
||||
return First;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Last ListElement.
|
||||
*/
|
||||
public ListElement last() {
|
||||
return Last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the class
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
ListElement e = First;
|
||||
String s = "";
|
||||
while (e != null) {
|
||||
s = s + e.content().toString() + ", ";
|
||||
e = e.next();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
79
rene/util/list/ListElement.java
Normal file
79
rene/util/list/ListElement.java
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.list;
|
||||
|
||||
/**
|
||||
* The nodes of a list.
|
||||
*
|
||||
* @see rene.list.ListClass
|
||||
*/
|
||||
|
||||
public class ListElement
|
||||
// A list node with pointers to previous and next element
|
||||
// and with a content of type Object.
|
||||
{
|
||||
ListElement Next, Previous; // the chain pointers
|
||||
Object Content; // the content of the node
|
||||
ListClass L; // Belongs to this list
|
||||
|
||||
public ListElement(final Object content)
|
||||
// get a new Element with the content and null pointers
|
||||
{
|
||||
Content = content;
|
||||
Next = Previous = null;
|
||||
L = null;
|
||||
}
|
||||
|
||||
// access methods:
|
||||
public Object content() {
|
||||
return Content;
|
||||
}
|
||||
|
||||
public ListElement next() {
|
||||
return Next;
|
||||
}
|
||||
|
||||
public ListElement previous() {
|
||||
return Previous;
|
||||
}
|
||||
|
||||
public void list(final ListClass l) {
|
||||
L = l;
|
||||
}
|
||||
|
||||
// modifying methods:
|
||||
public void content(final Object o) {
|
||||
Content = o;
|
||||
}
|
||||
|
||||
public void next(final ListElement o) {
|
||||
Next = o;
|
||||
}
|
||||
|
||||
public void previous(final ListElement o) {
|
||||
Previous = o;
|
||||
}
|
||||
|
||||
public ListClass list() {
|
||||
return L;
|
||||
}
|
||||
}
|
118
rene/util/list/Tree.java
Normal file
118
rene/util/list/Tree.java
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.list;
|
||||
|
||||
/**
|
||||
* A node with a list of children trees.
|
||||
*/
|
||||
|
||||
public class Tree {
|
||||
ListClass Children; // list of children, each with Tree as content
|
||||
Object Content; // content
|
||||
ListElement Le; // the listelement containing the tree
|
||||
Tree Parent; // the parent tree
|
||||
|
||||
/** initialize with an object and no children */
|
||||
public Tree(final Object o) {
|
||||
Content = o;
|
||||
Children = new ListClass();
|
||||
Le = null;
|
||||
Parent = null;
|
||||
}
|
||||
|
||||
/** add a child tree */
|
||||
public void addchild(final Tree t) {
|
||||
final ListElement p = new ListElement(t);
|
||||
Children.append(p);
|
||||
t.Le = p;
|
||||
t.Parent = this;
|
||||
}
|
||||
|
||||
/** insert a child tree */
|
||||
public void insertchild(final Tree t) {
|
||||
if (!haschildren()) // simple case
|
||||
{
|
||||
addchild(t);
|
||||
return;
|
||||
}
|
||||
// give t my children
|
||||
t.Children = Children;
|
||||
// make t my only child
|
||||
Children = new ListClass();
|
||||
final ListElement p = new ListElement(t);
|
||||
Children.append(p);
|
||||
t.Le = p;
|
||||
t.Parent = this;
|
||||
// fix the parents of all grandchildren
|
||||
ListElement le = t.Children.first();
|
||||
while (le != null) {
|
||||
final Tree h = (Tree) (le.content());
|
||||
h.Parent = t;
|
||||
le = le.next();
|
||||
}
|
||||
}
|
||||
|
||||
/** remove the specific child tree (must be in the tree!!!) */
|
||||
public void remove(final Tree t) {
|
||||
if (t.parent() != this)
|
||||
return;
|
||||
Children.remove(t.Le);
|
||||
}
|
||||
|
||||
/** remove all children */
|
||||
public void removeall() {
|
||||
Children.removeall();
|
||||
}
|
||||
|
||||
// Access Methods:
|
||||
public boolean haschildren() {
|
||||
return Children.first() != null;
|
||||
}
|
||||
|
||||
public Tree firstchild() {
|
||||
return (Tree) Children.first().content();
|
||||
}
|
||||
|
||||
public Tree lastchild() {
|
||||
return (Tree) Children.last().content();
|
||||
}
|
||||
|
||||
public Tree parent() {
|
||||
return Parent;
|
||||
}
|
||||
|
||||
public ListClass children() {
|
||||
return Children;
|
||||
}
|
||||
|
||||
public Object content() {
|
||||
return Content;
|
||||
}
|
||||
|
||||
public void content(final Object o) {
|
||||
Content = o;
|
||||
}
|
||||
|
||||
public ListElement listelement() {
|
||||
return Le;
|
||||
}
|
||||
}
|
372
rene/util/parser/StringParser.java
Normal file
372
rene/util/parser/StringParser.java
Normal file
|
@ -0,0 +1,372 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.parser;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* This is a string simple parser.
|
||||
*/
|
||||
|
||||
public class StringParser {
|
||||
char C[];
|
||||
int N, L;
|
||||
boolean Error;
|
||||
|
||||
/**
|
||||
* @param S
|
||||
* the string to be parsed.
|
||||
*/
|
||||
public StringParser(final String S) {
|
||||
C = S.toCharArray();
|
||||
N = 0;
|
||||
L = C.length;
|
||||
Error = (N >= L);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return next character is white?
|
||||
*/
|
||||
public boolean blank() {
|
||||
return (C[N] == ' ' || C[N] == '\t' || C[N] == '\n' || C[N] == '\r');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return next character is white or c?
|
||||
*/
|
||||
public boolean blank(final char c) {
|
||||
return (C[N] == ' ' || C[N] == '\t' || C[N] == '\n' || C[N] == '\r' || C[N] == c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cut off the String upto a character c.
|
||||
*/
|
||||
public String upto(final char c) {
|
||||
if (Error)
|
||||
return "";
|
||||
int n = N;
|
||||
while (n < L && C[n] != c)
|
||||
n++;
|
||||
if (n >= L)
|
||||
Error = true;
|
||||
final String s = new String(C, N, n - N);
|
||||
N = n;
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance one character.
|
||||
*
|
||||
* @return String is not empty.
|
||||
*/
|
||||
public boolean advance() {
|
||||
if (N < L)
|
||||
N++;
|
||||
if (N >= L)
|
||||
Error = true;
|
||||
return !Error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a word up to a blank.
|
||||
*/
|
||||
public String parseword() {
|
||||
if (Error)
|
||||
return "";
|
||||
while (blank()) {
|
||||
if (!advance())
|
||||
return "";
|
||||
}
|
||||
final int n = N;
|
||||
while (!Error && !blank())
|
||||
advance();
|
||||
return new String(C, n, N - n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse digits upto the character c or blank.
|
||||
*/
|
||||
public String parsedigits(final char c) {
|
||||
if (Error)
|
||||
return "";
|
||||
while (blank()) {
|
||||
if (!advance())
|
||||
return "";
|
||||
}
|
||||
final int n = N;
|
||||
while (!Error && !blank()) {
|
||||
if (N > L || C[N] < '0' || C[N] > '9' || C[N] == c)
|
||||
break;
|
||||
advance();
|
||||
}
|
||||
return new String(C, n, N - n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse digits upto a blank.
|
||||
*/
|
||||
public String parsedigits() {
|
||||
if (Error)
|
||||
return "";
|
||||
while (blank()) {
|
||||
if (!advance())
|
||||
return "";
|
||||
}
|
||||
final int n = N;
|
||||
while (!Error && !blank()) {
|
||||
if (N > L || C[N] < '0' || C[N] > '9')
|
||||
break;
|
||||
advance();
|
||||
}
|
||||
return new String(C, n, N - n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a word upto the character c or blank.
|
||||
*/
|
||||
public String parseword(final char c) {
|
||||
if (Error)
|
||||
return "";
|
||||
while (blank()) {
|
||||
if (!advance())
|
||||
return "";
|
||||
}
|
||||
final int n = N;
|
||||
while (!Error && !blank(c))
|
||||
advance();
|
||||
return new String(C, n, N - n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return next character is a digit?
|
||||
*/
|
||||
public boolean isint() {
|
||||
if (Error)
|
||||
return false;
|
||||
return (C[N] >= '0' && C[N] <= '9');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an int upto a blank. The int may be negative.
|
||||
*
|
||||
* @return the int
|
||||
*/
|
||||
public int parseint() {
|
||||
int sig = 1;
|
||||
try {
|
||||
skipblanks();
|
||||
if (Error)
|
||||
return 0;
|
||||
if (C[N] == '-') {
|
||||
sig = -1;
|
||||
N++;
|
||||
if (N > L) {
|
||||
Error = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return sig * Integer.parseInt(parsedigits(), 10);
|
||||
} catch (final NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an int upto a blank or c. The int may be negative.
|
||||
*
|
||||
* @return the int
|
||||
*/
|
||||
public int parseint(final char c) {
|
||||
int sig = 1;
|
||||
try {
|
||||
skipblanks();
|
||||
if (Error)
|
||||
return 0;
|
||||
if (C[N] == '-') {
|
||||
sig = -1;
|
||||
N++;
|
||||
if (N > L) {
|
||||
Error = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return sig * Integer.parseInt(parsedigits(c), 10);
|
||||
} catch (final NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip all white characters.
|
||||
*/
|
||||
public void skipblanks() {
|
||||
if (Error)
|
||||
return;
|
||||
while (blank())
|
||||
if (!advance())
|
||||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip everything to the string s.
|
||||
*
|
||||
* @return String was found
|
||||
*/
|
||||
public boolean skip(final String s) {
|
||||
if (Error)
|
||||
return false;
|
||||
final int l = s.length();
|
||||
if (N + l > L)
|
||||
return false;
|
||||
if (!new String(C, N, l).equals(s))
|
||||
return false;
|
||||
N += l;
|
||||
if (N >= L)
|
||||
Error = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next character.
|
||||
*/
|
||||
public char next() {
|
||||
if (Error)
|
||||
return ' ';
|
||||
else {
|
||||
N++;
|
||||
if (N >= L) {
|
||||
Error = true;
|
||||
}
|
||||
return C[N - 1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a String, which is parsed from words with limited length.
|
||||
*
|
||||
* @param columns
|
||||
* the maximal length of the string
|
||||
*/
|
||||
public String wrapline(final int columns) {
|
||||
int n = N, good = N;
|
||||
String s = "";
|
||||
while (n < L) {
|
||||
if (C[n] == '\n') {
|
||||
if (n > N)
|
||||
s = new String(C, N, n - N);
|
||||
N = n + 1;
|
||||
break;
|
||||
}
|
||||
if (C[n] == ' ' || C[n] == '\t' || C[n] == '\n') {
|
||||
good = n;
|
||||
}
|
||||
n++;
|
||||
if (n - N >= columns && good > N) {
|
||||
s = new String(C, N, good - N);
|
||||
N = good + 1;
|
||||
break;
|
||||
}
|
||||
if (n >= L) {
|
||||
if (n > N)
|
||||
s = new String(C, N, n - N);
|
||||
N = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (N >= L)
|
||||
Error = true;
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the string into lines.
|
||||
*
|
||||
* @param columns
|
||||
* the maximal length of each line
|
||||
* @return a Vector with lines
|
||||
*/
|
||||
public Vector wraplines(final int columns) {
|
||||
final Vector v = new Vector(10, 10);
|
||||
String s;
|
||||
while (!Error) {
|
||||
s = wrapline(columns);
|
||||
v.addElement(s);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
public String wraplineword(final int columns) {
|
||||
int n = N;
|
||||
final int good = N;
|
||||
String s = "";
|
||||
while (n < L) {
|
||||
if (C[n] == '\n') {
|
||||
s = new String(C, N, n - N);
|
||||
N = n + 1;
|
||||
break;
|
||||
}
|
||||
n++;
|
||||
if (n >= L) {
|
||||
if (n > N)
|
||||
s = new String(C, N, n - N);
|
||||
N = n;
|
||||
break;
|
||||
}
|
||||
if (n - N >= columns && good > N) {
|
||||
s = new String(C, N, good - N);
|
||||
N = good + 1;
|
||||
if (N < L && C[N] != '\n')
|
||||
s = s + "\\";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (N >= L)
|
||||
Error = true;
|
||||
return s;
|
||||
}
|
||||
|
||||
public Vector wrapwords(final int columns) {
|
||||
final Vector v = new Vector(10, 10);
|
||||
String s;
|
||||
while (!Error) {
|
||||
s = wraplineword(columns);
|
||||
v.addElement(s);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace c1 by c2
|
||||
*/
|
||||
public void replace(final char c1, final char c2) {
|
||||
for (int i = 0; i < L; i++)
|
||||
if (C[i] == c1)
|
||||
C[i] = c2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if an error has occured during the parsing.
|
||||
*/
|
||||
public boolean error() {
|
||||
return Error;
|
||||
}
|
||||
}
|
26
rene/util/sort/SortObject.java
Normal file
26
rene/util/sort/SortObject.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.sort;
|
||||
|
||||
public interface SortObject {
|
||||
public int compare(SortObject o);
|
||||
}
|
40
rene/util/sort/SortString.java
Normal file
40
rene/util/sort/SortString.java
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.sort;
|
||||
|
||||
public class SortString implements SortObject {
|
||||
String S;
|
||||
|
||||
public SortString(final String s) {
|
||||
S = s;
|
||||
}
|
||||
|
||||
public int compare(final SortObject o) {
|
||||
final SortString s = (SortString) o;
|
||||
return S.compareTo(s.S);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return S;
|
||||
}
|
||||
}
|
36
rene/util/sort/SortStringNoCase.java
Normal file
36
rene/util/sort/SortStringNoCase.java
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.sort;
|
||||
|
||||
public class SortStringNoCase extends SortString {
|
||||
String Orig;
|
||||
|
||||
public SortStringNoCase(final String s) {
|
||||
super(s.toLowerCase());
|
||||
Orig = s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Orig;
|
||||
}
|
||||
}
|
140
rene/util/sort/Sorter.java
Normal file
140
rene/util/sort/Sorter.java
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.sort;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Quick sort implementation. Sorts an array or a vector of SortObject.
|
||||
*/
|
||||
|
||||
public class Sorter {
|
||||
static public void sort(final SortObject v[]) {
|
||||
QuickSort(v, 0, v.length - 1);
|
||||
}
|
||||
|
||||
static public void sort(final SortObject v[], final int n) {
|
||||
QuickSort(v, 0, n - 1);
|
||||
}
|
||||
|
||||
static public void sort(final Vector v) {
|
||||
final SortObject o[] = new SortObject[v.size()];
|
||||
v.copyInto(o);
|
||||
sort(o);
|
||||
for (int i = 0; i < o.length; i++)
|
||||
v.setElementAt(o[i], i);
|
||||
}
|
||||
|
||||
static public void QuickSort(final SortObject a[], final int lo0,
|
||||
final int hi0) {
|
||||
int lo = lo0;
|
||||
int hi = hi0;
|
||||
SortObject mid;
|
||||
|
||||
if (hi0 > lo0) {
|
||||
mid = a[(lo0 + hi0) / 2];
|
||||
while (lo <= hi) {
|
||||
while ((lo < hi0) && (a[lo].compare(mid) < 0))
|
||||
++lo;
|
||||
while ((hi > lo0) && (a[hi].compare(mid) > 0))
|
||||
--hi;
|
||||
if (lo <= hi) {
|
||||
swap(a, lo, hi);
|
||||
++lo;
|
||||
--hi;
|
||||
}
|
||||
}
|
||||
if (lo0 < hi)
|
||||
QuickSort(a, lo0, hi);
|
||||
if (lo < hi0)
|
||||
QuickSort(a, lo, hi0);
|
||||
}
|
||||
}
|
||||
|
||||
static private void swap(final SortObject a[], final int i, final int j) {
|
||||
SortObject T;
|
||||
T = a[i];
|
||||
a[i] = a[j];
|
||||
a[j] = T;
|
||||
}
|
||||
|
||||
static public void QuickSort(final Object a[], final int lo0, final int hi0) {
|
||||
int lo = lo0;
|
||||
int hi = hi0;
|
||||
SortObject mid;
|
||||
|
||||
if (hi0 > lo0) {
|
||||
mid = (SortObject) a[(lo0 + hi0) / 2];
|
||||
while (lo <= hi) {
|
||||
while ((lo < hi0) && (((SortObject) a[lo]).compare(mid) < 0))
|
||||
++lo;
|
||||
while ((hi > lo0) && (((SortObject) a[hi]).compare(mid) > 0))
|
||||
--hi;
|
||||
if (lo <= hi) {
|
||||
swap(a, lo, hi);
|
||||
++lo;
|
||||
--hi;
|
||||
}
|
||||
}
|
||||
if (lo0 < hi)
|
||||
QuickSort(a, lo0, hi);
|
||||
if (lo < hi0)
|
||||
QuickSort(a, lo, hi0);
|
||||
}
|
||||
}
|
||||
|
||||
static private void swap(final Object a[], final int i, final int j) {
|
||||
Object T;
|
||||
T = a[i];
|
||||
a[i] = a[j];
|
||||
a[j] = T;
|
||||
}
|
||||
|
||||
public static void main(final String args[]) throws IOException
|
||||
// Sort the incoming lines and remove doublicates
|
||||
{
|
||||
final BufferedReader in = new BufferedReader(new InputStreamReader(
|
||||
System.in));
|
||||
final Vector v = new Vector();
|
||||
while (true) {
|
||||
final String line = in.readLine();
|
||||
if (line == null)
|
||||
break;
|
||||
v.addElement(new SortString(line));
|
||||
}
|
||||
in.close();
|
||||
sort(v);
|
||||
final Enumeration e = v.elements();
|
||||
String last = null;
|
||||
while (e.hasMoreElements()) {
|
||||
final String s = ((SortString) e.nextElement()).toString();
|
||||
if (last == null || !s.equals(last)) {
|
||||
System.out.println(s);
|
||||
last = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
86
rene/util/xml/SVGWriter.java
Normal file
86
rene/util/xml/SVGWriter.java
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.xml;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class SVGWriter extends XmlWriter {
|
||||
int W, H;
|
||||
|
||||
public SVGWriter(final PrintWriter o, final String enc, final int w,
|
||||
final int h) {
|
||||
super(o);
|
||||
printEncoding(enc);
|
||||
W = w;
|
||||
H = h;
|
||||
startTagStart("svg");
|
||||
printArg("width", "" + w);
|
||||
printArg("height", "" + h);
|
||||
startTagEndNewLine();
|
||||
}
|
||||
|
||||
public SVGWriter(final PrintWriter o) {
|
||||
super(o);
|
||||
}
|
||||
|
||||
public void startSVG(final int w, final int h) {
|
||||
printEncoding("utf-8");
|
||||
Out.println("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"");
|
||||
Out.println("\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">");
|
||||
startTagStart("svg");
|
||||
printArg("xmlns", "http://www.w3.org/2000/svg");
|
||||
printArg("width", "" + w);
|
||||
printArg("height", "" + h);
|
||||
startTagEndNewLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
endTag("svg");
|
||||
super.close();
|
||||
}
|
||||
|
||||
public void coord(final int x, final int y) {
|
||||
printArg("x", "" + x);
|
||||
printArg("y", "" + y);
|
||||
}
|
||||
|
||||
public void text(final String text, final int x, final int y) {
|
||||
startTagStart("text");
|
||||
coord(x, y);
|
||||
startTagEnd();
|
||||
print(text);
|
||||
endTagNewLine("text");
|
||||
}
|
||||
|
||||
public static void main(final String args[]) throws Exception {
|
||||
final SVGWriter out = new SVGWriter(new PrintWriter(
|
||||
new FileOutputStream("test.svg")), "", 300, 300);
|
||||
out.text("Hallo Welt", 10, 95);
|
||||
out.startTagStart("path");
|
||||
out.printArg("d", "M 150 150 A 50 50 0 1 0 100 200");
|
||||
out.printArg("style", "fill:none;stroke-width:1;stroke:black");
|
||||
out.finishTagNewLine();
|
||||
out.close();
|
||||
}
|
||||
}
|
505
rene/util/xml/XmlReader.java
Normal file
505
rene/util/xml/XmlReader.java
Normal file
|
@ -0,0 +1,505 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.xml;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import rene.util.SimpleByteBuffer;
|
||||
import rene.util.SimpleStringBuffer;
|
||||
import rene.util.list.ListElement;
|
||||
|
||||
public class XmlReader {
|
||||
BufferedReader In;
|
||||
SimpleStringBuffer buf = new SimpleStringBuffer(10000);
|
||||
|
||||
public XmlReader() {
|
||||
In = null;
|
||||
}
|
||||
|
||||
public XmlReader(final BufferedReader in) {
|
||||
In = in;
|
||||
}
|
||||
|
||||
public XmlReader(final InputStream in) throws XmlReaderException {
|
||||
try { // read the file into a buffer
|
||||
final BufferedInputStream rin = new BufferedInputStream(in);
|
||||
final SimpleByteBuffer bb = new SimpleByteBuffer(10000);
|
||||
while (true) {
|
||||
final int k = rin.read();
|
||||
if (k < 0)
|
||||
break;
|
||||
bb.append((byte) k);
|
||||
}
|
||||
rin.close();
|
||||
final byte b[] = bb.getByteArray();
|
||||
|
||||
// Try to open an ASCII stream, or a default stream
|
||||
ByteArrayInputStream bin = new ByteArrayInputStream(b);
|
||||
XmlReader R = null;
|
||||
try {
|
||||
R = new XmlReader(new BufferedReader(new InputStreamReader(bin,
|
||||
"ASCII")));
|
||||
} catch (final UnsupportedEncodingException ex) {
|
||||
R = new XmlReader(
|
||||
new BufferedReader(new InputStreamReader(bin)));
|
||||
}
|
||||
|
||||
// Determine the encoding
|
||||
String Encoding = null;
|
||||
while (true) {
|
||||
while (true) {
|
||||
final int c = R.read();
|
||||
if (c == -1)
|
||||
throw new Exception("<?xml> tag not found");
|
||||
if (c == '<')
|
||||
break;
|
||||
}
|
||||
if (R.found("?xml")) {
|
||||
String s = R.scanFor("?>");
|
||||
if (s == null)
|
||||
throw new Exception("<?xml> tag error");
|
||||
int n = s.indexOf("encoding=\"");
|
||||
if (n >= 0) {
|
||||
n += "encoding=\"".length();
|
||||
s = s.substring(n);
|
||||
final int m = s.indexOf('\"');
|
||||
if (m < 0)
|
||||
throw new Exception("Closing bracket missing");
|
||||
Encoding = s.substring(0, m).toUpperCase();
|
||||
if (Encoding.equals("UTF-8"))
|
||||
Encoding = "UTF8";
|
||||
// for IE5 !
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Open a stream with this encoding
|
||||
bin = new ByteArrayInputStream(b);
|
||||
if (Encoding == null)
|
||||
In = new BufferedReader(new InputStreamReader(bin));
|
||||
else
|
||||
try {
|
||||
In = new BufferedReader(
|
||||
new InputStreamReader(bin, Encoding));
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
try {
|
||||
In = new BufferedReader(new InputStreamReader(bin,
|
||||
"ASCII"));
|
||||
} catch (final UnsupportedEncodingException ex) {
|
||||
In = new BufferedReader(new InputStreamReader(bin));
|
||||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
throw new XmlReaderException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void init(final InputStream in) throws XmlReaderException {
|
||||
try { // read the file into a buffer
|
||||
|
||||
final BufferedInputStream rin = new BufferedInputStream(in);
|
||||
final SimpleByteBuffer bb = new SimpleByteBuffer(10000);
|
||||
while (true) {
|
||||
final int k = rin.read();
|
||||
if (k < 0)
|
||||
break;
|
||||
bb.append((byte) k);
|
||||
}
|
||||
rin.close();
|
||||
final byte b[] = bb.getByteArray();
|
||||
|
||||
// Try to open an ASCII stream, or a default stream
|
||||
ByteArrayInputStream bin = new ByteArrayInputStream(b);
|
||||
XmlReader R = null;
|
||||
try {
|
||||
R = new XmlReader(new BufferedReader(new InputStreamReader(bin,
|
||||
"ASCII")));
|
||||
} catch (final UnsupportedEncodingException ex) {
|
||||
R = new XmlReader(
|
||||
new BufferedReader(new InputStreamReader(bin)));
|
||||
}
|
||||
|
||||
// Determine the encoding
|
||||
String Encoding = null;
|
||||
while (true) {
|
||||
while (true) {
|
||||
final int c = R.read();
|
||||
if (c == -1)
|
||||
throw new Exception("<?xml> tag not found");
|
||||
if (c == '<')
|
||||
break;
|
||||
}
|
||||
if (R.found("?xml")) {
|
||||
String s = R.scanFor("?>");
|
||||
if (s == null)
|
||||
throw new Exception("<?xml> tag error");
|
||||
int n = s.indexOf("encoding=\"");
|
||||
if (n >= 0) {
|
||||
n += "encoding=\"".length();
|
||||
s = s.substring(n);
|
||||
final int m = s.indexOf('\"');
|
||||
if (m < 0)
|
||||
throw new Exception("Closing bracket missing");
|
||||
Encoding = s.substring(0, m).toUpperCase();
|
||||
if (Encoding.equals("UTF-8"))
|
||||
Encoding = "UTF8";
|
||||
// for IE5 !
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Open a stream with this encoding
|
||||
bin = new ByteArrayInputStream(b);
|
||||
if (Encoding == null)
|
||||
In = new BufferedReader(new InputStreamReader(bin));
|
||||
else
|
||||
try {
|
||||
In = new BufferedReader(
|
||||
new InputStreamReader(bin, Encoding));
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
try {
|
||||
In = new BufferedReader(new InputStreamReader(bin,
|
||||
"ASCII"));
|
||||
} catch (final UnsupportedEncodingException ex) {
|
||||
In = new BufferedReader(new InputStreamReader(bin));
|
||||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
throw new XmlReaderException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan an xml file. This function reads, until <?xml is found. then it
|
||||
* skips this declaration and scans the rest of the items.
|
||||
*/
|
||||
public XmlTree scan() throws XmlReaderException {
|
||||
while (true) {
|
||||
while (true) {
|
||||
final int c = read();
|
||||
if (c == -1)
|
||||
return null;
|
||||
if (c == '<')
|
||||
break;
|
||||
}
|
||||
if (found("?xml")) {
|
||||
final String s = scanFor("?>");
|
||||
if (s == null)
|
||||
return null;
|
||||
final XmlTree t = new XmlTree(new XmlTagRoot());
|
||||
t.addchild(new XmlTree(new XmlTagPI(s)));
|
||||
scanContent(t);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void scanContent(final XmlTree t) throws XmlReaderException { // System.out.println("Sanning for "+t.getTag().name()+" ("+
|
||||
// t.getTag().countParams()+")");
|
||||
while (true) {
|
||||
String s = scanFor('<');
|
||||
if (s == null) {
|
||||
if (t.getTag() instanceof XmlTagRoot)
|
||||
return;
|
||||
exception("File ended surprisingly");
|
||||
}
|
||||
if (!empty(s)) {
|
||||
t
|
||||
.addchild(new XmlTree(new XmlTagText(XmlTranslator
|
||||
.toText(s))));
|
||||
}
|
||||
if (found("!--")) {
|
||||
s = scanFor("-->");
|
||||
continue;
|
||||
}
|
||||
if (found("!")) {
|
||||
s = scanTagFor('>');
|
||||
continue;
|
||||
}
|
||||
if (found("?")) {
|
||||
s = scanTagFor("?>");
|
||||
t.addchild(new XmlTree(new XmlTagPI(s)));
|
||||
continue;
|
||||
}
|
||||
s = scanTagFor('>');
|
||||
if (s == null)
|
||||
exception("> missing");
|
||||
if (s.startsWith("/")) {
|
||||
if (s.substring(1).equals(t.getTag().name()))
|
||||
return;
|
||||
else
|
||||
exception("End tag without start tag");
|
||||
}
|
||||
if (s.endsWith("/")) {
|
||||
t.addchild(new XmlTree(new XmlTag(s
|
||||
.substring(0, s.length() - 1))));
|
||||
} else {
|
||||
final XmlTree t0 = new XmlTree(new XmlTag(s));
|
||||
scanContent(t0);
|
||||
t.addchild(t0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean empty(final String s) {
|
||||
final int n = s.length();
|
||||
for (int i = 0; i < n; i++) {
|
||||
final char c = s.charAt(i);
|
||||
if (c != ' ' && c != '\n' && c != '\t')
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip Blanks.
|
||||
*
|
||||
* @return Non-blank character or -1 for EOF.
|
||||
*/
|
||||
public int skipBlanks() throws XmlReaderException {
|
||||
while (true) {
|
||||
final int c = read();
|
||||
if (c == ' ' || c == '\t' || c == '\n')
|
||||
continue;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan for an end character.
|
||||
*
|
||||
* @return String between the current position and the end character, or
|
||||
* null.
|
||||
*/
|
||||
public String scanFor(final char end) throws XmlReaderException {
|
||||
buf.clear();
|
||||
int c = read();
|
||||
while (c != end) {
|
||||
buf.append((char) c);
|
||||
c = read();
|
||||
if (c < 0)
|
||||
return null;
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan for a specific string.
|
||||
*
|
||||
* @return String between the current position and the string.
|
||||
*/
|
||||
public String scanFor(final String s) throws XmlReaderException {
|
||||
buf.clear();
|
||||
while (!found(s)) {
|
||||
final int c = read();
|
||||
if (c < 0)
|
||||
return null;
|
||||
buf.append((char) c);
|
||||
}
|
||||
for (int i = 0; i < s.length(); i++)
|
||||
read();
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan tag for an end character (interpreting " and ')
|
||||
*
|
||||
* @return String between the current position and the end character, or
|
||||
* null.
|
||||
*/
|
||||
public String scanTagFor(final char end) throws XmlReaderException {
|
||||
buf.clear();
|
||||
int c = read();
|
||||
while (c != end) {
|
||||
if (c == '\"') {
|
||||
buf.append((char) c);
|
||||
while (true) {
|
||||
c = read();
|
||||
if (c < 0)
|
||||
return null;
|
||||
if (c == '\"')
|
||||
break;
|
||||
buf.append((char) c);
|
||||
}
|
||||
buf.append((char) c);
|
||||
} else if (c == '\'') {
|
||||
buf.append((char) c);
|
||||
while (true) {
|
||||
c = read();
|
||||
if (c < 0)
|
||||
return null;
|
||||
if (c == '\'')
|
||||
break;
|
||||
buf.append((char) c);
|
||||
}
|
||||
buf.append((char) c);
|
||||
} else
|
||||
buf.append((char) c);
|
||||
c = read();
|
||||
if (c < 0)
|
||||
return null;
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan tag for a specific string (interpreting " and ')
|
||||
*
|
||||
* @return String between the current position and the string.
|
||||
*/
|
||||
public String scanTagFor(final String s) throws XmlReaderException {
|
||||
buf.clear();
|
||||
while (!found(s)) {
|
||||
int c = read();
|
||||
if (c < 0)
|
||||
return null;
|
||||
if (c == '\"') {
|
||||
buf.append((char) c);
|
||||
while (true) {
|
||||
c = read();
|
||||
if (c < 0)
|
||||
return null;
|
||||
if (c == '\"')
|
||||
break;
|
||||
buf.append((char) c);
|
||||
}
|
||||
buf.append((char) c);
|
||||
} else if (c == '\'') {
|
||||
buf.append((char) c);
|
||||
while (true) {
|
||||
c = read();
|
||||
if (c < 0)
|
||||
return null;
|
||||
if (c == '\'')
|
||||
break;
|
||||
buf.append((char) c);
|
||||
}
|
||||
buf.append((char) c);
|
||||
} else
|
||||
buf.append((char) c);
|
||||
}
|
||||
for (int i = 0; i < s.length(); i++)
|
||||
read();
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
String Line = null;
|
||||
int LinePos;
|
||||
|
||||
public int read() throws XmlReaderException {
|
||||
try {
|
||||
if (Line == null) {
|
||||
Line = In.readLine();
|
||||
LinePos = 0;
|
||||
// System.out.println("Read --> "+Line);
|
||||
}
|
||||
if (Line == null)
|
||||
return -1;
|
||||
if (LinePos >= Line.length()) {
|
||||
Line = null;
|
||||
return '\n';
|
||||
}
|
||||
return Line.charAt(LinePos++);
|
||||
} catch (final Exception e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If the string is at the current line position.
|
||||
*/
|
||||
public boolean found(final String s) {
|
||||
final int n = s.length();
|
||||
if (LinePos + n > Line.length())
|
||||
return false;
|
||||
for (int i = 0; i < n; i++)
|
||||
if (s.charAt(i) != Line.charAt(LinePos + i))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void exception(final String s) throws XmlReaderException {
|
||||
throw new XmlReaderException(s, Line, LinePos);
|
||||
}
|
||||
|
||||
/**
|
||||
* A test program.
|
||||
*/
|
||||
public static void main(final String args[]) {
|
||||
try {
|
||||
final BufferedReader in = new BufferedReader(new InputStreamReader(
|
||||
new FileInputStream("rene\\util\\xml\\test.xml"), "UTF8"));
|
||||
final XmlReader reader = new XmlReader(in);
|
||||
final XmlTree tree = reader.scan();
|
||||
in.close();
|
||||
print(tree);
|
||||
} catch (final XmlReaderException e) {
|
||||
System.out.println(e.toString() + "\n" + e.getLine() + "\n"
|
||||
+ "Position : " + e.getPos());
|
||||
} catch (final IOException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void print(final XmlTree t) {
|
||||
final XmlTag tag = t.getTag();
|
||||
System.out.print("<" + tag.name());
|
||||
for (int i = 0; i < tag.countParams(); i++) {
|
||||
System.out.print(" " + tag.getParam(i) + "=\"" + tag.getValue(i)
|
||||
+ "\"");
|
||||
}
|
||||
System.out.println(">");
|
||||
ListElement el = t.children().first();
|
||||
while (el != null) {
|
||||
print((XmlTree) (el.content()));
|
||||
el = el.next();
|
||||
}
|
||||
System.out.println("</" + tag.name() + ">");
|
||||
}
|
||||
|
||||
public static boolean testXml(final String s) {
|
||||
int i = 0;
|
||||
while (i < s.length()) {
|
||||
final char c = s.charAt(i);
|
||||
if (c == '<')
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
if (i >= s.length())
|
||||
return false;
|
||||
if (s.substring(i).startsWith("<?xml"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
55
rene/util/xml/XmlReaderException.java
Normal file
55
rene/util/xml/XmlReaderException.java
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.xml;
|
||||
|
||||
public class XmlReaderException extends Exception {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
String Line;
|
||||
int Pos;
|
||||
String S;
|
||||
|
||||
public XmlReaderException(final String s, final String line, final int pos) {
|
||||
super(s);
|
||||
S = s;
|
||||
Line = line;
|
||||
Pos = pos;
|
||||
}
|
||||
|
||||
public XmlReaderException(final String s) {
|
||||
this(s, "", 0);
|
||||
}
|
||||
|
||||
public String getLine() {
|
||||
return Line;
|
||||
}
|
||||
|
||||
public int getPos() {
|
||||
return Pos;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return S;
|
||||
}
|
||||
}
|
149
rene/util/xml/XmlTag.java
Normal file
149
rene/util/xml/XmlTag.java
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.xml;
|
||||
|
||||
public class XmlTag {
|
||||
protected String Tag = "";
|
||||
String Param[];
|
||||
String Value[];
|
||||
int N = 0;
|
||||
|
||||
public XmlTag(final String s) {
|
||||
int n = 0;
|
||||
int k = 0;
|
||||
n = skipBlanks(s, n);
|
||||
while (n < s.length()) {
|
||||
n = endItem(s, n);
|
||||
k++;
|
||||
n = skipBlanks(s, n);
|
||||
}
|
||||
if (k == 0)
|
||||
return;
|
||||
n = 0;
|
||||
n = skipBlanks(s, n);
|
||||
int m = endItem(s, n);
|
||||
Tag = s.substring(n, m);
|
||||
n = m;
|
||||
N = k - 1;
|
||||
Param = new String[N];
|
||||
Value = new String[N];
|
||||
for (int i = 0; i < N; i++) {
|
||||
n = skipBlanks(s, n);
|
||||
m = endItem(s, n);
|
||||
final String p = s.substring(n, m);
|
||||
n = m;
|
||||
final int kp = p.indexOf('=');
|
||||
if (kp >= 0) {
|
||||
Param[i] = p.substring(0, kp);
|
||||
Value[i] = XmlTranslator.toText(p.substring(kp + 1));
|
||||
if (Value[i].startsWith("\"") && Value[i].endsWith("\"")) {
|
||||
Value[i] = Value[i].substring(1, Value[i].length() - 1);
|
||||
} else if (Value[i].startsWith("\'") && Value[i].endsWith("\'")) {
|
||||
Value[i] = Value[i].substring(1, Value[i].length() - 1);
|
||||
}
|
||||
} else {
|
||||
Param[i] = p;
|
||||
Value[i] = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int skipBlanks(final String s, int n) {
|
||||
while (n < s.length()) {
|
||||
final char c = s.charAt(n);
|
||||
if (c == ' ' || c == '\t' || c == '\n')
|
||||
n++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int endItem(final String s, int n) {
|
||||
while (n < s.length()) {
|
||||
final char c = s.charAt(n);
|
||||
if (c == ' ' || c == '\t' || c == '\n')
|
||||
break;
|
||||
if (c == '\"') {
|
||||
n++;
|
||||
while (true) {
|
||||
if (n >= s.length())
|
||||
return n;
|
||||
if (s.charAt(n) == '\"')
|
||||
break;
|
||||
n++;
|
||||
}
|
||||
} else if (c == '\'') {
|
||||
n++;
|
||||
while (true) {
|
||||
if (n >= s.length())
|
||||
return n;
|
||||
if (s.charAt(n) == '\'')
|
||||
break;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return Tag;
|
||||
}
|
||||
|
||||
public int countParams() {
|
||||
return N;
|
||||
}
|
||||
|
||||
public String getParam(final int i) {
|
||||
return Param[i];
|
||||
}
|
||||
|
||||
public String getValue(final int i) {
|
||||
return Value[i];
|
||||
}
|
||||
|
||||
public boolean hasParam(final String param) {
|
||||
for (int i = 0; i < N; i++)
|
||||
if (Param[i].equals(param))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasTrueParam(final String param) {
|
||||
for (int i = 0; i < N; i++)
|
||||
if (Param[i].equals(param)) {
|
||||
if (Value[i].equals("true"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getValue(final String param) {
|
||||
for (int i = 0; i < N; i++)
|
||||
if (Param[i].equals(param))
|
||||
return Value[i];
|
||||
return null;
|
||||
}
|
||||
}
|
30
rene/util/xml/XmlTagPI.java
Normal file
30
rene/util/xml/XmlTagPI.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.xml;
|
||||
|
||||
public class XmlTagPI extends XmlTag {
|
||||
String Content;
|
||||
|
||||
public XmlTagPI(final String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
30
rene/util/xml/XmlTagRoot.java
Normal file
30
rene/util/xml/XmlTagRoot.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.xml;
|
||||
|
||||
public class XmlTagRoot extends XmlTag {
|
||||
String Content;
|
||||
|
||||
public XmlTagRoot() {
|
||||
super("#ROOT");
|
||||
}
|
||||
}
|
35
rene/util/xml/XmlTagText.java
Normal file
35
rene/util/xml/XmlTagText.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.xml;
|
||||
|
||||
public class XmlTagText extends XmlTag {
|
||||
String Content;
|
||||
|
||||
public XmlTagText(final String s) {
|
||||
super("#PCDATA");
|
||||
Content = s;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return Content;
|
||||
}
|
||||
}
|
104
rene/util/xml/XmlTranslator.java
Normal file
104
rene/util/xml/XmlTranslator.java
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.xml;
|
||||
|
||||
import rene.util.SimpleStringBuffer;
|
||||
|
||||
public class XmlTranslator {
|
||||
static SimpleStringBuffer H = new SimpleStringBuffer(10000);
|
||||
|
||||
static String toXml(final String s) {
|
||||
final int m = s.length();
|
||||
H.clear();
|
||||
for (int i = 0; i < m; i++) {
|
||||
final char c = s.charAt(i);
|
||||
switch (c) {
|
||||
case '<':
|
||||
toH("<");
|
||||
break;
|
||||
case '>':
|
||||
toH(">");
|
||||
break;
|
||||
case '&':
|
||||
toH("&");
|
||||
break;
|
||||
case '\'':
|
||||
toH("'");
|
||||
break;
|
||||
case '\"':
|
||||
toH(""");
|
||||
break;
|
||||
default:
|
||||
H.append(c);
|
||||
}
|
||||
}
|
||||
return H.toString();
|
||||
}
|
||||
|
||||
static void toH(final String s) {
|
||||
final int m = s.length();
|
||||
for (int i = 0; i < m; i++) {
|
||||
H.append(s.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
static String toText(final String s) {
|
||||
final int m = s.length();
|
||||
H.clear();
|
||||
for (int i = 0; i < m; i++) {
|
||||
final char c = s.charAt(i);
|
||||
if (c == '&') {
|
||||
if (find(s, i, "<")) {
|
||||
H.append('<');
|
||||
i += 3;
|
||||
} else if (find(s, i, ">")) {
|
||||
H.append('>');
|
||||
i += 3;
|
||||
} else if (find(s, i, """)) {
|
||||
H.append('\"');
|
||||
i += 5;
|
||||
} else if (find(s, i, "'")) {
|
||||
H.append('\'');
|
||||
i += 5;
|
||||
} else if (find(s, i, "&")) {
|
||||
H.append('&');
|
||||
i += 4;
|
||||
} else
|
||||
H.append(c);
|
||||
} else
|
||||
H.append(c);
|
||||
}
|
||||
return H.toString();
|
||||
}
|
||||
|
||||
static boolean find(final String s, final int pos, final String t) {
|
||||
try {
|
||||
for (int i = 0; i < t.length(); i++) {
|
||||
if (s.charAt(pos + i) != t.charAt(i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (final Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
119
rene/util/xml/XmlTree.java
Normal file
119
rene/util/xml/XmlTree.java
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.xml;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
import rene.util.list.ListElement;
|
||||
import rene.util.list.Tree;
|
||||
import rene.util.parser.StringParser;
|
||||
|
||||
public class XmlTree extends Tree implements Enumeration {
|
||||
public XmlTree(final XmlTag t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
public XmlTag getTag() {
|
||||
return (XmlTag) content();
|
||||
}
|
||||
|
||||
public XmlTree xmlFirstContent() {
|
||||
if (firstchild() != null)
|
||||
return (XmlTree) firstchild();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isText() {
|
||||
if (!haschildren())
|
||||
return true;
|
||||
if (firstchild() != lastchild())
|
||||
return false;
|
||||
final XmlTree t = (XmlTree) firstchild();
|
||||
final XmlTag tag = t.getTag();
|
||||
if (!(tag instanceof XmlTagText))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
if (!haschildren())
|
||||
return "";
|
||||
final XmlTree t = (XmlTree) firstchild();
|
||||
final XmlTag tag = t.getTag();
|
||||
return ((XmlTagText) tag).getContent();
|
||||
}
|
||||
|
||||
ListElement Current;
|
||||
|
||||
public Enumeration getContent() {
|
||||
Current = children().first();
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return Current != null;
|
||||
}
|
||||
|
||||
public Object nextElement() {
|
||||
if (Current == null)
|
||||
return null;
|
||||
final XmlTree c = (XmlTree) (Current.content());
|
||||
Current = Current.next();
|
||||
return c;
|
||||
}
|
||||
|
||||
public String parseComment() throws XmlReaderException {
|
||||
final StringBuffer s = new StringBuffer();
|
||||
final Enumeration e = getContent();
|
||||
while (e.hasMoreElements()) {
|
||||
final XmlTree tree = (XmlTree) e.nextElement();
|
||||
final XmlTag tag = tree.getTag();
|
||||
if (tag.name().equals("P")) {
|
||||
if (!tree.haschildren())
|
||||
s.append("\n");
|
||||
else {
|
||||
final XmlTree h = tree.xmlFirstContent();
|
||||
String k = ((XmlTagText) h.getTag()).getContent();
|
||||
k = k.replace('\n', ' ');
|
||||
final StringParser p = new StringParser(k);
|
||||
final Vector v = p.wraplines(1000);
|
||||
for (int i = 0; i < v.size(); i++) {
|
||||
s.append((String) v.elementAt(i));
|
||||
s.append("\n");
|
||||
}
|
||||
}
|
||||
} else if (tag instanceof XmlTagText) {
|
||||
final String k = ((XmlTagText) tag).getContent();
|
||||
final StringParser p = new StringParser(k);
|
||||
final Vector v = p.wraplines(1000);
|
||||
for (int i = 0; i < v.size(); i++) {
|
||||
s.append((String) v.elementAt(i));
|
||||
s.append("\n");
|
||||
}
|
||||
} else
|
||||
throw new XmlReaderException("<" + tag.name()
|
||||
+ "> not proper here.");
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
}
|
203
rene/util/xml/XmlWriter.java
Normal file
203
rene/util/xml/XmlWriter.java
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
||||
|
||||
This file is part of C.a.R. software.
|
||||
|
||||
C.a.R. is a free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
C.a.R. is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
package rene.util.xml;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Vector;
|
||||
|
||||
import rene.util.parser.StringParser;
|
||||
|
||||
public class XmlWriter {
|
||||
PrintWriter Out;
|
||||
|
||||
public XmlWriter(final PrintWriter o) {
|
||||
Out = o;
|
||||
}
|
||||
|
||||
public void printTag(final String tag, final String content) {
|
||||
startTag(tag);
|
||||
print(content);
|
||||
endTag(tag);
|
||||
}
|
||||
|
||||
public void printTagNewLine(final String tag, final String content) {
|
||||
printTag(tag, content);
|
||||
Out.println();
|
||||
}
|
||||
|
||||
public void printTag(final String tag, final String arg,
|
||||
final String value, final String content) {
|
||||
startTag(tag, arg, value);
|
||||
print(content);
|
||||
endTag(tag);
|
||||
}
|
||||
|
||||
public void printTagNewLine(final String tag, final String arg,
|
||||
final String value, final String content) {
|
||||
printTag(tag, arg, value, content);
|
||||
Out.println();
|
||||
}
|
||||
|
||||
public void startTag(final String tag) {
|
||||
Out.print("<");
|
||||
Out.print(tag);
|
||||
Out.print(">");
|
||||
}
|
||||
|
||||
public void startTag(final String tag, final String arg, final String value) {
|
||||
Out.print("<");
|
||||
Out.print(tag);
|
||||
printArg(arg, value);
|
||||
Out.print(">");
|
||||
}
|
||||
|
||||
public void finishTag(final String tag, final String arg, final String value) {
|
||||
Out.print("<");
|
||||
Out.print(tag);
|
||||
printArg(arg, value);
|
||||
Out.println("/>");
|
||||
}
|
||||
|
||||
public void finishTag(final String tag) {
|
||||
Out.print("<");
|
||||
Out.print(tag);
|
||||
Out.print("/>");
|
||||
}
|
||||
|
||||
public void finishTagNewLine(final String tag) {
|
||||
Out.print("<");
|
||||
Out.print(tag);
|
||||
Out.println("/>");
|
||||
}
|
||||
|
||||
public void startTagStart(final String tag) {
|
||||
Out.print("<");
|
||||
Out.print(tag);
|
||||
}
|
||||
|
||||
public void startTagEnd() {
|
||||
Out.print(">");
|
||||
}
|
||||
|
||||
public void finishTag() {
|
||||
Out.print("/>");
|
||||
}
|
||||
|
||||
public void finishTagNewLine() {
|
||||
Out.println("/>");
|
||||
}
|
||||
|
||||
public void startTagEndNewLine() {
|
||||
Out.println(">");
|
||||
}
|
||||
|
||||
public void printArg(final String arg, final String value) {
|
||||
Out.print(" ");
|
||||
print(arg);
|
||||
Out.print("=\"");
|
||||
print(value);
|
||||
Out.print("\"");
|
||||
}
|
||||
|
||||
public void startTagNewLine(final String tag, final String arg,
|
||||
final String value) {
|
||||
startTag(tag, arg, value);
|
||||
Out.println();
|
||||
}
|
||||
|
||||
public void startTagNewLine(final String tag) {
|
||||
startTag(tag);
|
||||
Out.println();
|
||||
}
|
||||
|
||||
public void endTag(final String tag) {
|
||||
Out.print("</");
|
||||
Out.print(tag);
|
||||
Out.print(">");
|
||||
}
|
||||
|
||||
public void endTagNewLine(final String tag) {
|
||||
endTag(tag);
|
||||
Out.println();
|
||||
}
|
||||
|
||||
public void println() {
|
||||
Out.println();
|
||||
}
|
||||
|
||||
public void print(final String s) {
|
||||
Out.print(XmlTranslator.toXml(s));
|
||||
}
|
||||
|
||||
public void println(final String s) {
|
||||
Out.println(XmlTranslator.toXml(s));
|
||||
}
|
||||
|
||||
public void printEncoding(final String s) {
|
||||
if (s.equals(""))
|
||||
Out.println("<?xml version=\"1.0\"?>");
|
||||
else
|
||||
Out.println("<?xml version=\"1.0\" encoding=\"" + s + "\"?>");
|
||||
}
|
||||
|
||||
public void printXml() {
|
||||
printEncoding("");
|
||||
}
|
||||
|
||||
public void printEncoding() {
|
||||
printEncoding("utf-8");
|
||||
}
|
||||
|
||||
public void printXls(final String s) {
|
||||
Out.println("<?xml-stylesheet href=\"" + s + "\" type=\"text/xsl\"?>");
|
||||
}
|
||||
|
||||
public void printParagraphs(String s, final int linelength) {
|
||||
final StringParser p = new StringParser(s);
|
||||
final Vector v = p.wrapwords(linelength);
|
||||
for (int i = 0; i < v.size(); i++) {
|
||||
startTag("P");
|
||||
s = (String) v.elementAt(i);
|
||||
final StringParser q = new StringParser(s);
|
||||
final Vector w = q.wraplines(linelength);
|
||||
for (int j = 0; j < w.size(); j++) {
|
||||
if (j > 0)
|
||||
println();
|
||||
s = (String) w.elementAt(j);
|
||||
print(s);
|
||||
}
|
||||
endTagNewLine("P");
|
||||
}
|
||||
}
|
||||
|
||||
public void printDoctype(final String top, final String dtd) {
|
||||
Out.print("<!DOCTYPE ");
|
||||
Out.print(top);
|
||||
Out.print(" SYSTEM \"");
|
||||
Out.print(dtd);
|
||||
Out.println("\">");
|
||||
}
|
||||
|
||||
public void close() {
|
||||
Out.close();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue