Andreas Rozek Lesehinweise letzte Änderungen Gästebuch-Eintrag Mitteilungen an den Autor  English Version  zur Leitseite zum vorherigen Thema zum nächsten Thema  zur ersten Seite zur vorherigen Seite zur nächsten Seite

ByteArray

Die "ByteArray"-Klasse stellt unter JavaScript (dicht belegte) Byte-Felder veränderlicher Größe zur Verfügung. Der Zugriff auf die Elemente eines solchen Feldes geschieht auf dieselbe Weise wie bei einem JavaScript-"Array", anders als dort tauchen die Feld-Elemente jedoch nicht in for-in-Schleifen auf - außerdem ist die Implementierung effizienter, was sich vor allem bei größeren Byte-Feldern bemerkbar macht.

Aufgrund der Erfahrungen mit der "Enumerator"-Implementierung wurde die "ByteArray"-Klasse als Rhino "Host Object" realisiert. Eine zusätzliche, explizit implementierte Methode der "Scriptable"-Schnittstelle regelt die Sichtbarkeit von Methoden und Datenfeldern.

Allgemeine Hinweise

Definition von Ausschnitten aus einem ByteArray

"ByteArray"-Objekte können sowohl als Ganzes als auch ausschnittsweise adressiert werden. Ausschnitte werden durch einen Offset und ggfs. einen Count definiert. Mit dem Offset wird der Index des ersten zu berücksichtigenden Feld-Elementes festgelegt, und Count gibt die Anzahl der zu berücksichtigenden Elemente an (ohne Angabe eines Count umfaßt der Ausschnitt alle Elemente vom angegebenen Offset bis zum Ende eines Feldes). Kann auch die Angabe des Offset entfallen, so beginnt der Ausschnitt ohne die Offset-Angabe ab dem ersten Element des zugrundeliegenden Feldes.

Positive Offsets werden vom Anfang eines Feldes, negative von dessen Ende aus gezählt: so adressiert 0 das erste Element eines Feldes, 1 das zweite, usw. wohingegen -1 für das letzte Feld-Element, -2 für das vorletzte usw. steht. Der definierte Ausschnitt darf jedoch in beiden Fällen die Grenzen des zugrundeliegenden Feldes nicht überschreiten.

Veränderungen der Größe des aktuellen Objektes

Die Größe des aktuellen "ByteArray"-Objektes kann durch Anhängen (append) oder Einfügen (insert) eines anderen "ByteArray" vergrößert werden, durch Entfernen einzelner (remove) oder aller (clear) Elemente aus dem Objekt wird die Feld-Größe verringert, und replace verbindet beides in einem einzigen Aufruf. Alle anderen Methoden lassen die Größe eines "ByteArray" unverändert;

Verkettung von Methoden

Viele das aktuelle Objekt verändernde Methoden geben das modifizierte Objekt auch als Methoden-Ergebnis zurück - auf dieses Ergebnis kann nun sofort eine weitere Methode angewandt werden. Bei entsprechender Verwendung dieses "Tricks" läßt sich ggfs. der Schreibaufwand beim Programmieren verringern und die Lesbarkeit von Programmen verbessern.

Objektbeschreibung (JavaScript)

Konstruktor

new ByteArray ([initialSize])

erzeugt ein neues "ByteArray"-Objekt mit Platz für die angegebene Anzahl von Bytes (ohne Angabe einer anfänglichen Größe wird ein Feld mit 0 Elementen angelegt). Alle Feld-Elemente werden mit 0 vorbelegt;

new ByteArray (Content)

erzeugt ein neues "ByteArray"-Objekt und initialisiert dieses mit dem Inhalt eines anderen angegebenen "ByteArray";

Datenfelder

Size
enthält die derzeitige Anzahl der Elemente im "ByteArray" (read-only);

Methoden

append (Source[, SourceOffset[, SourceCount]]) -> ByteArray

fügt den Inhalt des angegebenen "ByteArray" Source komplett oder ausschnittsweise an das Ende des aktuellen Objektes an. Falls angegeben, definiert SourceOffset den Index des ersten zu kopierenden Byte aus Source, und SourceCount legt fest, wieviele Bytes aus Source übernommen werden sollen. Die Methode verändert das aktive "ByteArray"-Objekt und gibt dieses außerdem als Ergebnis zurück;

clear () -> ByteArray

löscht das "ByteArray"-Objekt und gibt den von den zuvor darin abgelegten Elementen belegten Speicherplatz frei. Die Methode verändert das aktive "ByteArray"-Objekt und gibt dieses außerdem als Ergebnis zurück;

