• Herzlich Willkommen!

    Nach der Schließung von inDiablo.de wurden die Inhalte und eure Accounts in dieses Forum konvertiert. Ihr könnt euch hier mit eurem alten Account weiterhin einloggen, müsst euch dafür allerdings über die "Passwort vergessen" Funktion ein neues Passwort setzen lassen.

    Solltet ihr keinen Zugriff mehr auf die mit eurem Account verknüpfte Emailadresse haben, so könnt ihr euch unter Angabe eures Accountnamens, eurer alten Emailadresse sowie eurer gewünschten neuen Emailadresse an einen Administrator wenden.

[Entwicklerblog] Entwickeln von Tools in Java

Stolperhannes

Diablo-Veteran
Registriert
5 April 2004
Beiträge
1.502
Hallo Leute,

ich wende mich mit diesem Entwicklerblog an Leute, die vielleicht nicht nur modden wollen indem sie Tabelleneinträge austauschen, sondern aktiv ein wenig mit der kostenlosen und gut dokumentierten Programmiersprache Java beschäftigen wollen.

Ich selbst habe auch nur im zweistelligen Stundenbereich Erfahrung mit Java, deshalb ist Nichtwissen oder nicht hochoptimaler Code kein Grund zum schämen für mich...


Als erstes : Kostenloses Lehrbuch aus dem Addison Wesley Verlag Link Java 5.0 wiki

Als zweites: Die kostenlose hervorragende IDE Eclipse wiki , download


Ziel des Threads ist die Entwicklung nützlicher Tools anfänglich alleine im Zusammenhang mit TXT-Dateien. Zum Beispiel soll ein TXT-Prozessor geschrieben werden, der Mod-Module im Quelltext verarbeiten kann.

Außerdem ergibt sich als Nebeneffekt eine TXT-Modder-Programmiersprache... Damit lassen sich Beispiele bzw Tutorials! klarer formulieren und als Input für einen Präprozessor verwenden... Es wird automatisch gemoddet...


In den nächsten Posts beschreibe ich die TXT-Modder-Programmiersprache.


Für das eigene Experimentieren habe ich eine nachfolgende Klasse geschrieben:

Sie enthält alles was wichtig ist
- laden
- speichern (normal und als Backup)
- leere Tabelle erzeugen
- Zeilen holen, löschen, clonen, einfügen, leere Zeile erzeugen
- Einträge löschen, ersetzen, holen, suchen


