>> Ganz einfach, bis zum Ende. Dafür konnte ich deine vorhandenen
>> Funktionen verwenden:
>> char[] buf = ParserUtils.scrape(uri, null, ISO_8859_1,
>> null).toString().toCharArray();
>
> Ein bisschen komisch ist, dass Du ein Byte-Array als char[] einliest.
> Diese Methode war eigentlich nur fuers Einlesen von Webseiten (=Text)
> gedacht. Wundert mich, dass es trotzdem funktioniert.
Mich auch. ;) Ursprünglich habe ich auch mit einem Byte-Array
gearbeitet. Da war aber das Problem, dass byte ein Vorzeichen hat und
ich somit ein (D)Word nicht einfach zusammenaddieren konnte (wobei das
sehr einfach zu beheben ist). Und da es nun schon im Prinzip genau die
Methode zum kompletten Einlesen für char gibt, habe ich darauf
verzichtet, sie mit byte nochmal zu bauen.
> Ja, genau diese Feinheiten sehe ich auch als Problem. Ich wollte Dich
> schon ueberreden, im Falle von "unbekannt" immer null (Object) oder 0
> (int/short) zurueckzugeben. Leerstrings, "---" etc. sind i.d.R. keine
> gute Idee.
Da stimme ich dir zu (wobei ich "undefiniert" eher als -1 wählen
würde, um es von Werten abgrenzen zu können, die einfach nicht kleiner
als 0 sein können, siehe getFootwayDuration). Allerdings habe ich das
auch schon weitestgehend umgesetzt. Wo fehlt dir das denn noch?
>
> Es gibt noch eine Reihe weiterer Dinge, die ich anmerken wuerde.
> Vielleicht das wichtigste, dass Du zusaetzlich zu den DTO nochmal alle
> Objecte in diese Parser-Objekte wrappst. Unter Android ist
> Objekt-Instantiierung nochmal viel teurer als bei normalem Java. Daher
> habe ich schon vor, ueber meinen Code nochmal optimierend drueber zu
> gehen, bevor ich alles auf master merge.
Ich habe mal gelernt, dass in Java die Objekt-Instantiierung billiger
ist als man denken würde.
Unter Android kann ich es nicht sagen. Ich glaube eher nicht, dass
sich das in einem bemerkbaren Rahmen bewegt (insbesondere mit JIT). Es
macht halt die Methodennamen etwas kürzer und bringt Struktur in den
Code (und die finde ich durchaus wichtig). Aber gut, darauf könnte ich
verzichten, da ich letztendlich sowieso ziemlich viele der Werte
ermittle. Aber an einem hänge ich doch sehr, und zwar die
umschließende Klasse pro Datei. Du hast ja vorhin das Encoding
eingebaut und musstest den Wert durch alle Funktionen durchschleifen.
Natürlich darf es kein Instanzfeld sein, aber wenn man auf einige
Werte einfach zugreifen kann ist das schon von Vorteil. Denn dann kann
man auch einfacher Teile des Codes in Funktionen auslagern, das fehlt
mir bei dir doch sehr.
Ich könnte mir das so vorstellen, dass es jeweils eine Funktion zum
Erstellen der DTOs für Connection, Part und Stop gibt. Bei komplexeren
Berechnungen vielleicht nochmal Unterfunktionen. Damit wären wir uns
denke ich schon deutlich einiger. ;) Und ich habe mir für mein
Framework auch den Interpreter und die Abläufe dabei angesehen, der
Aufwand für Funktionsrufe ist wirklich ziemlich gering.
> Die Umstellung von Stream auf Byte-Array koennte ich mir vorstellen,
> auch wenn ich schon einen Horror vor dem manuellen Hochzaehlen von
> Pointern habe.
Naja, man muss das ja nicht nach jedem Wert hochzählen. Ich arbeite
öfters mit Pointern auf die "Struktur" und dazu relativen Offsets.
Streams haben halt den Nachteil, dass das Lesen eines Wertes
Nebeneffekte hat. So kann man nicht mal einfach etwas von einer
anderen Stelle lesen, sondern muss danach wieder zurückspringen.
> Wie gesagt, wenn wir durch alle der Punkte durch sind, glaube ich sind
> wir ohnehin konvergiert... (-:
Das kann durchaus sein. Ich kann ja auf der einen Seite mal meinen
Code etwas flacher machen (sprich die Unterklassen raus) und die DTOs
direkt dort erzeugen und auf der anderen Seite deinen Code in
Funktionen in einer einzigen neuen Klassen unterteilen und diese ein
Byte-Array (oder char? der Aufwand ist ähnlich) verwenden lassen.
Damit dürften dann jeweils die zwei größten "Mängel" (die mMn nicht
wirklich falsch sind, sondern einfach unterschiedliche Philosophien
sind) behoben sein und wir können sehen, welche Unterschiede noch
übrig sind. Meinst du, so können wir auf einen gemeinsamen Nenner
kommen?
> Ich glaube, der String ist eigentlich als null zu interpretieren. Denn
> der String-Index von "---" ist immer 0, so dass ich glaube auf die 0
> kommts an und das "---" wurde nur eingefuegt um zu vermeiden dass
> schlecht programmierter Code crashed.
Also dass es ein Zeichen für "nicht vorhanden" ist, ist denke ich
klar. Aber ich hätte die Annahmen "Index 0 => null" nicht gemacht. Wer
auch immer die API benutzt, bekommt nicht die 0 sondern "---" und muss
ggf. darauf reagieren. Daher habe ich das genauso umgesetzt und
vergleiche beim Normalisieren mit "---". Wenn das gefunden wird oder
die Zeichenkette leer ist (nach dem trim()), wird null zurückgegeben.
> Uebrigens habe ich grade mal ein paar andere Verkehrsnetz durchprobiert.
> Zwei bisherige Problemfaelle, der BVG (Berlin) und VBN (Bremen) koennen
> auch h2g-direct=11. Leider ist jedoch der Extension Header nur 0x2c
> lang, wodurch es auf den ersten Blick keine Verbindungs-Attribute gibt.
> Es muss wohl noch einen anderen Weg geben, die ConnectionId ("C0-0") zu
> ermitteln.
>
Es muss nicht. ;) Ich habe bei der Bahn mal die Abfrage mit h2g-direct
ohne Wert gemacht - da steht der String nicht mit drin. Ich habe die
Befürchtung, dass diese ID dort einfach nicht mitgeliefert wird. Wenn
du die nur zur Identitätsfeststellung brauchst, müsste aber auch ein
Hash (z.B. aus Abfahrtsorten und -zeiten der Teilverbindungen)
genügen, oder? Ich hatte schon die Idee, mal eine Abdeckungsanalyse zu
machen, also mal mitzuschreiben, welche Bytes bereits gelesen werden
und welche möglicherweise noch unbekannte Daten enthalten.
Ich habe mittlerweile herausgefunden, dass die Plankennung für den
persönlichen Fahrplan verwendet wird, den man sich herunterladen kann.
Dann sind auch andere Bytes gefüllt. Weiterhin habe ich schon die
Fehlercodes für einige Situationen identifizieren können.
Mehrdeutigkeit gibt es auch, aber ohne Hinweise darauf was mehrdeutig
ist (das Ergebnis bei mehrdeutigem Start/Ziel ist komplett gleich).
Die Bahnapp verwendet übrigens XML für die automatische
Vervollständigung, ich weiß nicht ob das noch mehr Daten liefert als
JSON.
Und noch eine Frage: Gibt es in Öffi eine Sortierung der Verbindungen
(für die Anzeige) oder wird erwartet, dass diese in zeitlich richtiger
Reihenfolge zurückgegeben werden? Wenn man Verbindungen vor/nach
Mitternacht hat, gibt es manchmal Sprünge in der Anzeige.