equals (Object) -> Boolean

prüft, ob das "ByteArray"-Objekt mit dem angegebenen Objekt identisch ist bzw. diesem inhaltlich gleicht - falls ja, liefert die Funktion den Wert true zurück, ansonsten ist das Ergebnis false;

fill ([Offset[, Count]], Value) -> ByteArray

belegt alle oder einige Elemente des aktuellen "ByteArray"-Objektes mit dem angegebenen Zahlenwert Value (dieser muß dazu im Bereich -127...+255 liegen). Falls angegeben, definiert Offset den Index des ersten zu überschreibenden Elementes, und Count legt fest, wieviele Bytes insgesamt mit dem angegebenen Wert überschrieben werden sollen. Die Methode verändert das aktive "ByteArray"-Objekt und gibt dieses außerdem als Ergebnis zurück;

isEmpty () -> Boolean

prüft, ob das "ByteArray" leer ist, d.h. keine Elemente enthält - falls ja, liefert die Funktion den Wert true zurück, ansonsten ist das Ergebnis false;

insert (Offset, Source[, SourceOffset[, SourceCount]]) -> ByteArray

fügt ein "ByteArray"-Objekt (Source) ab der angegebenen Position (Offset) komplett oder ausschnittsweise in das aktuelle Objekt ein - dieses wird zuvor passend vergrößert und alle Elemente ab der Einfügeposition um die Anzahl der einzufügenden Bytes nach hinten verschoben. Falls angegeben, definiert SourceOffset den Index des ersten zu kopierenden Byte aus Source, und SourceCount legt fest, wieviele Bytes aus Source übernommen werden sollen. Die Methode verändert das aktive "ByteArray"-Objekt und gibt dieses außerdem als Ergebnis zurück;

overwrite (Offset, Source[, SourceOffset[, SourceCount]]) -> ByteArray

überschreibt im aktuellen Objekt die auf die angegebene Position (Offset) folgenden Elemente mit dem (kompletten oder ausschnittsweisen) Inhalt des "ByteArray"-Objektes Source. Im aktuellen Objekt werden dabei genau soviele Elemente überschrieben wie aus Source übernommen werden - bei Bedarf wird das aktuelle Objekt zuvor außerdem passend vergrößert. Falls angegeben, definiert SourceOffset den Index des ersten zu kopierenden Byte aus Source, und SourceCount legt fest, wieviele Bytes aus Source übernommen werden sollen. Die Methode verändert das aktive "ByteArray"-Objekt und gibt dieses außerdem als Ergebnis zurück;

remove (Offset[, Count]) -> ByteArray

entfernt alle (oder einige) auf die angegebene Position (Offset) folgenden Elemente aus dem aktuellen "ByteArray"-Objekt - dieses wird dabei entsprechend verkleinert. Falls angegeben, definiert Count die Anzahl der zu entfernenden Bytes, ansonsten wird von Offset ausgehend bis zum Ende des "ByteArray" gelöscht. Etwaige, auf den gelöschten Ausschnitt folgende Elemente werden soweit zum Anfang des "ByteArray" hin verschoben, daß sich wieder ein lückenloses Byte-Feld ergibt. Die Methode verändert das aktive "ByteArray"-Objekt und gibt dieses außerdem als Ergebnis zurück;

replace ([Offset, [Count,]] Source[, SourceOffset[, SourceCount]]) -> ByteArray

ersetzt alle (oder einige) auf die angegebene Position (Offset) folgenden Elemente des aktuellen "ByteArray"-Objektes durch den (kompletten oder ausschnittsweisen) Inhalt des "ByteArray"-Objektes Source. Die Größe des aktuellen Objektes wird dabei entsprechend angepaßt und alle nicht ersetzten Elemente soweit verschoben, daß sich wieder ein lückenloses Byte-Feld ergibt. Sofern angegeben, beginnt der zu ersetzende Ausschnitt ab Position Offset (sonst gleich vom ersten Element des aktuellen Objektes an) und erstreckt sich über Count Elemente (ansonsten bis zum Ende des aktuellen Feldes). Falls angegeben, definiert SourceOffset den Index des ersten zu kopierenden Byte aus Source, und SourceCount legt fest, wieviele Bytes aus Source übernommen werden sollen. Die Methode verändert das aktive "ByteArray"-Objekt und gibt dieses außerdem als Ergebnis zurück;

slice (Offset[, Count]) -> ByteArray