Code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class TxtContainer {
	
	public class LineColumn{
		public int line;
		public int column;
		public LineColumn(int line, int column)
		{
			this.line=line;
			this.column=column;
		};
		public LineColumn()
		{
			line=0;
			column=0;
		};
	}
	
	/**
	 * Beinhaltet alle Einträge der D2TXT-Datei
	 */
	StringBuilder content;
	File FileName;

	
	/**
	 * Die Spalten des Sheets sind mit Tabulatoren voneinander getrennt.
	 */
	final static String  SEPARATOR = "\t";
	final static String  LINETERMINATOR = "\r\n";

	int Columns=0;
	int Lines=0;
	
	
	public TxtContainer(File FileName)
	{
		
		this.FileName=FileName;
		read(FileName);
		makeBackup();
		countLines();
		countColumns();
	}
	
	/**
	 * <code>public void <b>read</b>(String FileName)</code><br><br>
	 * 
	 * Liest die komplette Datei in einen Stringbuilder
	 * @param FileName Dateiname 
	 */	
	public void read(File FileName){
		
		try {
			//--- einlesen 
			//--- Puffer mit der Größe der Datei erzeugen
			char[] ca=new char[(int)FileName.length()];

			//--- Datei öffnen
			BufferedReader f = new BufferedReader(
					new FileReader(FileName));

			//--- Datei komplett in Charpuffer einlesen
			f.read(ca);        			
			
			//--- datei schliesen
			f.close();
			
			//--- Stringbearbeitungsobjekt erzeugen 
			content =new StringBuilder();			
		
			//--- Stringoblekt mit Daten füllen
			content.append(ca);
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}		
	}
	
	public void makeBackup(){		
		String fn = FileName.toString().replace(".txt", ".bak");
		write(fn);						
	}
	
	public void write(){
		write(FileName.toString());
	}
	
	/**
	 * <code>public void <b>write</b>(String FileName)</code><br><br>
	 * 
	 * Schreibt die Tabelle an den vorgegebenen Ort 
	 * @param FileName Dateiname
	 */	
	public void write(String FileName)	    
		{			
			try {
											
				//--- Datei erzeugen
				BufferedWriter f = new BufferedWriter(
						new FileWriter(FileName));
				//--- Gibt den ganzen Inhalt als Komplettstring aus
				f.write(content.substring(0));
				
				//--- Datei schliessen
				f.close();
			} catch (IOException e) {
				e.printStackTrace();
			}				
		}	
	
	/**
	 * <code>private void <b>countColumns</b>()</code><br><br>
	 * 
	 * Zählt die Anzahl der aktuellen Spalten in der Tabelle 
	 */
	private void countColumns()
	{			
		Columns=0;			
		String s=this.getLine(0); 
		int i=0;
		while (true){
			Columns++;
			i=s.indexOf(SEPARATOR, i);
			if(i<0) break;
			i+=SEPARATOR.length();			
		}		
	}
	
	/**
	 * <code>private void <b>countLines</b>()</code><br><br>
	 * 
	 * Zählt die Anzahl der aktuellen Zeilen in der Tabelle
	 */
	private void countLines()
	{		
		Lines=0;								
		String s=content.substring(0);		
		int i=0;
		while (true){
			Lines++;
			i=s.indexOf(LINETERMINATOR, i);
			//--- Nachbedingung: i zeigt auf erstes Zeichen 
			//--- des LINETERMINATORs oder beeinhaltet -1
			//--- wenn kein weiteres Zeilenendezeichen mehr
			//--- gefunden wurde.
			if(i<0) break;
			//--- Auf erstes Zeichen nach Zeilenendezeichen weiterschalten 
			i+=LINETERMINATOR.length();
		}		
	}
	
	/**
	 * <code>public LineColumn <b>getLineColumn</b>(int index)</code><br><br>
	 * Gibt Zeile und Spalte zurück, in die der Index zeigt.
	 * 
	 * @param index	Index in den content
	 * @return  Klasse vom Typ: LineColumn 	
	 */
	public LineColumn getLineColumn(int index){
		LineColumn p=new LineColumn();		
		int l;
		int c;
		//--- Zeilen hochzählen bis zur richtigen Zeile
		for (l=0;(l<Lines)&&(this.getLineEndIndex(l)<index);l++) ;
		p.line=l;

		//--- Spalten hochzählen bis zur richtigen Spalte
		for (c=0;(l<Lines)&&(this.getColumnEndIndex(l, c)<index);c++) ;
		p.column=c;
		return p;
	}
		
	/**
	 * <code>public int <b>getColumnStartIndex</b>(int line, int column)</code><br><br>
	 * 
	 * Gibt den Startindex eines Eintrages innerhalb der Tabelle zurück. 
	 * Der Index zeigt auf erstes Zeichen im Eintrag.
	 * @param line		Zeile
	 * @param column	Spalte 
	 * @return			Startposition des Eintrages
	 */
	public int getColumnStartIndex(int line, int column)
	{		
		//--- Vorbedingung Index zeigt auf erstes Zeichen 
		//--- in Spalte 0 in der Zeile 0
		int index=0;
		for(int l=0;l<line;l++) 
			index=content.indexOf(LINETERMINATOR, index)+LINETERMINATOR.length();
		//--- Nachbedingung Index zeigt auf erstes Zeichen 
		//--- in Spalte 0 in der Zeile line
		for(int c=0;c<column;c++) 
			index=content.indexOf(SEPARATOR, index)+SEPARATOR.length();
		//--- Nachbedingung Index zeigt auf erstes Zeichen 
		//--- in Spalte column in der Zeile line
		
		return index; 
	}
	/**
	 * <code>public int <b>getColumnEndIndex</b>(int line, int column)</code><br><br>
	 * Gibt den Endindex eines Eintrages innerhalb der Tabelle   
	 * ohne Zeilenendezeichen zurück. 
	 * Der Index zeigt auf erstes Trennzeichen nach dem Eintrag.
	 * 
	 * @param line	Zeile
	 * @return		Endposition des Eintrages   
	 */
	public int getColumnEndIndex(int line, int column)
	{			
		int index=this.getColumnStartIndex(line, column);
		//--- Nachbedingung Index zeigt auf erstes Zeichen 
		//--- in Spalte column in der Zeile line
		
		while ((content.charAt(index)!='\t')&&(content.charAt(index)!='\r')) 
			index++;
		//--- Nachbedingung Index zeigt auf erstes Trennzeichen 
		//--- in Spalte column in der Zeile line		
		return index; 
	}
	
	/**
	 * <code>public int <b>getLineStartIndex</b>(int line)</code><br><br>
	 * Gibt den Startindex einer Zeile innerhalb der Tabelle.   
	 * Der Index zeigt auf erstes Zeichen in der Zeile.
	 * @param line 	Zeile
	 * @return 		Startposition der Zeile
	 */
	public int getLineStartIndex(int line){
		return this.getColumnStartIndex(line, 0);
	}
	
	/**
	 * <code>public int <b>getLineEndIndex</b>(int line)</code><br><br>
	 * Gibt den Endindex einer Zeile innerhalb der Tabelle   
	 * inklusive Zeilenendezeichen zurück. 
	 * Der Index zeigt auf erstes Zeichen nach der Zeile.
	 * 
	 * @param line	Zeile
	 * @return		Endposition der Zeile  
	 */
	public int getLineEndIndex(int line){
		return this.getColumnEndIndex(line, Columns-1)+LINETERMINATOR.length();
	}
	
	/**
	 * <code>public String <b>getLine</b>(int line)</code><br><br>
	 * Gibt eine Kopie einer Zeile aus dem Sheet inklusive aller 
	 * Trenn und Zeilenendezeichen zurück
	 * 
	 * @param line 	Zeilennummer 
	 */
	public String getLine(int line){
		return content.substring(this.getLineStartIndex(line), 
								 this.getLineEndIndex(line));
	}
	
	/**
	 * <code>public void <b>deleteLine</b>(int line)</code><br><br>
	 * Löscht eine Zeile aus dem Sheet inklusive aller 
	 * Trenn und Zeilenendezeichen
	 * 
	 * @param line 	Zeilennummer 
	 */
	public void deleteLine(int line){
		content.delete(this.getLineStartIndex(line), 
				       this.getLineEndIndex(line));	
	}
	
	/**
	 * <code>public void <b>insertLine</b>(int line, String Linestr)</code><br><br>
	 * Fügt eine komplette leere Zeile in die Tabelle ein.
	 * Alle nachfolgenden Zeilen werden nach hinten verschoben.
	 *   
	 * @param Linestr 	Eine komplette leere Zeile im Stringformat
	 * @param line 		Zeilennummer der neuen Zeile
	 */
	public void insertLine(int line, String Linestr){
		content.insert(this.getLineStartIndex(line), Linestr);		
	}
	
	/**
	 * <code>public String <b>newLine</b>(int columns)</code><br><br>
	 * Erzeugt einen String, der eine leere Zeile mit Anzahl Spalten repräsentiert. 
	 * Inklusive Trennzeichen und Zeilenendezeichen
	 * 
	 * @param columns 	Spalten
	 * @return  Eine leere Zeile
	 */
	public String newLine(int columns){
		String s="";		
		for (int i=0;i<columns-1;i++) s+=SEPARATOR;
		s+=LINETERMINATOR;
		return s;
	}
	/**
	 * <code>public String <b>newSheet</b>(int line, int columns)</code><br><br>
	 * Erzeugt einen String, der eine leere Tabelle mit Anzahl Zeilen 
	 * und Spalten repräsentiert. 
	 * Inklusive Trennzeichen und Zeilenendezeichen
	 * 
	 * @param line 		Zeilen
	 * @param columns 	Spalten
	 * @return  Eine leere Tabelle
	 */
	public String newSheet(int line, int columns){		
		String s="";		
		StringBuilder sb = new StringBuilder();		
		s=newLine(columns);
		for (int i=0;i<line;i++) sb.append(s);
		return sb.substring(0);
	}
	
	
	/**
	 * <code>public void <b>cloneLine</b>(int line)</code><br><br>
	 * Macht eine Kopie von einer Zeile und fügt sie am Ende der Tabelle an.
	 * @param line Zeilennummer der Zeile, die kopiert werden soll
	 */	
	public void cloneLine(int line){		
		content.append(getLine(line));	
		countLines();
		
	}
			
	/**
	 * <code>public String <b>getEntry</b>(int line, int column)</code><br><br>
	 * Gibt die Kopie eines Eintrages aus der Tabelle 
	 * @param line 		Zeilennummer
	 * @param column 	Spaltennummer
	 * @return Eintrag aus der Tabelle ohne Trennzeichen
	 */
	public String getEntry(int line, int column)
	{	
		//--- Eintrag wird ohne Trennzeichen zurückgegeben
		return content.substring(getColumnStartIndex(line,column),
								 getColumnEndIndex(line,column));
	}	

	/**
	 * <code>public void <b>clearEntry</b>(int line, int column)</code><br><br>
	 * Löscht einen Eintrag in der Tabelle
	 * @param line Zeilennummer
	 * @param column Spaltennummer
	 */	
	public void clearEntry(int line, int column){
		content.delete(getColumnStartIndex(line,column),
					   getColumnEndIndex(line,column));
	}

	/**
	 * <code>public void <b>replaceEntry</b>(int line, int column, String Entry)</code><br><br>
	 * Ersetzt einen Eintrag in der Tabelle durch einen neuen Eintrag
	 * @param line Zeilennummer
	 * @param column Spaltennummer
	 * @param Entry Eintrag
	 */
	public void replaceEntry(int line, int column, String Entry){
		clearEntry(line, column);
		if (Entry!=null)		
			content.insert(getColumnStartIndex(line,column), Entry);
	}
	
	/**
	 * <code>public void <b>searchEntry</b>(String Entry)</code><br><br>
	 * Sucht einen Eintrag in der Tabelle. 
	 * <code><b>indexOf</b>(Entry, index)</code> findet Teilstrings. Gesucht sind jedoch komplette 
	 * Tabelleneinträge und nicht Teilstrings in Tabelleneinträge.  
	 * 
	 * @param Entry Gesuchter Eintrag
	 * @return Index des Eintrages 
	 */
	public int searchEntry(String Entry, int index){

		LineColumn lc=new LineColumn();
				
		int i=index;
		
		while(true){
			//--- Teilstring suchen			
			i =content.indexOf(Entry,i);
			
			//--- Wenn keinen Teilstring (mehr) gefunden, dann Ende
			if (i<0)return i;			
			
			//--- Teilstring gefunden, Zeile und Spalte ermitteln
			lc=this.getLineColumn(i);
			
			//--- Eintrag in Tabelle ist identisch mit Suchstring
			if(this.getEntry(lc.line, lc.column).equals(Entry)) 
				return i;
			
			//--- Tabelleneintrag war nicht Suchstring
			i+=Entry.length();						
		}
		
	}	

}
 
