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
|