Kopiert alle (oder einige) Elemente des aktuellen "ByteArray"-Objektes in ein neu angelegtes "ByteArray" und liefert dieses als Methoden-Ergebnis zurück. Falls angegeben, legt Offset die Position des ersten zu kopierenden Elementes fest (ansonsten wird vom Anfang des aktuellen Feldes an kopiert), und Count definiert die Anzahl der zu übernehmenden Bytes (ansonsten werden alle Bytes bis zum Ende des Feldes übernommen);

toString () -> String

liefert eine literale Repräsentaton des "ByteArray"-Objektes;

Verwendungshinweise (JavaScript)

Erzeugen und Bearbeiten eines neuen ByteArray

Die Verwendung von "ByteArray"-Objekten ist denkbar einfach: zunächst wird ein leeres "ByteArray" passender Größe angelegt:

  var Array = new ByteArray(Size);

Auf dieses Feld kann nun wie auf ein JavaScript "Array" zugegriffen werden:

  Array[Index] = ByteValue;
  ... = Array[Index];

Einer der Unterschiede zu einem JavaScript "Array" besteht darin, daß die Elemente eines "ByteArray" nicht in for-in-Schleifen auftauchen. Desweiteren müssen sich die verwendeten Indices innerhalb der aktuellen Feldgrenzen (0...Array.Size) bewegen und die zugewiesen Werte zahlen im Bereich -127... 255 sein.

Anwendungsbeispiel (JavaScript)

Das Rhino-Skript ByteArrayTest.js verdeutlicht das Anlegen eines "ByteArray" sowie dessen Verwendung. Zusätzlich werden alle Slots des "ByteArray"-Objektes angezeigt.

Das Programm wird ohne Angabe von Kommandozeilen-Argumenten aufgerufen

  java Rhino ByteArrayTest.js

und liefert folgende Ausgabe:

  ByteArrayTest - tests the "sunda.rhino.data.ByteArray" class

  constructing a first ByteArray...
  printing that array's contents:
    Size = 8, Contents = 0x0102030405060708
  removing a few bytes...
    Size = 6, Contents = 0x010203060708
  extracting the first two bytes...
    Size = 2, Contents = 0x0102
  and appending them to the array again...
    Size = 8, Contents = 0x0102030607080102
  inserting its first two bytes into the array...
    Size = 10, Contents = 0x01020301020607080102
  and filling half of it with a fixed value...
    Size = 10, Contents = 0x01020355555555555555
  comparing the array with itself...
    Array == Array ? true
  comparing the array with a copy of itself...
    Array == new ByteArray(Array) ? true
  comparing the array with another ByteArray...
    Array == anotherArray ? false
  clearing the array...
    Size = 0, Contents = (empty)
  analyzing the Array's internals:
   - append: function append() {  [native code] }
   - clear: function clear() {    [native code] }
   - equals: function equals() {  [native code] }
   - fill: function fill() {      [native code] }
   - isEmpty: function isEmpty() {        [native code] }
   - insert: function insert() {  [native code] }
   - overwrite: function overwrite() {    [native code] }
   - remove: function remove() {  [native code] }
   - replace: function replace() {        [native code] }
   - Size: 0
   - slice: function slice() {    [native code] }
   - toString: function toString() {      [native code] }

Wie aus der Programmausgabe ersichtlich, verhält sich die "ByteArray"-Implementierung beinahe wie eine intrinsische Rhino-Klasse und bedarf deshalb keiner weiteren Erläuterung.

Quelltexte

Alle Java-Klassen und Rhino-Skripte sind auch im Quelltext verfügbar:

Literaturhinweise

[1]

(Netscape)
Tutorial: Embedding Rhino
(siehe http://www.mozilla.org/rhino/tutorial.html)
die angegebene Anleitung beschreibt Verfahren zur Verknüpfung von Java und JavaScript (Rhino);

[2]

(Microsoft)
JScript Documentation
(siehe http://msdn.microsoft.com/library/default.asp/?url=/library/en-us/script56/html/js56jsoriJScript.asp)
die Dokumentation zu Microsoft's JScript enthält nicht nur ein sehr schönes JScript-Tutorial, sondern beschreibt auch die Microsoft-spezifischen Erweiterungen des JavaScript-Standards;

Haftungsausschluß

Bitte beachten Sie auch den Haftungsausschluß des Autors!

http://www.Andreas-Rozek.de/Rhino/Erweiterungen/ByteArray.html    (letzter Stand: 06.04.2002)