Ich würde mal sagen: Respekt, wenn du das hier durchziehst. ;)

Ist aber eine sehr schöne Idee. Wenn du es nun so machen könntest, dass zu z.B. einen ItemCreator erstellen würdest, der automatisch eine Zeile in der armor.txt oder so erstellt, wo man nur noch die Attribute über ein Interface einpflegen müsste, wäre das eine Einstiegserleichterung für viele Anfänger.

Wenn du Hilfe bei irgendwelchen Algorithmen brauchst, frag ruhig nach. Die Syntax von Java ähnelt sehr C++ und PHP, da können dir hier sicher einige Leute helfen.
 
( Ich wollts ja im eigentlich nit schreiben, hab schon im AllesModder mit mir gerungen, aber ich nehm dir das googlen mal ab )

Die aktuellen IDE's von Delphi sind auch umsonst, aber man hätte sich ja selbst bewegen müssen. Scheint für einige "Bevölkerungsgruppen" ja schon anstrengend zu sein. Hauptsache man kackt auf den Staat und kann auf der anderen Hand nich genug Subventionen in den Rachen geschoben bekommen und erwartet dann frecherweise auch noch, dass der Staat für einen einen neuen Job sucht.

Und selbst nach Jahren von ... geht man dann nich auf Angebote ein, weil Kräfte mit 10 Jahren Pause natürlich sofort Anspruch auf absolute Toppositionen haben ... wobei sie sich nichma zum Nutzen von Google durchringen können.

http://www.turboexplorer.com !
 
In einem anderen Thread hatte ich geschrieben:

Stolperhannes schrieb:
Ich bin ALG2er. Ich bin pleite. Menschenwürdige Teilhabe an der Gesellschaft ist mir nicht möglich. Ich kann mir keine Bücher oder Programme kaufen...


FreePascal unterstützt Windowstauglich BorlandPascal. Ich kann keine entsprechende Literatur kaufen oder kostenlos downloaden. Das Hilfesystem funzt nicht.

Da steig ich auf kostenlos im Internet verfügbare:
- Editor Eclipse
- Programmiersprache Java
- Ein Originalbuch von Guido Krüger:"Handbuch der Java-Programmierung" (Danke an den Autor) zurück

Die Armut ist bei mir schon lange angekommen. (30 offene Stellen in meinem Beruf in der Region - Meine Empfehlung: Werde niemals älter als 40, dann wirft man dich weg.)

Ich denke besser darüber nicht mehr nach, sonst ist das nächste was ich entwickele ein Atomsprengsatz für den deutschen Reichstag. Das ist da wo Gröfaz mal herrschte. Nun ja, seine Enkel verwalten sein Erbe würdig.


Toll, das ich geschrieben habe, dass ich Delphi im Net nicht finde... Toll, finde ich auch das Threadstalking...
 
oO was soll man da sagen?
ich hab noch nicht ganz begriffen worum es hier geht, aber wenn ihr wirklich sowas wie einen Itemcreator oder ähnliches entwickelt, muss ich dazu folgende Punkte anmerken:
- nicht ohne mich ^^. Ich lern das in der Schule.
- arme Modanfänger...die steigen dann durch das Programm noch weniger durch und haben im Endeffekt kaum Ahnung was sich an den Spielresourcen ändert (ich muss da immer an den Vergleich Windoof / Linux denken. Linux ist Arbeit aber du steigst auch wirklich durch was passiert, dagegen ist Windoofbenutzen meist blödsinniges Bildchenklicken und Keineahnunghaben)

naja is ja wayne...ich bin auf jeden Fall dabei wenn sowas startet.

Grüße Sofa
 
