/*
Datei............: Aufg1134.java
Projekt..........: Einführung in die Java-Programmierung
Erstellt.........: 22.11.97, Guido Krüger
Geändert.........: --
Aufgabe..........: Musterlösung zu Aufgabe 11.34
Kommentare.......:

Die Lösung zu dieser Aufgabe kann im wesentlichen in zwei Schritte
unterteilt werden:

- Das Hauptprogramm öffnet einen FileReader, um die Eingabedatei
  zeichenweise zu lesen und speichert je 16 gelesene Zeichen in 
  einem Pufferarray.
- Nachdem 16 Zeichen gelesen wurden (oder das Ende der Eingabe
  erreicht ist), wird der Puffer mit Hilfe der Methode printBuffer
  formatiert ausgegeben.

Einzige Hilfsmethode ist toFixHexString, mit der es möglich ist,
eine Ganzzahl im Hexformat mit einer festen Stellenzahl auszugeben.
*/
import java.util.*;
import java.io.*;

public class Aufg1134
{
  //--- Instanzmerkmale ------------------------------
  static int firstbytecnt;

  public static void main(String args[])
  {
	if (args.length < 1) {
	  usage();
	}
	try {
	  int buffer[]= new int[16];
	  int size = 0;
	  firstbytecnt = 0;
	  Reader rin = new FileReader(args[0]);
	  int c;
	  while ((c = rin.read()) != -1) {
		buffer[size++] = c;
		if (size == 16) {
		  printBuffer(buffer, size);
		  size = 0;
		  firstbytecnt += 16;
		}
	  }
	  printBuffer(buffer, size);
	  rin.close();
	} catch (FileNotFoundException e) {
	  System.out.println("***Fehler: " + e.toString());
	} catch (IOException e) {
	  System.out.println("***Fehler: " + e.toString());
	}
  }

  //--- Private Methoden ------------------------------
  /**
   * Benutzungsmeldung des Programms. Wird ausgegeben, wenn das
   * Programm mit falscher Kommandozeile aufgerufen wird und beendet
   * anschließend das Programm.
   */
  private static void usage()
  {
	System.out.println("Aufruf: Aufg1134 <datei>");
	System.exit(0);
  }

  /**
   * Ausgabe des maximal size Zeichen großen Buffers im vorgeschriebenen
   * Format. Der Buffer darf höchstens 16 Zeichen lang sein und 
   * beliebige Zeichen enthalten. Die Zeilennummer wird durch das
   * Instanzmerkmal firstbytecnt von außen vorgegeben.
   */
  private static void printBuffer(int buffer[], int size)
  {
	//Byteposition des ersten Zeichens
	System.out.print(toFixHexString(firstbytecnt, 4) + "  ");
	//Hexcodes
	for (int i = 0; i < 16; ++i) {
	  if (i < size) {
		System.out.print(toFixHexString(buffer[i], 2));
	  } else {
		System.out.print("  ");
	  }
	  if (i == 7 && size > 8) {
		System.out.print("-");
	  } else {
		System.out.print(" ");
	  }
	}
	//ASCII-Zeichen
	for (int i = 0; i < size; ++i) {
	  if (buffer[i] >= 32 && buffer[i] <= 126) {
		System.out.print((char)buffer[i]);
	  } else {
		System.out.print(".");
	  }
	}
	//Zeilenschaltung
	System.out.println();
  }

  /**
   * Ausgabe einer Ganzzahl in einer festen Länge im Hexformat. 
   * Falls die Zahl kürzer ist, wird sie linksbündig mit Nullen
   * gefüllt.
   */
  private static String toFixHexString(int value, int len)
  {
	String ret = Integer.toHexString(value);
	if (ret.length() < len) {
	  ret = "0000000000000000".substring(0, len - ret.length()) + ret;
	}
	return ret.toUpperCase();
  }
}


