First commit.
authorviric@llimona
Fri, 12 Jan 2007 00:30:50 +0100
changeset 0 8bc2bfcd1bd8
child 1 f84379205c35
First commit.
Makefile
src/META-INF/MANIFEST.MF
src/data/list.g
src/data/teisa.g
src/horaris/File2Graph.java
src/horaris/HoraroTransporta.java
src/horaris/Horaroj.java
src/horaris/Main.java
src/horaris/MainList.java
src/horaris/TimeList.java
src/ogdl/Characters.java
src/ogdl/Function.java
src/ogdl/Graph.java
src/ogdl/Graphs.java
src/ogdl/Ogdl2Graph.java
src/ogdl/OgdlBinary.java
src/ogdl/OgdlBinaryParser.java
src/ogdl/OgdlParser.java
src/ogdl/RFClient.java
src/ogdl/SyntaxException.java
src/ogdl/parser/IParserHandler.java
src/ogdl/parser/ParserHandlerBase.java
src/ogdl/util/ByteBuffer.java
--- /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;
+    }    
+}