*GMW*-Sofa schrieb:
oO was soll man da sagen?
ich hab noch nicht ganz begriffen worum es hier geht, aber wenn ihr wirklich sowas wie einen Itemcreator oder ähnliches entwickelt, muss ich dazu folgende Punkte anmerken:

- nicht ohne mich ^^. Ich lern das in der Schule.

- arme Modanfänger...die steigen dann durch das Programm noch weniger durch und haben im Endeffekt kaum Ahnung was sich an den Spielresourcen ändert (ich muss da immer an den Vergleich Windoof / Linux denken. Linux ist Arbeit aber du steigst auch wirklich durch was passiert, dagegen ist Windoofbenutzen meist blödsinniges Bildchenklicken und Keineahnunghaben)

naja is ja wayne...ich bin auf jeden Fall dabei wenn sowas startet.

Grüße Sofa


Wie du siehst geht es um eine "Mod-Sprache" (Mitwirkung bei der Konstruktion der Sprache und allen anderen Teilen des Projektes gerne willkommen), die die manuelle Tätigkeit des "Tabellenmoddens" wie eine Batchdatei erledigt. Man kann die offenen Javamodule in eigene Projekte einbinden.

Die Mitmacher können außerdem nebenbei ein bischen Java lernen. - Ich kann es auch nicht perfekt. Eine nette Programmiersprache, die für mich ein bischen meine sehr alten Turbo-Pascal-5.5-Gefühle weckt.

Der Vorteil bei dieser Vorgehensweise: Tutorials können einmal "programmiert" werden und die Beispiele funktionieren dann ohne fehleranfälliges eintippen. Trotzdem muss man immer noch wissen was man tut.

PS Ich bin deiner Meinung: Bildchenklicken ist doof!


----------------------------------------------------------------------

Vorläufige grobe (nicht vollständige oder richtige) Syntaxbeschreibung der "Mod-Programiersprache". Also bitte nicht zu genau hinschauen - Ich mußte das aus dem Gedächtnis hinschludern.

Fernziel soll Beispielsweise auch das Bearbeiten von *.tbl Dateien sein. (Mal nachschauen ob ich ein TBL-Dateiformatbeschreibung finde - Zur Not muß ich es selber analysieren). Bei Phroozen und anderen war im ersten flüchtigen Vorbeischauen nichts davon zu sehen.

Weiterhin wird es mit dieser Mod-Sprache möglich Daten wie aus einer Datenbank abzufragen und in eigene Sheets zu bringen. Eigentlich nett für Statistiker

Es wird noch um weitere Konstrukte erweitert: ich dachte an foreach(), if(), searchFor(Spalte, Eintrag) bzw. searchFor(Zeile, Eintrag) zum indizieren. Zu umfangreich sollte es aber nicht werden.


Mod-Programm besteht aus
- Beliebig vielen
Importdeklaration; (Andere Module)
Dateideklaration; (Existierende oder neu zu erzeugende Dateien)
Zeilendeklaration; (Namenskürzel für Zeilennummern)
Spaltendeklaration; (Namenskürzel für Spaltennummern, Spaltenüberschriften oder Buchstaben)
Anweisungsblock; (Die Aktionen)

Kommentar besteht aus
- // Einzeilenkommentar
- /* Mehrzeilenkommentar */

Dateideklaration besteht aus
- (nichts)
- file Dateityp Dateibezeichner=Dateinamen Dateienliste

Dateienliste besteht aus
- ;Dateityp Dateibezeichner=Dateinamen

Dateityp besteht aus
- txt

Dateibezeichner besteht aus
- Variablennamen

Dateinamen besteht aus
-"PfadDateinamen"

Anweisungsblock besteht aus
- begin Anweisungsliste end

Anweisungsliste besteht aus
- Anweisung; Anweisungsliste
- Anweisung;

Anweisung besteht aus
- (nichts)
- Zuweisung
- Befehl
- Zeilenmarke

Zeilenmarke besteht aus
- @Variablennamen;

Variablennamen besteht aus
- einem Buchstaben gefolgt aus beliebig vielen Buchstaben und Ziffern

Befehl besteht aus
- newLines(zahl)
- cloneLine(zeile)
- deleteLine(zeile)
- loadSheet(Dateibezeichner)
- saveSheet(Dateibezeichner)


Zuweisung besteht aus
- Tabellenaddresse=Zuweisungsausdruck;

Zuweisungsausdruck besteht aus
- "Stringkonstante"
- 'Stingkonstante'
- Tabellenaddresse

Tabellenaddresse besteht aus
- Datei[Zeilenausdruck][Spaltenausdruck]

Zeilenausdruck besteht aus
- LASTLINE Ausdruckrest
- Zeilennamen Ausdruckrest
- Zahl Ausdruckrest

Spaltenausdruck besteht aus
- Spaltennamen Ausdruckrest
- Zahl Ausdruckrest

Ausdruckrest
- (nichts)
- +Zahl
- -Zahl

Zahl besteht aus Ziffern

Stringkonstante besteht aus
- beliebigen Zeichen
(' " '= Wenn ein String doppelte Anführungszeichen verwendet, dann muß er mit einfachen Anführungszeichen eingeschlossen werden)
 
srry hab den ersten post entweder net gesehen oder angezeigt bekommen ^^ ich mach mich gleich mal ans lesen...

grüße Sofa
 
ok ich hab mir mal den code ein wenig durchgelesen...
und habe festgestellt dass ich nur ein paar wenige befehle noch von c kenne, aber wie gesagt es kann sich nur noch um wochen handeln und ich bin auf dem gebiet java ein wandelndes schulbuch ^^

Edit:

Was mir so als Idee für ein größeres Projekt gekommen ist im Thema Itemeditor...und zwar folgendes:

Man hat eine schöne Benutzeroberfläche, die wie ein Bestellformular aufgebaut ist. Da kann man dann eintragen:

Auswahl des Items:
*Waffe
*Rüstung
*bla
Qualität:
*Rare
*Uniqe
*bla
-Verteidigung: xxx (Textfeld zum Zahl eintragen)
...
und alle weiteren wichtigen Punkte zu dem Item.

Dann sollte man natürlich das Bild hinzufügen können (das dann gleich an richtigem Ort plaziert wird(die ganze Geschichte könnte man dann für Dropfiles dann auch noch machen!))

