First commit.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,54 @@
+# PRJ
+PRJ=horaris
+VENDOR=viric
+VERSION=0.1
+
+# RTE
+WTK2?=/opt/wtk2.2
+EMULATOR=${WTK2}/bin/emulator
+CLASSPATH=${WTK2}/lib/midpapi20.jar:${WTK2}/lib/cldcapi11.jar:${PRJ}.jar:.
+#CLASSPATH=${WTK2}/lib/midpapi.zip:mojab.jar:./src/:.
+SRCDIRS=${PRJ} ogdl
+PKGADDONS=icons data
+
+# TARJETS
+all:
+ @cd src && mkdir -p output ${SRCDIRS} ${PKGADDONS}
+ @echo "==> Building"
+ @cd src && \
+ javac -source 1.2 -target 1.1 -classpath ${CLASSPATH} \
+ -bootclasspath ${CLASSPATH} -encoding UTF-8 \
+ `find ${SRCDIRS} -type f -iname *.java`
+ @echo "==> Preverifying"
+ @cd src && \
+ ${WTK2}/bin/preverify1.1 -classpath ./:${CLASSPATH} \
+ `find ${SRCDIRS} |grep class|awk -F . '{ print $$1; }'`
+
+clean:
+ @echo "==> Cleaning"
+ @rm -rf ${PRJ}.jad ${PRJ}.jar `find src/| grep class` src/output javadoc
+
+doc:
+ @echo "==> Generating documentation"
+ @cd src && \
+ javadoc -classpath ${CLASSPATH} -d ../javadoc/ \
+ `find ${SRCDIRS} -type f -iname *.java`
+
+jar:
+ @echo "==> Generating JAR file"
+ @cd src && cp -rf ${PKGADDONS} output/
+ @cd src/output && \
+ jar cmf ../META-INF/MANIFEST.MF ../${PRJ}.jar `find .| grep class` ${PKGADDONS}
+ @mv src/${PRJ}.jar ./
+ @echo "==> Generating manifest for JAD file"
+ @echo "MIDlet-1: ${PRJ}, /icons/online.png, ${PRJ}.Main" > ${PRJ}.jad
+ @echo "MIDlet-Jar-Size: `ls -l ${PRJ}.jar|awk '{print $$5 }'`" >> ${PRJ}.jad
+ @echo "MIDlet-Jar-URL: ${PRJ}.jar" >> ${PRJ}.jad
+ @echo "MIDlet-Name: ${PRJ}" >> ${PRJ}.jad
+ @echo "MIDlet-Vendor: ${VENDOR}" >> ${PRJ}.jad
+ @echo "MIDlet-Version: ${VERSION}" >> ${PRJ}.jad
+
+run:
+ @echo "==> Running emulator"
+ @${EMULATOR} -classpath ${CLASSPATH} -Xdescriptor:${PRJ}.jad \
+ -Xdevice:DefaultColorPhone
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/META-INF/MANIFEST.MF Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,6 @@
+MIDlet-1: horaris, , horaris.Main
+MIDlet-Name: Horaris
+MIDlet-Vendor: viric
+MIDlet-Version: 0.1
+MicroEdition-Configuration: CLDC-1.1
+MicroEdition-Profile: MIDP-1.0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/data/list.g Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,1 @@
+teisa.g Teisa-Olot
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/data/teisa.g Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,254 @@
+Dies
+ "Dl-Dv Feiners"
+ Dissabte
+ Festiu
+ "Festiu Vigilia Universitari"
+ "Dv o últim dia lectiu"
+Llocs
+ Olot
+ Banyoles
+ Amer
+ Barcelona
+Sentits
+ Olot-Barcelona
+ Olot
+ Barcelona
+ Barcelona-Olot
+ Barcelona
+ Olot
+
+# Horaris per banyoles
+Comboi
+ Dies
+ "Dl-Dv Feiners"
+ Dissabte
+ Comentari "Per Banyoles"
+ Sentit Olot-Barcelona
+ Hores
+ 6:30 Olot
+ 7:10 Banyoles
+ 8:35 Barcelona
+Comboi
+ Dies
+ Festiu
+ Comentari "Per Banyoles"
+ Sentit Olot-Barcelona
+ Hores
+ 7:30 Olot
+ 8:10 Banyoles
+ 9:35 Barcelona
+Comboi
+ Dies
+ "Dl-Dv Feiners"
+ Dissabte
+ Comentari "Per Banyoles Semidirecte"
+ Sentit Olot-Barcelona
+ Hores
+ 8:40 Olot
+ 9:20 Banyoles
+ 10:40 Barcelona
+Comboi
+ Dies
+ "Dl-Dv Feiners"
+ Dissabte
+ Comentari "Per Banyoles"
+ Sentit Olot-Barcelona
+ Hores
+ 13:30 Olot
+ 14:10 Banyoles
+ 15:35 Barcelona
+Comboi
+ Dies
+ Festiu
+ "Dl-Dv Feiners"
+ Dissabte
+ "Festiu Vigilia Universitari"
+ "Dv o últim dia lectiu"
+ Comentari "Per Banyoles"
+ Sentit Olot-Barcelona
+ Hores
+ 16:30 Olot
+ 17:10 Banyoles
+ 18:35 Barcelona
+Comboi
+ Dies
+ Festiu
+ Comentari "Per Banyoles"
+ Sentit Olot-Barcelona
+ Hores
+ 18:30 Olot
+ 19:10 Banyoles
+ 20:35 Barcelona
+Comboi
+ Dies
+ "Dl-Dv Feiners"
+ Comentari "Per Banyoles"
+ Sentit Barcelona-Olot
+ Hores
+ 9:00 Barcelona
+ 10:22 Banyoles
+ 11:00 Olot
+Comboi
+ Dies
+ Dissabte
+ Festiu
+ Comentari "Per Banyoles"
+ Sentit Barcelona-Olot
+ Hores
+ 9:30 Barcelona
+ 10:52 Banyoles
+ 11:30 Olot
+Comboi
+ Dies
+ "Dl-Dv Feiners"
+ Dissabte
+ Comentari "Per Banyoles"
+ Sentit Barcelona-Olot
+ Hores
+ 14:00 Barcelona
+ 15:22 Banyoles
+ 16:00 Olot
+Comboi
+ Dies
+ "Dl-Dv Feiners"
+ Dissabte
+ Comentari "Per Banyoles. Semidirecte"
+ Sentit Barcelona-Olot
+ Hores
+ 17:00 Barcelona
+ 18:22 Banyoles
+ 19:00 Olot
+Comboi
+ Dies
+ "Dl-Dv Feiners"
+ Dissabte
+ Festiu
+ "Festiu Vigilia Universitari"
+ "Dv o últim dia lectiu"
+ Comentari "Per Banyoles"
+ Sentit Barcelona-Olot
+ Hores
+ 19:00 Barcelona
+ 20:22 Banyoles
+ 21:00 Olot
+Comboi
+ Dies
+ "Dv o últim dia lectiu"
+ Comentari "Per Banyoles"
+ Sentit Barcelona-Olot
+ Hores
+ 20:30 Barcelona
+ 21:52 Banyoles
+ 22:30 Olot
+Comboi
+ Dies
+ Festiu
+ Comentari "Per Banyoles"
+ Sentit Barcelona-Olot
+ Hores
+ 21:00 Barcelona
+ 22:22 Banyoles
+ 23:00 Olot
+
+# Ara els que van per Amer
+Comboi
+ Dies
+ "Dl-Dv Feiners"
+ Comentari "Per Amer"
+ Sentit Olot-Barcelona
+ Hores
+ 6:00 Olot
+ 6:35 Amer
+ 8:15 Barcelona
+Comboi
+ Dies
+ Dissabte
+ Festiu
+ Comentari "Per Amer"
+ Sentit Olot-Barcelona
+ Hores
+ 7:00 Olot
+ 8:35 Amer
+ 9:15 Barcelona
+Comboi
+ Dies
+ "Dl-Dv Feiners"
+ Dissabte
+ Comentari "Per Amer"
+ Sentit Olot-Barcelona
+ Hores
+ 9:30 Olot
+ 10:05 Amer
+ 11:45 Barcelona
+Comboi
+ Dies
+ "Dl-Dv Feiners"
+ Dissabte
+ Comentari "Per Amer"
+ Sentit Olot-Barcelona
+ Hores
+ 15:30 Olot
+ 16:05 Amer
+ 17:45 Barcelona
+Comboi
+ Dies
+ Festiu
+ Comentari "Per Amer"
+ Sentit Olot-Barcelona
+ Hores
+ 17:30 Olot
+ 18:05 Amer
+ 19:45 Barcelona
+Comboi
+ Dies
+ "Festiu Vigilia Universitari"
+ Comentari "Per Amer"
+ Sentit Olot-Barcelona
+ Hores
+ 20:30 Olot
+ 21:05 Amer
+ 22:45 Barcelona
+
+Comboi
+ Dies
+# Diari
+ "Dl-Dv Feiners"
+ Dissabte
+ Festiu
+ "Festiu Vigilia Universitari"
+ "Dv o últim dia lectiu"
+ Comentari "Per Amer"
+ Sentit Barcelona-Olot
+ Hores
+ 10:00 Barcelona
+ 11:25 Amer
+ 12:00 Olot
+Comboi
+ Dies
+ "Dl-Dv Feiners"
+ Dissabte
+ Comentari "Per Amer"
+ Sentit Barcelona-Olot
+ Hores
+ 15:00 Barcelona
+ 16:25 Amer
+ 17:00 Olot
+Comboi
+ Dies
+ "Dl-Dv Feiners"
+ Dissabte
+ Comentari "Per Amer"
+ Sentit Barcelona-Olot
+ Hores
+ 20:00 Barcelona
+ 21:25 Amer
+ 22:00 Olot
+Comboi
+ Dies
+ Festiu
+ Comentari "Per Amer"
+ Sentit Barcelona-Olot
+ Hores
+ 20:15 Barcelona
+ 21:40 Amer
+ 22:15 Olot
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/horaris/File2Graph.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,51 @@
+package horaris;
+
+import javax.microedition.midlet.MIDlet;
+
+import ogdl.Graph;
+import ogdl.Ogdl2Graph;
+import ogdl.OgdlParser;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.io.InputStreamReader;
+import java.lang.Class;
+
+public class File2Graph
+{
+ public static void load(String filename, Graph root, MIDlet main)
+ {
+ /* Open file */
+ InputStream is = main.getClass().getResourceAsStream(filename);
+ if (is == null)
+ {
+ System.err.println("Resource "+ filename +
+ " not found");
+ return;
+ }
+ InputStreamReader in;
+ try {
+ in = new InputStreamReader(is,
+ "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ System.err.println("Enconding error " + e);
+ return;
+ }
+
+ Ogdl2Graph ev = new Ogdl2Graph(root);
+ try {
+ OgdlParser parser = new OgdlParser(in, ev);
+ parser.parse();
+ } catch (Exception e) {
+ System.err.println("Exception parsing." + e.getMessage());
+ }
+
+
+ try {
+ in.close();
+ } catch (IOException e)
+ {
+ System.err.println("Exception closing is");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/horaris/HoraroTransporta.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,217 @@
+package horaris;
+
+import ogdl.*;
+
+import javax.microedition.lcdui.*;
+import java.util.Vector;
+import java.lang.Exception;
+
+public class HoraroTransporta implements CommandListener, ItemStateListener
+
+{
+ private Graph radiko;
+ private Graph tagoj;
+ private Graph direktoj;
+ private Graph lokoj;
+ private Graph sencoj;
+
+ private Main main;
+
+ private Form myform;
+ private ChoiceGroup ftagoj;
+ private ChoiceGroup fsenco;
+ private ChoiceGroup fkomenco;
+ private ChoiceGroup ffino;
+ private Command cmd_sercxi;
+ private Command cmd_malantauxen;
+
+ private TimeList mytimelist;
+
+
+ public HoraroTransporta(Graph _radiko, Main _main) throws Exception
+ {
+ radiko = _radiko;
+ main = _main;
+
+ System.err.println("Loading dies");
+ tagoj = radiko.getNode("Dies");
+ System.err.println("Loading llocs");
+ lokoj = radiko.getNode("Llocs");
+ System.err.println("Loading sentits");
+ sencoj = radiko.getNode("Sentits");
+
+ try {
+ show();
+ } catch (Exception e)
+ {
+ System.err.println("Cannot create form: " + e);
+ e.printStackTrace();
+ }
+ }
+
+ public void show()
+ {
+ myform = new Form("Cerca");
+
+ /* Items */
+ ftagoj = new ChoiceGroup("Dia", ChoiceGroup.MULTIPLE);
+ addTagoj(ftagoj);
+ myform.append(ftagoj);
+
+ fsenco = new ChoiceGroup("Sentit", ChoiceGroup.EXCLUSIVE);
+ addSencoj(fsenco);
+ myform.append(fsenco);
+
+ fkomenco = new ChoiceGroup("Origen", ChoiceGroup.EXCLUSIVE);
+ addLokoj(fkomenco);
+ myform.append(fkomenco);
+
+ ffino = new ChoiceGroup("Destí", ChoiceGroup.EXCLUSIVE);
+ addLokoj(ffino);
+ myform.append(ffino);
+
+ /* Commands */
+ cmd_sercxi = new Command("Buscar", Command.OK, 0);
+ cmd_malantauxen = new Command("Enrera", Command.BACK, 0);
+ myform.addCommand(cmd_sercxi);
+ myform.addCommand(cmd_malantauxen);
+ myform.setCommandListener(this);
+ myform.setItemStateListener(this);
+ System.err.println("Setting screen");
+ main.display.setCurrent(myform);
+ }
+
+ private void addTagoj(ChoiceGroup g)
+ {
+ for (int i=0; i < tagoj.size(); i++)
+ g.append(tagoj.get(i).getName(), null);
+ }
+
+ private void addSencoj(ChoiceGroup g) {
+
+ System.err.println("Sentits: " + sencoj.size());
+ for (int i=0; i < sencoj.size(); i++)
+ g.append(sencoj.get(i).getName(), null);
+ }
+
+ private void addLokoj(ChoiceGroup g) {
+
+ System.err.println("Llocs: " + lokoj.size());
+ for (int i=0; i < lokoj.size(); i++)
+ g.append(lokoj.get(i).getName(), null);
+ }
+
+ private boolean inVector(Vector v, String s)
+ {
+ for (int i=0; i < v.size(); i++)
+ if(s.equals((String)v.elementAt(i)))
+ return true;
+ return false;
+ }
+
+ private Vector sercxiTempojn(Vector tagoj, String senco,
+ String komenco, String fino)
+ {
+ Vector v = new Vector();
+
+ for (int i=0; i < radiko.size(); i++)
+ {
+ if (! radiko.get(i).getName().equals("Comboi"))
+ continue;
+
+ Graph veturo = radiko.get(i);
+ Graph gtmp;
+ boolean bona;
+
+ String elirtempo = null, alventempo = null;
+
+ /* Dies */
+ System.err.println("Cercant Dies...");
+ gtmp = veturo.getNode("Dies");
+ bona = false;
+ for(int j=0; j < gtmp.size(); j++)
+ {
+ System.err.println("Dia "+gtmp.get(j).getName()+
+ "?");
+ if (inVector(tagoj, gtmp.get(j).getName()) )
+ bona = true;
+ }
+ if (bona != true)
+ continue;
+
+ /* Sentits */
+ System.err.println("Cercant Sentits...");
+ gtmp = veturo.getNode("Sentit");
+ bona = false;
+ for(int j=0; j < gtmp.size(); j++)
+ {
+ if (senco.equals(gtmp.get(j).getName()))
+ bona = true;
+ }
+ if (bona != true)
+ continue;
+
+ /* Komenco kaj Fino */
+ System.err.println("Cercant Inici i Fi...");
+ gtmp = veturo.getNode("Hores");
+ for(int j=0; j < gtmp.size(); j++)
+ {
+ String stacio = gtmp.get(j).get(0).getName();
+
+ if (stacio.equals(komenco))
+ {
+ System.err.println("Inici!");
+ elirtempo = gtmp.get(j).getName();
+ }
+ else if (stacio.equals(fino))
+ {
+ System.err.println("Fi!");
+ alventempo = gtmp.get(j).getName();
+ }
+ }
+ if (elirtempo == null || alventempo == null)
+ continue;
+
+ System.err.println("Trobat!");
+ /* Trovita! */
+ v.addElement(elirtempo + "-" + alventempo);
+ }
+
+ return v;
+ }
+
+ public void commandAction(Command c, Displayable d)
+ {
+
+ if (c == cmd_sercxi)
+ {
+ Vector tagoj = new Vector();
+ for (int i = 0; i < ftagoj.size(); i++)
+ {
+ if (ftagoj.isSelected(i))
+ tagoj.addElement(ftagoj.getString(i));
+ }
+ String senco =
+ fsenco.getString(fsenco.getSelectedIndex());
+ String komenco =
+ fkomenco.getString(fkomenco.getSelectedIndex());
+ String fino =
+ ffino.getString(ffino.getSelectedIndex());
+
+ Vector t = sercxiTempojn(tagoj, senco, komenco, fino);
+
+ if (t.size() > 0)
+ {
+ mytimelist = new TimeList(t,this, main);
+ mytimelist.show();
+ }
+ } else if (c == cmd_malantauxen)
+ {
+ main.show();
+ }
+ }
+
+ public void itemStateChanged(Item item)
+ {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/horaris/Horaroj.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,20 @@
+package horaris;
+
+import ogdl.Graph;
+
+public class Horaroj
+{
+ /* specoj */
+ public final static int TRANSPORTA = 1;
+ public final static int CXEESTA = 2;
+
+ public static int distingi(Graph radiko)
+ {
+ Graph lokoj = radiko.getNode("Llocs");
+
+ if (lokoj == null)
+ return CXEESTA;
+ else
+ return TRANSPORTA;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/horaris/Main.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,56 @@
+package horaris;
+
+import javax.microedition.lcdui.*;
+import javax.microedition.midlet.MIDlet;
+
+import ogdl.*;
+
+public class Main
+ extends MIDlet
+{
+ public Display display;
+ private MainList mymainlist;
+
+ public Main()
+ {
+ display = Display.getDisplay(this);
+ }
+
+ /*
+ public void kreiHoraroekranon(Graph radiko)
+ {
+ int speco = Horaro.distingi(radiko);
+ if (speco == Horaro.TRANSPORTA)
+ {
+ horaro = new HoraroTransporta(radiko, display);
+ } else // CXEESTA
+ {
+ }
+ }
+ */
+
+ public void show()
+ {
+ mymainlist.show();
+ }
+
+ protected void startApp()
+ {
+ mymainlist = new MainList(this);
+ show();
+ }
+
+ protected void destroyApp(boolean c)
+ {
+ }
+
+ protected void pauseApp()
+ {
+ }
+
+ public void quit()
+ {
+ destroyApp(true);
+ notifyDestroyed();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/horaris/MainList.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,106 @@
+package horaris;
+
+import javax.microedition.lcdui.*;
+import java.util.Hashtable;
+
+import ogdl.*;
+
+public class MainList implements CommandListener
+{
+ private Graph list;
+ private List mylist;
+ private Command cmd_elekti;
+ private Command cmd_eliri;
+ private Main main;
+ private Hashtable table;
+
+ public MainList(Main _main)
+ {
+ main = _main;
+ loadList();
+ }
+
+ public void show()
+ {
+ mylist = new List("Horaris", List.EXCLUSIVE);
+
+ /* Show the Titles (they're also in the hashtable) */
+ for (int i=0; i < list.size(); i++)
+ mylist.append(list.get(i).get(0).getName(), null);
+
+ cmd_elekti = new Command("Triar", Command.OK, 0);
+ cmd_eliri = new Command("Sortir", Command.EXIT, 0);
+
+ mylist.addCommand(cmd_elekti);
+ mylist.addCommand(cmd_eliri);
+ mylist.setCommandListener(this);
+ System.err.println("Setting screen");
+ main.display.setCurrent(mylist);
+ }
+
+ private void loadList()
+ {
+ /* Open file */
+ String res = "/data/list.g";
+ list = new Graph("Root");
+ File2Graph.load(res, list, main);
+
+ table = new Hashtable();
+
+ /* Hashtable "Title" - "filename" */
+ for (int i=0; i < list.size(); i++)
+ table.put(list.get(i).get(0).getName(),
+ list.get(i).getName());
+ }
+
+ public void commandAction(Command c, Displayable d)
+ {
+ if (c == cmd_eliri)
+ {
+ System.out.println("Exit");
+ main.quit();
+ } else if (c == cmd_elekti)
+ {
+ String dosiero;
+
+ dosiero = (String) table.get(mylist.getString(mylist.getSelectedIndex()));
+ System.err.println("Loading file " + dosiero);
+
+ loadHoraro(dosiero);
+ }
+ }
+
+ private void loadHoraro(String dosiero)
+ {
+ Graph horaro = new Graph("RootHoraro");;
+ File2Graph.load("/data/"+dosiero, horaro, main);
+
+ int speco = Horaroj.distingi(horaro);
+
+ /* if (speco == Horaroj.CXEESTA)
+ {
+ newCxeesta(horaro);
+ } else */ if (speco == Horaroj.TRANSPORTA);
+ {
+ try {
+ newTransporta(horaro);
+ } catch (Exception e)
+ {
+ System.err.println("No es pot carregar" +
+ " l'horari " + dosiero);
+ }
+ }
+ }
+
+ private void newTransporta(Graph g) throws Exception
+ {
+ HoraroTransporta horaro = new HoraroTransporta(g, main);
+ }
+
+ /*
+ private void newCxeesta(Graph g)
+ {
+ HoraroCxeesta horaro = new HoraroCxeesta(g, main);
+ }
+ */
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/horaris/TimeList.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,46 @@
+package horaris;
+
+import javax.microedition.lcdui.*;
+import java.util.Vector;
+
+import ogdl.*;
+
+public class TimeList implements CommandListener
+{
+ private Graph list;
+ private List mylist;
+ private Command cmd_malantauxen;
+ private Main main;
+ private Vector vtempoj;
+ private HoraroTransporta horaro;
+
+ public TimeList(Vector t, HoraroTransporta _horaro, Main _main)
+ {
+ vtempoj = t;
+ horaro = _horaro;
+ main = _main;
+ }
+
+ public void show()
+ {
+ mylist = new List("Inici-Fi", List.IMPLICIT);
+
+ for (int i=0; i < vtempoj.size(); i++)
+ mylist.append((String) vtempoj.elementAt(i), null);
+
+ cmd_malantauxen = new Command("Enrera", Command.BACK, 0);
+
+ mylist.addCommand(cmd_malantauxen);
+ mylist.setCommandListener(this);
+ main.display.setCurrent(mylist);
+ }
+
+ public void commandAction(Command c, Displayable d)
+ {
+ if (c == cmd_malantauxen)
+ {
+ horaro.show();
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/Characters.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,99 @@
+/* OGDL, Ordered Graph Data Language
+ * (c) R.Veen, 2002-2006.
+ * License: see http://ogdl.org/ (similar to zlib)
+ */
+
+package ogdl;
+
+/** OGDL character classes.
+
+ This class encapsulates all character related productions.
+
+ date: Jul 2002
+ *
+ * todo: check Unicode compliance
+*/
+
+public final class Characters
+{
+ public final static int PRINTABLE = 1;
+ public final static int WORD = 2;
+ public final static int SPACE = 3;
+ public final static int BREAK = 4;
+
+ /** Do not use this function if c can be negative, since negative values
+ * will not be detected correctly as BREAK. Use an integer for c then.
+ */
+
+ public static boolean is (char c, int type)
+ {
+ switch (type) {
+ case PRINTABLE: return isPrintable(c);
+ case WORD: return isWord(c);
+ case SPACE: return isSpace(c);
+ case BREAK: return isBreak(c);
+ default: return false;
+ }
+ }
+
+ public static boolean is (int i, int type)
+ {
+ char c = (char) i;
+
+ switch (type) {
+ case PRINTABLE: return isPrintable(c);
+ case WORD: return isWord(c);
+ case SPACE: return isSpace(c);
+ case BREAK:
+ if (i<0) return true;
+ return isBreak(c);
+ default: return false;
+ }
+ }
+
+ /** Printable character.
+
+ <p>But: Java characters have a maximum value of 65535.</p>
+ */
+
+ public static boolean isPrintable(char c)
+ {
+ if (c >= 0x20 && c <= 0x7e) return true;
+ if (c == 9 || c == 10 || c == 13 || c == 0x85) return true;
+ if (c >= 0xa0 && c <= 0xd7ff) return true;
+ if (c >= 0xe000 && c <= 0xfffd) return true;
+ return false;
+ }
+
+ /** Returns true for all printable characters except spaces and breaks */
+
+ public static boolean isWord(char c)
+ {
+ if (isSpace(c) || isBreak(c) || isSeparator(c) )
+ return false;
+ return isPrintable(c);
+ }
+
+ /** space :: = TAB | SP
+ */
+
+ public static boolean isSpace(char c)
+ {
+ if (c == 9 || c == 0x20) return true;
+ return false;
+ }
+
+ /** break ::= LF | CR */
+
+ public static boolean isBreak(char c)
+ {
+ if (c == 10 || c == 13) return true;
+ return false;
+ }
+
+ public static boolean isSeparator(char c)
+ {
+ if (c == '(' || c == ')' || c == ',' ) return true;
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/Function.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,13 @@
+/* OGDL Microedition.
+ * (C) Rolf Veen, 2006.
+ * License: see http://ogdl.org.
+ */
+
+package ogdl;
+
+public interface Function
+{
+ Object exec (Graph path) throws Exception;
+
+ void close(); /* avoid an extra Closeable intf */
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/Graph.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,349 @@
+/* OGDL Microedition.
+ * (C) Rolf Veen, 2006.
+ * License: see http://ogdl.org.
+ */
+
+package ogdl;
+
+import java.util.Vector;
+
+/*
+ * @author: Rolf Veen (rolf.veen@helide.com> date: 2001 oct 3
+ */
+
+public class Graph
+{
+ protected String name = null, type = null;
+ protected Object value = null;
+ protected Vector v = null;
+
+ protected boolean extensible = false; /*
+ * if this graph can be extended
+ * with classes
+ */
+
+ public Graph() {
+ this.name = "_root";
+ }
+
+ public Graph(String name) {
+ this.name = name;
+ }
+
+ public Graph(String name, Object value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public Graph(String name, Object value, String type) {
+ this.name = name;
+ this.value = value;
+ this.type = type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ /** Return the name of a subnode */
+
+ public String getName(int index)
+ {
+ if (size()>index)
+ return get(index).getName();
+ else
+ return null;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setValue(Object value) {
+ this.value = value;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ /** add a subnode XXX addNodes behavior ?? */
+
+ public Graph add(Graph g) {
+ if (g == null)
+ return null;
+
+ if (v == null) // don't create the Vector before we need it
+ v = new Vector();
+ v.addElement(g);
+
+ return g;
+ }
+
+ public Graph add(String s) {
+ if (s == null || s.length() == 0)
+ return null;
+
+ return add(new Graph(s));
+ }
+
+
+
+
+ /** put a subnode in place of the first subnode with the same name */
+
+ public void setNode(Graph g) {
+ String name = g.getName();
+
+ if (name == null)
+ throw new IllegalArgumentException(
+ "Trying to set and unnamed graph");
+
+ int i;
+
+ for (i = 0; i < size(); i++) {
+ Graph node = (Graph) v.elementAt(i);
+
+ if (name.equals(node.getName()))
+ break;
+ }
+ if (i == size())
+ add(g);
+ else
+ v.setElementAt(g, i);
+ }
+
+ public void setNode(String name, Object value) {
+ setNode(new Graph(name, value));
+ }
+
+ /* set the value giving a path */
+
+
+ /** return the number of subnodes */
+
+ public int size() {
+ if (v == null)
+ return 0;
+ else
+ return v.size();
+ }
+
+
+ /** get the subnode at index */
+
+ public Graph get(int index) {
+ if (index < 0 || v == null || index >= v.size())
+ return null;
+ return (Graph) v.elementAt(index);
+ }
+
+ /** set the subnode at index */
+
+ public Graph set(int index, Graph node) {
+ if (index < 0 || v == null || index >= v.size())
+ return null;
+
+ v.setElementAt(node,index);
+ return node;
+ }
+
+ /** return the first subnode with this name */
+
+ public Graph getNode(String name) {
+ if (name == null)
+ return null;
+
+ for (int i = 0; i < size(); i++) {
+ Graph node = (Graph) v.elementAt(i);
+ if (name.equals(node.name))
+ return node;
+ }
+ return null;
+ }
+
+
+ private static String _chop(String in)
+ {
+ if (in == null) return null;
+
+ int i = in.length() - 1;
+ if (i < 1)
+ return in;
+
+ if (in.charAt(i) == '\n')
+ return in.substring(0, i);
+ return in;
+ }
+
+ private static String _unquote(String s)
+ {
+ if (s == null) return null;
+
+ if (s.length() <2) return s;
+
+ if (s.charAt(0) == '\'' || s.charAt(0) == '"') {
+ return s.substring(1,s.length()-2);
+ }
+ return s;
+ }
+
+ /**
+ * Nodes in graph g are merged into this graph.
+ *
+ * Nodes in this graph with the same name as nodes in g are deleted first.
+ */
+
+ public void merge(Graph g) throws Exception {
+ for (int i = 0; i < g.size(); i++)
+ add(g.get(i)); // XXX check preexistence of nodes
+ }
+
+ /** remove all subnodes with the given name */
+
+ public void removeNode(String name) {
+ int len = size();
+
+ for (int i = 0; i < len; i++) {
+ Graph g = (Graph) v.elementAt(i);
+
+ if (name.equals(g.name)) {
+ v.removeElementAt(i); // esto funciona ??
+ i--;
+ len--;
+ }
+ }
+ }
+
+ /** remove the given subnode */
+
+ public void remove(int index) {
+ if (index < size())
+ v.removeElementAt(index);
+ }
+
+ /** remove all subnodes with the given name and value */
+
+ public void removeNode(String name, String value) {
+ int len = size();
+
+ for (int i = 0; i < len; i++) {
+ Graph g = (Graph) v.elementAt(i);
+
+ if (name.equals(g.name) && value.equals(g.value)) {
+ v.removeElementAt(i); // esto funciona ??
+ i--;
+ len--;
+ }
+ }
+ }
+
+ /** Remove all subnodes */
+
+ public void clear() {
+ if (v != null)
+ v.removeAllElements();
+ }
+
+ /**
+ * return true if this node is a vector of scalars.
+ *
+ * It should have more than one scalar subnode and all subnodes must be
+ * scalar or empty.
+ */
+
+
+ /**
+ * Return an object resulting from instantiating class with the
+ * contructor(Graph cfg).
+ *
+ * The object is instantiated with cfg (the current node), but its context
+ * is the graph 'root'. (mar 2003)
+ */
+
+ public String toString() {
+ String s = Graphs.toString(this);
+ if (s == null)
+ return null;
+ if (s.length() == 0)
+ return null;
+
+ if (s.charAt(0) == '"')
+ return s.substring(1, s.length() - 2);
+ return s;
+ }
+
+ public void addNodes(Graph g) // throws Exception
+ {
+ if (g == null) return;
+ for (int i = 0; i < g.size(); i++)
+ add(g.get(i));
+ }
+
+ /* -------------------------------------------------------
+ * Simple attribute interface
+ *
+ *
+ *
+ */
+
+ /** return the first subnode with this name, as a String */
+
+ public String getAttribute(String name)
+ {
+ if (name == null)
+ return null;
+
+ for (int i = 0; i < size(); i++) {
+ Graph node = (Graph) v.elementAt(i);
+ if (name.equals(node.name)) {
+ if (node.size()>0) {
+ return node.get(0).getName();
+ }
+ else return null;
+ }
+ }
+ return null;
+ }
+
+ /** add a name/value pair */
+
+ public void addAttribute(String name, String value)
+ {
+ if (name == null || value == null)
+ return;
+
+ Graph g = new Graph(name);
+ g.add(value);
+
+ add(g);
+ }
+
+ /** set a name/value pair */
+
+ public void setAttribute(String name, String value)
+ {
+ if (name == null || value == null)
+ return;
+
+ /* remove any nodes with the name 'name' */
+ removeNode(name);
+
+ Graph g = new Graph(name);
+ g.add(value);
+
+ add(g);
+ }
+
+ public Vector getNodes() {
+ return v;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/Graphs.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,170 @@
+/* OGDL Microedition.
+ * (C) Rolf Veen, 2006.
+ * License: see http://ogdl.org.
+ */
+
+package ogdl;
+
+
+/** Graph utilities
+ */
+
+public final class Graphs {
+
+ // ---- OGDL emitter ------------------------
+
+ public static String toString(Graph g) {
+ StringBuffer sb = new StringBuffer();
+
+ addNodes(sb,g,0);
+ return sb.toString();
+ }
+
+ private static void addNodes(StringBuffer sb, Graph g, int level) {
+ for (int i=0; i<g.size(); i++) {
+ Graph node = g.get(i);
+String name = node.getName();
+if (name == null || name.length()==0)
+node.setName("__null");
+ addString(sb,node.getName(),level);
+
+ if (node.getType() != null)
+ addString(sb,"!"+node.getType(),level+1);
+
+ addObject(sb,node.getValue(),level+1);
+ addNodes(sb,node,level+1);
+ }
+ }
+
+ private static void addObject(StringBuffer sb, Object o, int level) {
+ if (o == null) return;
+ addString(sb,o.toString(), level);
+ }
+
+ private static void addString(StringBuffer sb, String s, int level) {
+ if (s == null) return;
+
+ int n = level * 2;
+ while (n-- != 0)
+ sb.append(' ');
+
+ if (s.indexOf('\n') != -1) {
+ addBlock(sb,s,level);
+ return;
+ }
+
+ int q2 = s.indexOf('"');
+ int q1 = s.indexOf('\'');
+
+ if (q1 != -1 && q2 != -1) {
+ addBlock(sb,s,level);
+ return;
+ }
+
+ if ( q1 != -1)
+ sb.append('"').append(s).append('"');
+ else if (q2 != -1)
+ sb.append('\'').append(s).append('\'');
+ else if (s.indexOf(' ') != -1) {
+ if (q1==-1) {
+ sb.append('\'');
+ sb.append(s);
+ sb.append('\'');
+ } else {
+ sb.append('"');
+ sb.append(s);
+ sb.append('"');
+ }
+ } else
+ sb.append(s);
+
+ sb.append('\n');
+ }
+
+ private static void addBlock(StringBuffer sb, String s, int level) {
+ int i;
+ int n = level*2;
+ // for (i=0; i<n; i++)
+ // sb.append(' ');
+
+ sb.append('\"');
+
+
+ for (i=0; i<s.length(); i++) {
+ char c = s.charAt(i);
+ sb.append(c);
+ if (c == '\n') {
+ for (int j=0; j<n; j++)
+ sb.append(' ');
+ }
+ }
+ sb.append("\"\n");
+ }
+
+
+ /** simplifies a graph:
+ *
+ * - 1-node graphs to value of parent
+ *
+ */
+
+ public static void simplify(Graph g) {
+ for (int i=0; i<g.size(); i++) {
+ Graph node = g.get(i);
+
+ if (node.size() == 1 && node.getValue() == null) {
+ Graph subnode = node.get(0);
+ if (subnode.size() == 0) {
+ node.setValue(subnode.getName());
+ subnode = null;
+ node.remove(0);
+ }
+ }
+ simplify(node);
+ }
+ }
+
+ /** clean
+ *
+ * - Delete '(' nodes
+ * - strip quoted strings
+ *
+ */
+
+ public static void clean(Graph g) {
+ for (int i=0; i<g.size(); i++) {
+ Graph node = g.get(i);
+ clean(node);
+ String s = node.getName();
+ char c = s.charAt(0);
+
+ if (s.equals("(") && i>0) {
+ Graph prev = g.get(i-1);
+ prev.addNodes(node);
+ g.remove(i);
+ } else if (c == '\'' || c=='"') {
+ s = s.substring(1,s.length()-1);
+ if (s.length()>0)
+ node.setName(s);
+ }
+
+ }
+ }
+
+
+ /** Return a copy of a node */
+
+ public static Graph copy(Graph g)
+ {
+ return new Graph(g.getName(), g.getValue(), g.getType());
+ }
+
+
+ /** Add nodes from a string array */
+
+ public static void add(Graph g, String[] ss)
+ {
+ for (int i=0; i<ss.length; i++)
+ g.add(ss[i]);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/Ogdl2Graph.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,61 @@
+/* OGDL Microedition.
+ * (C) Rolf Veen, 2006.
+ * License: see http://ogdl.org.
+ */
+
+package ogdl;
+
+import ogdl.parser.ParserHandlerBase;
+
+
+public class Ogdl2Graph extends ParserHandlerBase {
+ Graph[] g;
+ int index;
+ String edge;
+ int level;
+
+ public Ogdl2Graph(Graph g) {
+ this.g = new Graph[50];
+ index = 0;
+ level = 0;
+ edge = null;
+ this.g[0] = g;
+ }
+
+ public void event(int i, int j, String s)
+ {
+ if (i != OgdlBinaryParser.CONTENT)
+ return;
+
+ if (s == null) return;
+
+ edge = s;
+ level = j;
+
+ Graph node = new Graph();
+ node.setName(s);
+ g[level].add(node);
+ level++;
+ g[level] = node;
+ }
+
+ public void event(int i, int j, Object s)
+ {
+ if (i != OgdlBinaryParser.CONTENT && i != OgdlBinaryParser.BINARY)
+ return;
+
+ if (s == null) return;
+
+ if (i == OgdlBinaryParser.BINARY) {
+ g[level].setValue(s);
+ }
+ else {
+ Graph node = new Graph();
+ level = j;
+ node.setName(s.toString());
+ g[level].add(node);
+ level++;
+ g[level] = node;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/OgdlBinary.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,138 @@
+/* OGDL Microedition.
+ * (C) Rolf Veen, 2006.
+ * License: see http://ogdl.org.
+ */
+
+package ogdl;
+
+import java.io.*;
+import ogdl.parser.*;
+
+public class OgdlBinary
+{
+ public static Graph parse(InputStream in) throws Exception
+ {
+ Graph g = new Graph();
+ IParserHandler handler = new Ogdl2Graph(g);
+
+ OgdlBinaryParser p = new OgdlBinaryParser(in,handler);
+ p.parse();
+ return g;
+ }
+
+ /** Binary OGDL emitter
+ *
+ * Buffered by a byte array. If the elements of the
+ * graph are not sent in one write(), there appear some
+ * strange delays between for example the header and
+ * the rest.
+ */
+
+ public static void emit(Graph g, OutputStream out) throws IOException
+ {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ final byte[] h = { 1, 'G', 0 };
+ out_write(bout,h);
+
+ if (! "_root".equals(g.getName()))
+ writeBinary(0,g,bout);
+ else {
+ for (int i=0; i<g.size(); i++) {
+ Graph node = g.get(i);
+ writeBinary(0,node,bout);
+ }
+ }
+
+ out_write(bout,0);
+
+ /* XXX This wastes a whole byte array
+ * since b is a duplicate
+ */
+ byte[] b = bout.toByteArray();
+ out.write(b);
+ }
+
+ private static void writeBinary(int lev, Graph g, OutputStream out) throws IOException
+ {
+ writeTextNode(lev, g.getName(), out);
+
+ Object b = g.getValue();
+
+ if (b!=null && (b instanceof byte[]))
+ writeBinaryNode(lev, (byte[]) b, out );
+
+
+ // do with all nodes
+ Graph node;
+
+ for (int i=0; i<g.size(); i++) {
+ node = g.get(i);
+ writeBinary(lev+1,node,out);
+ }
+ }
+
+ private static void writeTextNode (int level, String s, OutputStream out) throws IOException
+ {
+ multiByteInteger(level+1,out);
+ out_write(out,s.getBytes("UTF-8"));
+ out_write(out,0);
+ }
+
+ private static void writeBinaryNode (int level, byte[] b, OutputStream out) throws IOException
+ {
+ // XXX split
+ multiByteInteger(level+1,out);
+ out_write(out,1);
+ multiByteInteger(b.length,out);
+ out_write(out,b);
+ out_write(out,0);
+ }
+
+ /* Variable length integer encoding
+ *
+ * 0 - 0x0000007F: 0xxxxxxx
+ * 0 - 0x00003FFF: 10xxxxxx xxxxxxxx
+ * 0 - 0x001FFFFF: 110xxxxx xxxxxxxx xxxxxxxx
+ * 0 - 0x0FFFFFFF: 1110xxxx xxxxxxxx xxxxxxxx xxxxxxxx
+ * 0 - 0x7FFFFFFFF: 11110xxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
+ *
+ */
+
+ private static void multiByteInteger(int i, OutputStream out) throws IOException
+ {
+ if (i<0x80) {
+ out_write(out,i);
+ return;
+ }
+ if (i<0x4000) {
+ out_write(out,0x80|(i>>8));
+ out_write(out,i&0xff);
+ return;
+ }
+ if (i<0x200000) {
+ out_write(out,0xc0|(i>>16));
+ out_write(out,(i>>8)&0xff);
+ out_write(out,i&0xff);
+ return;
+ }
+ if (i<0x10000000) {
+ out_write(out,0xe0|(i>>24));
+ out_write(out,(i>>16)&0xff);
+ out_write(out,(i>>8)&0xff);
+ out_write(out,i&0xff);
+ return;
+ }
+ out_write(out,0);
+ }
+
+ static void out_write(OutputStream out,int c) throws IOException
+ {
+ out.write(c);
+ }
+
+ static void out_write(OutputStream out,byte[] b) throws IOException
+ {
+ out.write(b);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/OgdlBinaryParser.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,183 @@
+/* OGDL Microedition.
+ * (C) Rolf Veen, 2006.
+ * License: see http://ogdl.org.
+ */
+
+package ogdl;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import ogdl.parser.IParserHandler;
+import ogdl.util.ByteBuffer;
+
+
+
+/** Parser for the OGDL binary format
+
+ author: Rolf Veen
+ date: Nov 2005.
+
+ XXX Detect client closing connection!!
+*/
+
+public final class OgdlBinaryParser
+{
+ public final static int CONTENT = 1; /* primary events, content related */
+ public final static int FORMAT = 2; /* secondary events, format related */
+ public final static int BINARY = 3; /* secondary events, format related */
+
+ protected InputStream in=null;
+ boolean raw=false;
+
+ int line=1, level=-1, groups[], lineInd[], lineLevel, groupLevel, groupIndex=0;
+
+ private IParserHandler event;
+
+ ByteBuffer bb;
+
+ public OgdlBinaryParser (InputStream in, IParserHandler event) throws Exception
+ {
+ this.in = in;
+ this.event = event;
+ groups = new int[64];
+ lineInd = new int[64];
+
+ bb = new ByteBuffer(0);
+ }
+
+ boolean header() throws IOException
+ {
+ /* Read two bytes (0x0147) */
+ if ( read() != 0x01)
+ return false;
+ if ( read() != 0x47)
+ return false;
+ while ( read() != 0x00 );
+
+ return true;
+ }
+
+ /* Variable length integer encoding
+ *
+ * 0 - 0x0000007F: 0xxxxxxx
+ * 0 - 0x00003FFF: 10xxxxxx xxxxxxxx
+ * 0 - 0x001FFFFF: 110xxxxx xxxxxxxx xxxxxxxx
+ * 0 - 0x0FFFFFFF: 1110xxxx xxxxxxxx xxxxxxxx xxxxxxxx
+ * 0 - 0x7FFFFFFFF: 11110xxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
+ *
+ * This functions reads byte by byte to compose the
+ * full integer.
+ */
+
+ int integer() throws IOException
+ {
+ int b0, b1, b2, b3;
+
+ b0 = read();
+ if (b0 < 0x80) return b0;
+ if (b0 < 0xc0) {
+ b1 = read();
+ return (b0 & 0x3f)<<8 | b1;
+ }
+ if (b0 < 0xe0) {
+ b1 = read();
+ b2 = read();
+ return ((b0 & 0x1f)<<16) | (b1<<8) | b2;
+ }
+ if (b0 < 0xf0) {
+ b1 = read();
+ b2 = read();
+ b3 = read();
+ return ((b0 & 0x0f)<<24) | (b1<<16) | (b2<<8) | b3;
+ }
+
+ // XXX
+ return 0;
+ }
+
+ boolean line() throws IOException
+ {
+ /* read a multibyte integer, indicating the level */
+ int lev = integer()-1;
+ if (lev==-1) return false;
+
+ /* text or binary ? */
+ int c = read();
+
+// System.out.println("OBP: lev "+lev+", c(bin/text) "+c);
+
+ if (c == 1) {
+
+ /* binary node. Composed by an arbitrary
+ * number of chuncks */
+
+ int len;
+
+ bb.reset();
+
+ while ( (len = integer()) > 0 ) {
+// System.out.println("OBP bin length "+len);
+ bb.extend(len);
+ for (int i=0; i<len; i++) {
+ bb.put((byte)read());
+ }
+ }
+// System.out.println("OBP: binary event of length "+bb.length());
+ event.event(BINARY,lev, bb.cloneBuffer());
+ return true;
+ }
+ else if (c>1){
+ /* text node */
+
+ bb.reset();
+ bb.extend(64);
+ bb.put((byte) c);
+
+ while ( (c=read()) != 0)
+ bb.put((byte)c);
+
+try {
+ event.event(CONTENT,lev,new String (bb.getBuffer(),0,bb.length(),"UTF-8"));
+
+} catch (Exception ex) { ex.printStackTrace(); }
+
+ return true;
+ }
+ return false;
+ }
+
+ public void parse() throws Exception
+ {
+ if (!header()) return;
+ while (line());
+ }
+
+
+ /* -----------------------------------------------------
+ Small isolation layer.
+ */
+
+ private boolean unGetFlag = false;
+ private int unChar;
+
+ public void unread(int c)
+ {
+ unGetFlag = true;
+ unChar = c;
+ }
+
+ private int read() throws IOException
+ {
+ if (unGetFlag) {
+ unGetFlag = false;
+ return unChar;
+ }
+
+ unChar = in.read();
+ return unChar;
+ }
+
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/OgdlParser.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,389 @@
+/* OGDL, Ordered Graph Data Language
+ * (c) R.Veen, 2002-2006.
+ * License: see http://ogdl.org/ (similar to zlib)
+ */
+
+package ogdl;
+
+
+import java.io.IOException;
+import java.io.Reader;
+
+import ogdl.parser.IParserHandler;
+
+
+/** Parser for the OGDL text format
+
+ Non recursive parser. Doesn't need a special Reader.
+
+ <ul>
+ <li>All functions return boolean if the item exists, false if not. If false, they don't modify anything.
+ <li>Relevant functions send an event thru the ParserEvent object.
+ <li>Uses a special ParserReader, not a java.io.PushBackReader.
+ <li>Stores locally one leaf/string to process escape sequences. The minimum content element returned
+ is one leaf (block or not).
+ <li>Leaf type is not preserved: simple, quoted or blocks are all returned as
+ </ul>
+
+ date: Nov 2002.
+
+ $Id: OgdlParser.java,v 1.8 2005/06/06 16:10:53 tbryan Exp $
+*/
+
+public final class OgdlParser
+{
+ public final static int CONTENT = 1; /* primary events, content related */
+ public final static int FORMAT = 2; /* secondary events, format related */
+
+ protected Reader r;
+ int line=1, level=-1, groups[], lineInd[], lineLevel, groupLevel, groupIndex=0;
+
+ int savedSpaces = 0;
+ boolean savedNewline = false;
+
+ private IParserHandler event;
+
+ /* leaf buffer, for first level string processing: escape sequences */
+ StringBuffer sb;
+
+ public OgdlParser (Reader r, IParserHandler event) throws Exception
+ {
+ this.r = r;
+ this.event = event;
+ sb = new StringBuffer();
+ groups = new int[64];
+ lineInd = new int[64];
+ }
+
+ /* XXX: here an efficient string reader ... */
+
+ /** space = char_space+
+
+ Returns the number of spaces. Mixing of tabs and spaces is not
+ allowed as indentation, but not checked yet.
+ */
+
+ public int space() throws IOException
+ {
+ int i;
+
+ if ( savedSpaces != 0 ) {
+ i = savedSpaces;
+ savedSpaces = 0;
+ return i;
+ }
+
+ i = 0;
+ while ( Characters.is( read(), Characters.SPACE ) )
+ i++;
+
+ unread();
+ return i;
+ }
+
+ /** newline ::= ( CR LF) | CR | LF */
+
+ public boolean newline() throws IOException
+ {
+ line++;
+
+ if ( savedNewline ) {
+ savedNewline = false;
+ return true;
+ }
+
+ int c = read();
+
+ if ( c == '\r' ) {
+ c = read();
+ if ( c != '\n' )
+ unread();
+ return true;
+ }
+ else if ( c == '\n' )
+ return true;
+
+ line--;
+ unread();
+ return false;
+ }
+
+
+ /** eos ::= end of stream (no more chars) */
+
+ public boolean eos() throws IOException
+ {
+ int c = read();
+ unread();
+
+ return c == -1 || c == '\f' ? true: false;
+ }
+
+ /** word
+ */
+
+ public boolean word() throws IOException
+ {
+ int i = 0, c;
+
+ sb.setLength(0);
+
+ while ( Characters.is( c=read(), Characters.WORD ) ) {
+ sb.append((char) c);
+ i++;
+ }
+
+ unread();
+ return i>0 ? true:false;
+ }
+
+ public boolean comment() throws IOException
+ {
+ int i = 0, c;
+
+ sb.setLength(0);
+
+ if ( (c=read()) == '#' ) {
+ sb.append((char) c);
+ i++;
+ while ( ! Characters.is( c=read(), Characters.BREAK ) ) {
+ sb.append((char) c);
+ i++;
+ }
+ }
+
+ unread();
+ return i>0 ? true:false;
+ }
+
+ /** separator
+ */
+
+ public boolean separator() throws IOException
+ {
+ int i = 0, c;
+
+ sb.setLength(0);
+
+ if ( Characters.isSeparator( (char) (c=read()) ) ) {
+ sb.append((char) c);
+ i++;
+ }
+ else
+ unread();
+
+ return i>0 ? true:false;
+ }
+
+ public boolean quoted() throws IOException
+ {
+ int q = read();
+ int c, cc=0;
+ int skip=0;
+
+ if ( q != '"' && q != '\'' ) {
+ unread();
+ return false;
+ }
+
+ sb.setLength(0);
+
+ while ( true ) {
+ c = read();
+ if ( c == -1 || ( c == q && cc != '\\' ) )
+ break;
+
+ if (skip > 0) {
+ if ( Characters.isSpace((char) c) ) {
+ skip--;
+ cc = c;
+ continue;
+ }
+ else
+ skip = 0;
+ }
+
+ sb.append((char) c);
+ cc = c;
+ if ( c == '\n' )
+ skip = lineInd[level] + 1;
+ }
+ return true;
+ }
+
+ public boolean block() throws IOException
+ {
+ int c = read();
+ int m,i;
+ int ind=-1;
+
+ if ( c != '\\' ) {
+ unread();
+ return false;
+ }
+
+ if ( !newline() )
+ return false; // loosing one char !
+
+ sb.setLength(0);
+
+ while (true) {
+ m = space();
+ if (m <= lineInd[lineLevel]) {
+ if (newline())
+ sb.append('\n');
+ else {
+ savedSpaces = m;
+ break;
+ }
+ }
+ else {
+ if (ind<0) ind = m;
+ for (i=ind; i<m; i++)
+ sb.append(' ');
+ while (true) {
+ c = read();
+ if ( c == -1 || c == '\n' ) {
+ sb.append('\n');
+ break;
+ }
+ sb.append((char)c);
+ }
+ if (c == -1)
+ break;
+ }
+ }
+ return true;
+ }
+
+ public int node() throws IOException
+ {
+ if (block()) {
+ event.event(CONTENT,level, sb.toString());
+ return -1;
+ }
+
+ if (!quoted() && !comment() && !word() && !separator())
+ return 0;
+
+ int len = sb.length();
+ char c = len>0? sb.charAt(0): 0;
+
+ if ( c == '(' ) {
+ groups[groupIndex++] = level;
+ event.event(FORMAT,level, "(");
+ return 1;
+ }
+ else if ( c == ')' ) {
+ groups[--groupIndex] = level;
+ event.event(FORMAT,level, ")");
+ return 1;
+ }
+ else if (c == ',') {
+ // reset level to the first node of this line
+ if (groupIndex==0)
+ level=lineLevel;
+ else
+ level = groups[groupIndex-1];
+ return 1;
+ }
+ else if (c == '#')
+ return 1;
+
+ if (len != 0)
+ event.event(CONTENT, level, sb.toString());
+
+ level++;
+
+ return 1;
+ }
+
+
+ /** line() : space? ( node ( space node )* )? space? newline
+
+ returns:
+ 0 : EOS
+ 1 : more
+ */
+
+ public boolean line() throws Exception
+ {
+ int i = space();
+ if ( newline() ) return true;
+ if ( eos () ) return false;
+
+ if ( level < 0 ) {
+ lineInd[0]=i;
+ lineLevel=0;
+ }
+ else if ( i > lineInd[lineLevel] ) {
+ lineInd[++lineLevel] = i;
+ }
+ else if ( i < lineInd[lineLevel] ) {
+ while (lineLevel != 0) {
+ if ( i >= lineInd[lineLevel] )
+ break;
+ lineLevel--;
+ }
+ }
+
+ level = lineLevel;
+
+ while ( (i=node()) > 0)
+ space();
+
+ if (i > 0) { /* after a block don't eat spaces */
+ space();
+ newline();
+ }
+
+ if (eos())
+ return false;
+ return true;
+ }
+
+ /** parse ::= line* */
+
+ public void parse() throws Exception
+ {
+ try {
+ while ( line() ) ;
+ }
+ catch (SyntaxException e)
+ {
+ event.error(e,e.line);
+ }
+ }
+
+
+
+ /* -----------------------------------------------------
+ Small isolation layer.
+ */
+
+ boolean unGetFlag = false;
+ int unChar;
+
+ public void unread(int c)
+ {
+ unGetFlag = true;
+ unChar = c;
+ }
+
+ private int read() throws IOException
+ {
+ if (unGetFlag) {
+ unGetFlag = false;
+ return unChar;
+ }
+ return unChar = r.read();
+ }
+
+ private void unread()
+ {
+ unGetFlag = true;
+ }
+
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/RFClient.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,53 @@
+/* OGDL Microedition.
+ * (C) Rolf Veen, 2006.
+ * License: see http://ogdl.org.
+ */
+
+package ogdl;
+
+import java.io.*;
+import javax.microedition.io.*;
+import javax.microedition.io.StreamConnection;
+
+public class RFClient implements Function
+{
+ InputStream in = null;
+ OutputStream out = null;
+ StreamConnection conn = null;
+ String url;
+
+ public RFClient(String url) throws Exception
+ {
+ open(url);
+ }
+
+ public void open(String url) throws Exception
+ {
+ conn = (StreamConnection)Connector.open(url);
+ in = conn.openInputStream();
+ out = conn.openOutputStream();
+
+ this.url = url;
+ }
+
+ public void close()
+ {
+ try {
+ if (conn != null)
+ conn.close();
+ conn = null;
+ }
+ catch (Exception ex) {}
+ }
+
+ public Object exec (Graph g) throws Exception
+ {
+ if (conn == null)
+ throw new Exception ("No open connection to host");
+
+ OgdlBinary.emit(g,out);
+ out.flush();
+
+ return OgdlBinary.parse(in);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/SyntaxException.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,26 @@
+/* OGDL, Ordered Graph Data Language
+ * (c) R.Veen, 2002-2006.
+ * License: see http://ogdl.org/ (similar to zlib)
+ */
+
+package ogdl;
+
+public class SyntaxException extends Exception
+{
+ private static final long serialVersionUID = 1L;
+
+ public int line;
+
+ public SyntaxException() {
+ super();
+ }
+
+ public SyntaxException(String s) {
+ super(s);
+ }
+
+ public SyntaxException(String s, int line) {
+ super(s);
+ this.line = line;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/parser/IParserHandler.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,24 @@
+/* OGDL Microedition.
+ * (C) Rolf Veen, 2006.
+ * License: see http://ogdl.org.
+ */
+
+package ogdl.parser;
+
+/** Generic parser event API.
+
+ Fixed structure for fast callbacks.
+
+ author: Rolf Veen
+ date: March 2002
+ */
+
+public interface IParserHandler
+{
+ void event(int i);
+ void event(int i, String s);
+ void event(int i, int j);
+ void event(int i, int j, String s);
+ void event(int i, int j, Object s);
+ void error(Exception e, int line);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/parser/ParserHandlerBase.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,23 @@
+/* OGDL Microedition.
+ * (C) Rolf Veen, 2006.
+ * License: see http://ogdl.org.
+ */
+
+package ogdl.parser;
+
+
+/** Generic parser event API.
+
+ author: Rolf Veen
+ date: Jun 2002
+ */
+
+public class ParserHandlerBase implements IParserHandler
+{
+ public void event(int i){}
+ public void event(int i, int j){}
+ public void event(int i, String s){}
+ public void event(int i, int j, String s){}
+ public void event(int i, int j, Object s){}
+ public void error(Exception e, int line){}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ogdl/util/ByteBuffer.java Fri Jan 12 00:30:50 2007 +0100
@@ -0,0 +1,92 @@
+/* OGDL Microedition.
+ * (C) Rolf Veen, 2006.
+ * License: see http://ogdl.org.
+ */
+
+package ogdl.util;
+
+/** This is not a fast byte buffer because each time
+ * the buffer is extended, it is not resized but recreated.
+ * (is there a way to do this in Java? XXX)
+ *
+ * @author Rolf Veen
+ * * Id *
+ */
+
+public class ByteBuffer
+{
+ byte[] buffer=null;
+ int len=0;
+ int pos=0;
+
+ public ByteBuffer()
+ {
+ buffer = new byte[16];
+ this.len = 16;
+ }
+
+ public ByteBuffer(int len)
+ {
+ buffer = new byte[len];
+ this.len = len;
+ }
+
+ /** add a byte to the buffer */
+
+ public void put(byte b)
+ {
+ if (pos>=len)
+ extend(16);
+ buffer[pos++] = b;
+ }
+
+ /** extend the local buffer by an amount */
+
+ public void extend(int len)
+ {
+ byte[] a = new byte[this.len+len];
+
+ for (int i=0; i<this.len; i++)
+ a[i] = buffer[i];
+
+ buffer = a;
+ this.len+=len;
+ }
+
+ /** reset the internal buffer to zero.
+ * This way it can be reused.
+ */
+
+ public void reset()
+ {
+ buffer = null;
+ len = 0;
+ pos = 0;
+ }
+
+ /** return the number of bytes in the buffer */
+
+ public int length()
+ {
+ return pos;
+ }
+
+ /** return the buffer */
+
+ public byte[] getBuffer()
+ {
+ return buffer;
+ }
+
+ /** return the buffer */
+
+ public byte[] cloneBuffer()
+ {
+ byte[] a = new byte[len];
+
+ for (int i=0; i<len; i++)
+ a[i]=buffer[i];
+
+ return a;
+ }
+}