und wenn möglich den Code eingeben können der dann automatisch in die *.tbl geschrieben wird.(Also: -Itemcode -Text der dem Code zugefügt wird -Farbe des Textes -Sonderzeichen sollen automatisch in Formatierungszeichen umgewandelt werden)

Wie gesagt die Idee ist dann Highendausführung ^^. Man kann ja mal klein anfangen. Inwiefern funktioniert eigtl dein Code schon den du oben gepostet hast?

grüße
 
Ich schreibe gerade den Parser. Ich mußte mir erst einen Knoten ins Hirn machen, weil noch nie einen habe schreiben müßen. Außerdem mußte ich auf eine ältere Java-Version per Download mit Quelltexten zurückgreifen, weil ich zuerst nicht herausbekam wie ich an die Quotes von gequoteten Strings beim StreamTokenizer komme.

Aber nach den ersten paar Funktionen läuft es jetzt wie von selbst. Heute Nacht oder morgen abend kann ich den Quelltext hier reinstellen.


Ein größeres Projekt ist ohne Probleme möglich. Basis sind möglichst brauchbare und effektive Klassen.

*GMW*-Sofa schrieb:
Inwiefern funktioniert eigtl dein Code schon den du oben gepostet hast?

grüße

Ich habe countLines und countColumns umprogrammiert ohne den Code zu testen. Ansonsten sind alle Funktionen getestet. (Hoppla newSheet() glaub ich auch nicht...) Einmal in einem Suchprogramm über alle Dateien, wo bestimmte eingegebene Begriffe gesucht werden konnten und einmal über den ForenFileGuide Formatierer. (Spaltennamen und Dateinamen automatisiert eingefärbt - war nicht ganz so toll programmiert)

Ach ja - Fehler abfangen. Wenn ich programmiere, dann fange ich normalerweise keine Fehler ab, sondern verwende Funktionen sorgfältig. Damit läßt sich ein monströser Quellcodeoverhead vermeiden.

Sollte ein Fremder Einfluß auf das Programm haben, dann fange ich Fehler oberhalb der Funktionen ab. Man kann schneller und konzentrierter auf das Wessentliche programmieren.

Kleiner Zwischenstand:
Das kann der Parser aktuell (Ja, ja weniger Fernsehen gucken...)

Code:
Import
  AnotherModfile2 = "F:\\Diablo II\\Modfiles\\Klabauterset.mod"; 

File
  TXT cubemain = "F:\\Diablo II\\data\\global\\excel\\cubemain.txt"; 


Line
  Weaponrepair = 139; //--- Die Eintragsnummer, es wird ab 1 gezählt
 
Column
  ene1 = "enabled"; //--- Spaltennamen und
  ene2 = b; //--- Spaltenbuchstabe und
  ene3 = 2; //--- Spaltenzahl zeigen alle auf die gleiche Zeile
    
Action
  //--- lädt die Datei
  cubemain.loadFile; 

  //--- Kopiert Zeile Weaponrepair 
  //--- + 2 Folgezeile ans Ende der Tabelle   
  cubemain.cloneLines(Weaponrepair,3);   
                                         
  //--- hängt 10 leere Zeilen an die Tabelle
  cubemain.appendLines(10);	
  
  //--- löscht die Zeile
  cubemain.deleteLines(Weaponrepair,1);   
  
  //--- speichert die Datei                                       
  cubemain.saveFile;

Nein, er kann noch nichts, außer ein paar Zeilenarten erkennen... Ist noch überschüssiger Müll vorhanden z.B. in match();

Code:
package dispatcher.prozessoren;

import java.io.*;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class ModProzessor {

	private  StreamTokenizer st;
	private final static int TT_NUMBER=256;
	private final static int TT_ID=257;
	private final static int TT_DONE=258;
	private final static int TT_FILE=259;
	private final static int TT_FILETYPE=260;
	private final static int TT_STRING=261;
	private final static int TT_IMPORT=262;
	private final static int TT_LINE=263;
	private final static int TT_COLUMN=264;
	private final static int TT_ACTION=265;
	private static final int TT_LOADFILE = 266;
	private static final int TT_SAVEFILE = 267;
	private static final int TT_CLONELINES = 268;	
	private static final int TT_APPENDLINES = 270;
	private static final int TT_DELETELINES = 271;
	
	private File Filename;
	public ModProzessor(File Filename){
		this.Filename=Filename;
	}
	private static String[] keywords ={
		"Import","File","Line","Column","Action","Lastline","TXT",
		"appendLines","cloneLines","deleteLines","loadSheet","saveSheet"
	};
	
	public void run(){
		try {
			
			//char[] ca=new char[(int) Filename.length()];
			BufferedReader f= new BufferedReader( new FileReader(Filename));
			//f.read(ca);
			//String content=ca.
			
			Properties p=new Properties();
			
			
			st= new StreamTokenizer(f);
			
			st.slashSlashComments(true);
			st.slashStarComments(true);
			st.ordinaryChar('.');

			parse();
			
				
			 
			f.close();
	
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	private void match(int token) throws IOException{
		
		
		if(token==TT_FILETYPE)System.out.print("Filetype erwartet, ");
		else if(token==TT_NUMBER)System.out.print("Zahl erwartet, ");
		else if(token==TT_STRING) System.out.print("String erwartet, ");
		else if(token==TT_FILE) System.out.print("File erwartet, ");
		else if(token==TT_LINE) System.out.print("Line erwartet, ");
		else if(token==TT_COLUMN) System.out.print("Column erwartet, ");
		else if(token==TT_ACTION) System.out.print("Action erwartet, ");
		else if(token==TT_LOADFILE) System.out.print("loadFile erwartet, ");
		else if(token==TT_SAVEFILE) System.out.print("saveFile erwartet, ");
		else if(token==TT_APPENDLINES) System.out.print("appendLines erwartet, ");
		else if(token==TT_DELETELINES) System.out.print("deleteLines erwartet, ");
		else if(token==TT_CLONELINES) System.out.print("cloneLines erwartet, ");
		else if(token==TT_ID)System.out.print("ID erwartet, ");
		else if(token==TT_DONE)System.out.print("EOF erwartet, ");
		else if(token==';')System.out.print(" ';' erwartet, ");
		else if(token=='=')System.out.print(" '=' erwartet, ");
		else if(token=='.')System.out.print(" '.' erwartet, ");
		else if(token=='(')System.out.print(" '(' erwartet, ");
		else if(token==')')System.out.print(" ')' erwartet, ");
		else if(token==',')System.out.print(" ',' erwartet, ");
		
		if(isString()) System.out.println("String gefunden");
		else if(isNumber()) System.out.println("Zahl gefunden:"+ st.nval);
		else if(isFile()) System.out.println("FILE gefunden");
		else if(isFiletype()) System.out.println("Filetyp gefunden");
		else if(isLine()) System.out.println("Line gefunden");
		else if(isColumn()) System.out.println("Column gefunden");
		else if(isAction()) System.out.println("Action gefunden");
		else if(isLoadFile()) System.out.println("loadFile gefunden");
		else if(isSaveFile()) System.out.println("saveFile gefunden");
		else if(isAppendLines()) System.out.println("appendLines gefunden");
		else if(isDeleteLines()) System.out.println("deleteLines gefunden");
		else if(isCloneLines()) System.out.println("cloneLines gefunden");
		else if(isID())System.out.println("ID gefunden:" + st.sval);
		else if(st.ttype==StreamTokenizer.TT_EOF)System.out.println("EOF gefunden");
		else if(st.ttype==';')System.out.println("';' gefunden" );
		else if(st.ttype=='=')System.out.println("'=' gefunden" );
		else if(st.ttype=='.')System.out.println("'.' gefunden" );
		else if(st.ttype=='(')System.out.println("'(' gefunden" );
		else if(st.ttype==')')System.out.println("')' gefunden" );
		else if(st.ttype==',')System.out.println("',' gefunden" );
		
		
		if ((token==st.ttype)) st.nextToken();		
		else if(token==TT_ID && isID())st.nextToken();
		else if(token==TT_NUMBER && isNumber())st.nextToken();
		else if(token==TT_STRING && isString())st.nextToken();
		else if(token==TT_FILE && isFile())st.nextToken();
		else if(token==TT_LINE && isLine())st.nextToken();
		else if(token==TT_COLUMN && isColumn())st.nextToken();
		else if(token==TT_ACTION && isAction())st.nextToken();
		else if(token==TT_LOADFILE && isLoadFile())st.nextToken();
		else if(token==TT_SAVEFILE && isSaveFile())st.nextToken();
		else if(token==TT_APPENDLINES && isAppendLines())st.nextToken();
		else if(token==TT_DELETELINES && isDeleteLines())st.nextToken();
		else if(token==TT_CLONELINES && isCloneLines())st.nextToken();
		else if (token==TT_FILETYPE && isFiletype())st.nextToken();
		else if (token==TT_IMPORT && isImport())st.nextToken();
		else if (token==TT_DONE && StreamTokenizer.TT_EOF==st.ttype);//-- nichts tun
		else {System.out.println("Fehler:"+st.toString());st.nextToken();}		
	};
	
	
	private void parse() throws IOException{
		st.nextToken();
		ModProgram();match(TT_DONE);	
		System.out.println("Job done");
	}
	
	private void ModProgram() throws IOException{
		
		while(true){
	
			if(isImport())importdeklaration(); 
			else if(isFile()) Filedeklaration();
			else if(isLine()) Zeilendeklaration();
			else if(isColumn()) Spaltendeklaration();
			else if(isAction()) Anweisungen();
			
			if(st.ttype==StreamTokenizer.TT_EOF)break;		
						
		}
	}

	
	private void Anweisungen() throws IOException {
		match(TT_ACTION);
		while(true){
			if (isID()){			
				match(TT_ID);match('.');SheetAnweisung();match(';');
			}
			else break;
		}
	}
	private void SheetAnweisung() throws IOException 
	{
		if(isLoadFile()) match(TT_LOADFILE);
		else if(isSaveFile()) match(TT_SAVEFILE);
		else if(isCloneLines()){
			match(TT_CLONELINES); match('('); faktor(); match(','); match(TT_NUMBER); match(')');
		}
		else if(isDeleteLines()){
			match(TT_DELETELINES); match('('); faktor(); match(','); match(TT_NUMBER); match(')');
		}
		else if(isAppendLines()){
			match(TT_APPENDLINES); match('('); match(TT_NUMBER); match(')');
		}
	}
	
	private void faktor() throws IOException 
	{		 
		if (isNumber()){
			match(TT_NUMBER);
		}else if (isID()){
			match(TT_ID);
		}		
	}
	private void importdeklaration() throws IOException 
	{
		match(TT_IMPORT);
		while(true){
			if (isID()){			
				match(TT_ID); match('='); match(TT_STRING); match(';');
			}
			else break;
		}
	}
	private void Filedeklaration() throws IOException 
	{		
		match(TT_FILE);
		while(true){
			if (isFiletype()){			
				match(TT_FILETYPE); match(TT_ID); match('='); match(TT_STRING); match(';');
			}
			else break;
		}
	}
	private void Zeilendeklaration() throws IOException 
	{
		match(TT_LINE);
		while(true){
			if (isID()){			
				match(TT_ID); match('='); match(TT_NUMBER); match(';');
			}
			else break;
		}
	}
	
	private void Spaltendeklaration() throws IOException {
		match(TT_COLUMN);
		while(true){
			if (isID()){			
				match(TT_ID); match('=');Spaltenausdruck(); match(';');
			}
			else break;
		}
	}
	private void Spaltenausdruck() throws IOException {
		if (isString()){
			match(TT_STRING);
		}else if (isNumber()){
			match(TT_NUMBER);
		}else if (isID()){
			match(TT_ID);
		}				
	}

	private boolean lookupKeywords() {
		for(int i=0;i<keywords.length;i++)
			if(st.sval.equalsIgnoreCase(keywords[i])) return true;
		return false;
	}
	private boolean isID() {
		if ((st.ttype==StreamTokenizer.TT_WORD)&&!lookupKeywords()) 
			return true;			
		else return false;
	}
    private boolean isNumber() {
    	if ((st.ttype==StreamTokenizer.TT_NUMBER)) 
			return true;
		return false;
	}
	private boolean isString() {
		if ((st.ttype=='\"')||(st.ttype=='\'')) 
			return true;			
		else return false;
	}
	private boolean isImport() {
		if ((st.ttype==StreamTokenizer.TT_WORD)&& st.sval.equals("Import")) 
			return true;			
		else return false;
	}
	
	private boolean isFiletype() {
		if ((st.ttype==StreamTokenizer.TT_WORD)&& st.sval.equals("TXT")) 
			return true;			
		else return false;
	}
	private boolean isFile() {
		if ((st.ttype==StreamTokenizer.TT_WORD)&& st.sval.equals("File")) 
			return true;			
		else return false;
	}
	private boolean isLine() {
		if ((st.ttype==StreamTokenizer.TT_WORD)&& st.sval.equals("Line")) 
			return true;			
		else return false;
	}
	private boolean isColumn() {
		if ((st.ttype==StreamTokenizer.TT_WORD)&& st.sval.equals("Column")) 
			return true;			
		else return false;
	}
	private boolean isAction() {
		if ((st.ttype==StreamTokenizer.TT_WORD)&& st.sval.equals("Action")) 
			return true;			
		else return false;
	}
	private boolean isLoadFile() {
		if ((st.ttype==StreamTokenizer.TT_WORD)&& st.sval.equals("loadFile")) 
			return true;			
		else return false;
	}
	private boolean isSaveFile() {
		if ((st.ttype==StreamTokenizer.TT_WORD)&& st.sval.equals("saveFile")) 
			return true;			
		else return false;
	}
	private boolean isDeleteLines() {
		if ((st.ttype==StreamTokenizer.TT_WORD)&& st.sval.equals("deleteLines")) 
			return true;			
		else return false;
	}
	private boolean isCloneLines() {
		if ((st.ttype==StreamTokenizer.TT_WORD)&& st.sval.equals("cloneLines")) 
			return true;			
		else return false;
	}
	private boolean isAppendLines() {
		if ((st.ttype==StreamTokenizer.TT_WORD)&& st.sval.equals("appendLines")) 
			return true;			
		else return false;
	}
}

Die Testausgabe des Programmes:

Code:
ID erwartet, ID gefunden:AnotherModfile2
 '=' erwartet, '=' gefunden
String erwartet, String gefunden
 ';' erwartet, ';' gefunden
File erwartet, FILE gefunden
Filetype erwartet, Filetyp gefunden
ID erwartet, ID gefunden:cubemain
 '=' erwartet, '=' gefunden
String erwartet, String gefunden
 ';' erwartet, ';' gefunden
Line erwartet, Line gefunden
ID erwartet, ID gefunden:Weaponrepair
 '=' erwartet, '=' gefunden
Zahl erwartet, Zahl gefunden:139.0
 ';' erwartet, ';' gefunden
Column erwartet, Column gefunden
ID erwartet, ID gefunden:ene1
 '=' erwartet, '=' gefunden
String erwartet, String gefunden
 ';' erwartet, ';' gefunden
ID erwartet, ID gefunden:ene2
 '=' erwartet, '=' gefunden
ID erwartet, ID gefunden:b
 ';' erwartet, ';' gefunden
ID erwartet, ID gefunden:ene3
 '=' erwartet, '=' gefunden
Zahl erwartet, Zahl gefunden:2.0
 ';' erwartet, ';' gefunden
Action erwartet, Action gefunden
ID erwartet, ID gefunden:cubemain
 '.' erwartet, '.' gefunden
loadFile erwartet, loadFile gefunden
 ';' erwartet, ';' gefunden
ID erwartet, ID gefunden:cubemain
 '.' erwartet, '.' gefunden
cloneLines erwartet, cloneLines gefunden
 '(' erwartet, '(' gefunden
ID erwartet, ID gefunden:Weaponrepair
 ',' erwartet, ',' gefunden
Zahl erwartet, Zahl gefunden:3.0
 ')' erwartet, ')' gefunden
 ';' erwartet, ';' gefunden
ID erwartet, ID gefunden:cubemain
 '.' erwartet, '.' gefunden
appendLines erwartet, appendLines gefunden
 '(' erwartet, '(' gefunden
Zahl erwartet, Zahl gefunden:10.0
 ')' erwartet, ')' gefunden
 ';' erwartet, ';' gefunden
ID erwartet, ID gefunden:cubemain
 '.' erwartet, '.' gefunden
deleteLines erwartet, deleteLines gefunden
 '(' erwartet, '(' gefunden
ID erwartet, ID gefunden:Weaponrepair
 ',' erwartet, ',' gefunden
Zahl erwartet, Zahl gefunden:1.0
 ')' erwartet, ')' gefunden
 ';' erwartet, ';' gefunden
ID erwartet, ID gefunden:cubemain
 '.' erwartet, '.' gefunden
saveFile erwartet, saveFile gefunden
 ';' erwartet, ';' gefunden
EOF erwartet, EOF gefunden
Job done
 
Ich habe die aktuelle Entwicklung oben erneut im Post eingeschrieben.

Nachdem mir die Werkzeuge des Parserbaus einigermaßen geschmeidig im Kopf handhabbar sind, bemerke ich ein anderes Problem: Die Modsprache ist nicht durchdacht genug. Mir fallen ständig neue Konstrukte ein.

Nachdem ich also das "wie mach ich das in dieser neuen Programmiersprache?" geklärt habe, muß ich mich mehr auf das "Was ist diese Modsprache eigentlich? Wie soll sie aufgebaut sein?"

Ich sehe grundsätzlich zwei Wege: Der künstliche und der organische...

Künstlich:
Die Sprache wird von mir logisch herunterdefiniert. Vollkommen ohne Erfahrung was in so einer Programmiersprache wichtig und richtig ist. Ich tue alles hinein von dem ich glaube, dass es gut sei. Problem: Je komplexer so eine Sprache und je mehr an den praktischen Erfordernissen vorbei, desto größer die Umstellungen und desto weniger wahrscheinlich eine Abwärtskompatibilität.

Dauer der Entwicklung bis ein Testmuster zur Verfügung steht ist lange.

Organisch:
Ich definiere ein absolutes Minimum an Anweisungen. Sowenig wie nur geht. Das wäre also:
- Datei laden (geschieht per Deklaration)
- Letzte Zeile zufügen
- Letzte Zeile löschen
- Zellen Werte zuweisen
- Datei speichern (geschieht per Ende der ModProgrammdatei)
Vorteil: man bekommt ein schnell funtionierendes Testmuster. Die Sprache kann wachsen.

Sinnvollerweise werde ich nicht ganz so minimalistisch handeln. Ich ergänze das Konzept um:
- Eine Zeile clonen
Das dürfte gerade in Dateien mit mehr als 20 vollbelegten Spalten sinnvoll sein.

Ich habe mich für organische Entwicklung entschieden. Es gibt den Vorteil, dass man nicht zu schnell in eine Sprachkonstruktliche Sackgasse läuft. Nun ja, mit Zeit kann die Sprache sinnvoll wachsen.
 
Ja, der Parser läuft seit ein paar Tagen. Keine Probleme in der Umsetzung.

Aktuell arbeite ich an einem TBL-Container. Die Beschreibung des Dateiformats läßt sich aus dem Quelltext des AFJ-TBL-Editors ableiten. (Man sollte wirklich auch mal auf die "News"- Seite von Phrozen gehen... Ich such im Internet und ganz vorne steht es als News... :irre: )

Na, ja: Eines der wichtigsten Dinge funktioniert: Der Checksummengenerator...

Wie es aussieht kann man dann per Mod-Sprache automatisch TXT und TBL bearbeiten... Gefällt mir.
Code:
/**
	 * Quelle: AFJ-TBL-Editor Sourcecode
	 * Der Prüfsummentest
	 * 
	 * @param calc Der Stringabschnitt
	 * @param size Länge des Stringabschnittes inkl. 
	 * @return Der Prüfwert
	 */
	public int CRC(StringBuilder calc, long size)
	{
		int[]   CRCTable = { 
	    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 
	    0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 
	    0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 
	    0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 
	    0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 
	    0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 
	    0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 
	    0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 
	    0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, 
	    0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 
	    0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 
	    0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 
	    0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, 
	    0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 
	    0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 
	    0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0}; 

		
		
		int charvalue, temp, value = 0xFFFF;
        
		//--- Für die Gesamtgröße tue...
		for(long i = 0; i<size;i++)
		{			
			//--- Der eigentliche Test			
			charvalue = (byte)calc.charAt((int)i);			
			charvalue ^= (value & 0xFFFF) >> 8;
			temp = (value & 0xFF) << 8;
			value = CRCTable[charvalue]; 
			value ^= temp;
		}

		return value;
	}
 
Mit Bytes hat es Java nicht so dolle. Zweibyte-Zeichensätze und verschiedene Codes machen korrekte Konvertierungen zwischen Chararrays und Bytearrays etwas unwirtschaftlich und fehlerträchtig, auch wenn es scheinbar eine direkte Konversionsmethode gibt.

Nachdem ich einige Zeit experimentiert habe, bleibt letztendlich nichts anderes als für die Bearbeitung von *.tbl Dateien eine eigene ByteBuilder/Bytebuffer-Klasse zu erzeugen. Die Analyse des Java-Quelltextes und das intensive Studium der API wies mir keine anderen Weg.

Hierzu bearbeite ich einen StringBuilder-Quelltext um. Eins zu eins kann ich den Text nicht übernehmen, weil in der Klasse String diverse Funktionen realisiert sind, die StringBuilder weidlich nutzt, aber die für ByteArrays nicht existieren. Ein paar der Funktionen sind in Assembler geschrieben, deren Quelltext nicht offen gelegt ist.

Ich denke, dass ich heute noch ByteBuffer fertig mache und dann wieder an den TblContainer gehe.
 
Ein Problem wenn man mit einer neuen Programmiersprache beginnt: Die ganzen komfortablen selbst geschriebenen Supportklassen fehlen. Man kommt vom Hundertste ins Tausendste um wieder auf alte Standards zu kommen. Nun ja, man wird aber auch mit neuen Programmiersprache entsprechend eng vertraut.

Ich konnte es mir einfach nicht verkneifen: Ich habe meinen ByteBuffer um allgemein gültigen UTF-Charsupport ergänzt (1-, 2-, 3-ByteChars). Endlich lesbare Einträge in der *.tbl-Datei... ä, ö, ü etc. werden richtig dargestellt und geschrieben.

Da ich jeden Tag eher nur eine oder zwei Stunden am Text sitze, geht es etwas langsam voran. Wenn die Supportklassen endlich endgültig stehen, ist der Rest eher ein Kinderspiel. Jedes weitere Projekt eher auch.

Vorlage aus FileInputStream; Umgeschrieben für ByteBuffer: Lesen eines Zeichens.
Aufgerufen wird die Funktion über den hasMoreChars()-Test von nextChar()

Code:
    public char charAt(int index) throws IOException {

    	int c, char2, char3;
    	int count = index;
    	
    		c = (int) value[count] & 0xff;
    		switch (c >> 4) {
    		case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
    			/* 0xxxxxxx*/
    			count++;
    			charindex=count;
    			return(char)c;
    			
    		case 12: case 13:
    			/* 110x xxxx   10xx xxxx*/
    			count += 2;    			
    			char2 = (int) value[count-1];
    			if ((char2 & 0xC0) != 0x80)
    				throw new UTFDataFormatException();
    			charindex=count;
    			return((char)(((c & 0x1F) << 6) | (char2 & 0x3F)));
    			
    		case 14:
    			/* 1110 xxxx  10xx xxxx  10xx xxxx */
    			count += 3;    			
    			char2 = (int) value[count-2];
    			char3 = (int) value[count-1];
    			if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
    				throw new UTFDataFormatException();
    			charindex=count;
    			return((char)(((c     & 0x0F) << 12) |
    					((char2 & 0x3F) << 6)  |
    					((char3 & 0x3F) << 0)));
    			
    		default:
    			/* 10xx xxxx,  1111 xxxx */
    			throw new UTFDataFormatException();
    			
    		}    	
    }
 
Aktuell bin ich noch dabei mein neues Linux einzurichten. Mein Bruder überraschte mich mit Suse 10.2 zu meinem Geburtstag... Aktuell bleibt nicht viel Zeit um am Projekt weiter zu machen. (Da gibt es noch das eine oder andere Paket zum downloaden)

Das meiste lief auf Anhieb (kein Vergleich zu Linux vor 10 Jahren, da war tüffteln und von Hand konfigurieren angesagt). TV-Karte, Geforce 6800LE, Fritzbox, Internetverbindung... verblüffend einfach. Alles geht... Hab` nur ein kleines Problemchen mit meinem DVD-Player. Meine alten Kauf-DVD's laufen trotz VLC trotzdem nicht...

Eclipse ist jetzt auch drauf... Jetzt brauch ich nur noch Ersatz für meine vollkommen zerkratzte LOD-CD...

Mein Rechner ist leider noch keine vollkommen Microsoft-freie Zone... Mal schaun...
 
Zurück
Oben