hotti: Numerische Angaben in Sequenzen

In Sequenzen habe ich Längenangaben, prosaisch notiert:
-als Nächstes sind 5 bytes zu lesen.....
-als Nächstes sind 55 bytes zu lesen............... ... unsw.

Diese Längenangaben, also 5 oder 55 stehen natürlich nicht so drin im Stream, vielmehr sind diese Angaben in einer byte-Sequenz so codiert, dass das immer 4 byte sind (32 Bier). Also: Eine Längenangabe 5 benötigt 4 byte, 55 kriegt auch 4 byte.

Frage: Kann JavaScript mittlerweile mit binär codierten Zahlen umgehen, gibts da sowas wie pack/unpack?

Horst

  1. Hallo hotti,

    Frage: Kann JavaScript mittlerweile mit binär codierten Zahlen umgehen, gibts da sowas wie pack/unpack?

    Antwort: Ja.

    Gruß, Jürgen

    1. Danke lieber Jürgen;

      Antwort: Ja.

      Ob das Big- oder Little Endians sind... ok, ich kriege das raus, werd mal damit spielen. Wichtig ist, dass ein Uint32Array mit dem zurechtkommt, was pack("N", 123) oder pack("V", 123) (Network- bzw. Vax-Order) in einer Response sendet, z.B. eine kleine 'Datenbank' oder andere komplexe Datenstrukturen.

      Viele Grüße!

      --
      Wenn wir geboren werden, weinen wir. Wenn wir sterben, weinen die Anderen Danke Dieter
      1. Hallo hotti,

        meine Erfahrungen mit Binärdaten in Javascript beschränken sich auf das auswerten des EXIF-Headers von JPEG-Bildern. Ich lese sie mit

        request.responseType = "arraybuffer";

        und

        result.binarydata = new Uint8Array(request.response);

        bzw. mit der File-API

        var reader = new FileReader();  
        reader.readAsArrayBuffer(fileobject);  
        reader.onload = function(evt) {  
          binarydata = new Uint8Array(evt.target.result);  
          .........  
        }
        

        Gruß, Jürgen

        1. Hi Jürgen,

          request.responseType = "arraybuffer";
          reader.onload = function(evt) {

          Ha! Der reader hat mir noch gefehlt, brauch ich, nehm ich, danke Dir!!!!

          @1UnitedPower
          Ja, im v. Jürgen verlinkten Dokument steht was über die Byte-Order. Sollte ich iiiiiiirgendwie berücksichtigen, für meine ersten Schritte nehme ich mal an, dass es auf Client und Server dieselbe ist, i.d.R. isses Network-Order.

          Demnächst die erste Brettschaltung, Übertragung eines Arrays als Byte-Stream, NICHT zeichenorientiert strukturiert, also kein JSON, XML o.ä. Im Unterschied zu JSON wird ein Stream nicht geparst, nachdem er im Speicher eingelesen wurde. Ein Stream wird unmittelbar, byte für byte gelesen, der Speicherbedarf ist geringer, d.h., es liegt nur das Ergebnis im RAM, nicht jedoch die Rohdaten.

          Bis dann,
          Horst

          1. Hallo hotti,

            beachte:

            request.responseType = "arraybuffer";

            das gehört zum httpRequest, also Lesen vom Server (und im FF auch vom lokalen Speicher)

            und

            reader.onload = function(evt) {

            gehört zur File-API, also Lesen vom lokalen Speicher,

            Gruß, Jürgen

            1. hi Jürgen,

              ich blick noch nicht durch.
              Brettschaltung

              sendet, wenn Parameter im Request sind, die Zahl 4711 binär in Network-Order als 32-Bit-unsigned integer.

              Meine ajax-Callback gibt diese Response nur z.T. aus, zu sehen ist nur das letzte byte.

              Was muss ich in Sachen JS machen, damit 4711 ausgegeben wird?

              Bitte mal um Hilfestellung...

              1. Hallo hotti,

                Was muss ich in Sachen JS machen, damit 4711 ausgegeben wird?

                du darfst den http-Request nicht in ascii laufen lassen. Hier mal ein ungetesteter Auszug aus meinem getesteten Filereader

                request = new XMLHttpRequest();  
                request.onreadystatechange = function() {  
                  if (request.readyState == 4) {  
                    status = request.status;  
                    if (status == 200 || status == 0) { // 0 für lokalen Speicher  
                      request.onreadystatechange = function() {};  
                      binarydata = new Uint8Array(request.response); // nicht responseText  
                      callback(binarydata, status);  
                    }  
                  }  
                }  
                request.open('GET', url, true);  
                request.responseType = "arraybuffer";  
                request.send(null);
                

                Gruß, Jürgen

                1. Hi Jürgen,

                  du darfst den http-Request nicht in ascii laufen lassen. Hier mal ein ungetesteter Auszug aus meinem getesteten Filereader [..]

                  Ich danke Dir ganz herzlich, jetzt habe ich den Anfang, das ist immer der schwierigste Moment. Die Änderungen habe ich in eine kleine, nunmehr blib.js genannte Lib gefasst, b wie binary ;)

                  Meine Testseite gibt nun eine 243 aus, 4711 war wohl doch ein wenig zuviel.... ne im Ernst, ich muss mir das mal in Ruhe angucken ;)

                  Serverseitig erzeuge ich für die Zahl 243 die binary wie folgt, ich poste einfach mal die ganze Response-Class (Perl + HTML, ist ja nicht viel):

                    
                  package Stream;  
                    
                  use base 'main';  
                  use strict;  
                  use warnings;  
                    
                  sub control{  
                      my $self = shift;  
                      $self->{CONTENT} = pack "CCCC", 243;  
                      $self->header("Content-Type" => "appication/octet-stream");  
                  }  
                    
                    
                  1;#########################################################################  
                  __DATA__  
                    
                  <script src="/blib.js"></script>  
                  <script>  
                    
                  var stream = {  
                      callback: function(binary){  
                          alert(binary[0]);  
                      },  
                      call: function(){  
                          this.method = 'POST',  
                          this.url = '%url%',  
                          this.params = 'x=y';  
                          ajaxB_Request(this);  
                          return false;  
                      }  
                  };  
                  stream.call();  
                  </script>  
                  
                  

                  Unterhalb __DATA__ ist das HTML-Template, das ist alles für o.g. Link zur Webressource.
                  Wobei in pack() die Schablone "C" für 8 bit steht... ich habe hier noch ein Verständnisproblem, für was auch Uint32Array(xhr.response); steht, das ist mir noch nicht ganz klar (siehe Link zu /blib.js im Quelltext).

                  Morgen ist auch noch ein Tag...

                  Viele Grüße vom Horst
                  (der sich jetzt zum Fernseher rumdreht, da kommt irgenwas über Rüsseltiere)

      2. Meine Herren!

        Ob das Big- oder Little Endians sind...

        Die deiner Prozessor-Architektur: http://www.khronos.org/registry/typedarray/specs/latest/#2.1

        TypedArrays wurden im wesentlichen zur Performanz-Steigerung eingeführt und sind deshalb nah an die Hardware gebunden.

        Node.js bietet mit Buffern eine robustere (aber vermutlich auch langsamere) API an. Vermutlich existiert auch ein Port für Browser.

        --
        “All right, then, I'll go to hell.”
    2. hi,

      Frage: Kann JavaScript mittlerweile mit binär codierten Zahlen umgehen, gibts da sowas wie pack/unpack?

      Antwort: Ja.

      HTML5 rockt!!!!

      Echt der Hammer auch, was MDN derzeit leistet. Related: FileUpload.

      Am Ende wirds alles ganz einfach ;)

      (Hoffentlich auch gut)

  2. 4 byte sind (32 Bier).

    Whow, das sind ja mehr als zwei Kästen Bier in 4 Byte. Sensationelle Packungsdichte.

    Das geht mit Javascript? Her damit, ich möchte mir Bier auf den USB-Stick laden.

    Linuchs

    1. Hallo,

      4 byte sind (32 Bier).
      Whow, das sind ja mehr als zwei Kästen Bier in 4 Byte. Sensationelle Packungsdichte.

      klar - vor etwa 20 Jahren ging in etwa folgender Kalauer rum:

      F: Wie kommt es eigentlich, dass Windows fast alles kann?
      A: Das liegt an den 32 Bit.
         Wenn ich 32 Bit intus habe, glaube ich auch, ich könnte alles.

      Her damit, ich möchte mir Bier auf den USB-Stick laden.

      Fang mit einfacheren Übungen an: Cola auf die Tastatur. ;-)

      Ciao,
       Martin

      --
      F: Was macht ein Offizier, der in der Nase bohrt?
      A: Er holt das Letzte aus sich heraus.
      Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
  3. Hi there,

    In Sequenzen habe ich Längenangaben, prosaisch notiert:
    -als Nächstes sind 5 bytes zu lesen.....
    -als Nächstes sind 55 bytes zu lesen............... ... unsw.

    nennt man das nicht "verkettete Liste"?

    1. Hi there,

      In Sequenzen habe ich Längenangaben, prosaisch notiert:
      -als Nächstes sind 5 bytes zu lesen.....
      -als Nächstes sind 55 bytes zu lesen............... ... unsw.

      nennt man das nicht "verkettete Liste"?

      Nein, eine verkettete Liste ist was völlig Anderes. Eine byte-Sequenz ist das Abbild einer Datenstruktur auf Byte-Ebene. Da kann eine verkettete Liste drinstehen, muss aber nicht. Da können also auch dreihundert Objekte drinstehen, die überhaupt nichts miteinander zu tun haben. Über den physikalischen Aufbau einer Bytesequenz entscheidet ein Algorithmus, der auch rekursiv sein kann.

      Horst

  4. Meine Herren!

    WebSockets dürften deine Ansprüche besser erfüllen, als AJAX. Wenn man auf den den IE <= 9 verzichten kann, dann ist das sicher eine interessante Erwägung.

    --
    “All right, then, I'll go to hell.”
    1. Hi mein Lieber;

      WebSockets dürften deine Ansprüche besser erfüllen, als AJAX.

      Mein Anspruch ist eine zweckmäßige Strunkturierung der zu übertragenden Daten, egal ob das über Websocket oder ajax läuft.

      Fertige Lösungen, OK, aber ich muss es ja verstehen. Derzeit, also s.o., schlage ich mich mit dem rum, was Browser in Sachen LowLevel auf Byte-Ebene überhaupt können. Hier habe ich Einiges nachzuholen, denn das was heutige Browser können, hat mich ein bischen überholt und es gibt neue interessante Libraries wie z.B. stringview.js u.v.a.m.

      Alles in Allem kann ich jetzt an Sachen rangehen, deren diesbezügliche Pläne seit Jahren unter meinem Schreibtisch liegen.

      Die Energie des Verstehens ist bei mir vorhanden, diese Energie in Arbeit umzusetzen, erfordert zeitlich gesehen eine bestimmte Leistung, die ich jetzt aufbringen kann, solange ich (noch) arbeitslos bin.

      Schönes Wochenende,
      Horst

      1. Meine Herren!

        Mein Anspruch ist eine zweckmäßige Strunkturierung der zu übertragenden Daten, egal ob das über Websocket oder ajax läuft.

        Verstehe. Binäre Kodierungen sind ja vor allem interessant, wenn es darum geht den Speicherbedarf gering zu halten, zum Beispiel auch bei Netzwerk-Übertragungen. AJAX hat im Gegensatz zu Websockets einen relativ großen Overhead, weil bei jeder Transaktion die HTTP-Header mit verschickt werden müssen. Das ist also ein Nachteil hinsichtlich dieser Aufgabenstellung. Deshalb und weil du an anderer Stelle im Thread von Streams gesprochen hast, habe ich WebScokets in den Raum geworfen.

        Weiterhin viel Spaß beim Lernen und Üben ;)

        --
        “All right, then, I'll go to hell.”
  5. Demo Array

    Ich werd später noch was dazu schreiben, steht dann auf der Seite s.o.

    Übertragen wird ein Array über xhr.responseType = 'arraybuffer';

    Die Längenangaben habe ich mal auf 255 begrenzt, pack-Schablone "C" ist das und braucht 1 byte. Hier spielt die Byte-Order keine Rolle, auf meinen Kisten funktioniert ansonsten der Little-Endian mit pack-Schablone "V" (Vax, 32 Bit), ich weiß aber nicht, ob das überall so ist, deswegen bleibts ersteinmal bei 8 Bit, reicht ja auch in den meisten Fällen.

    Sofern ein assoziatives Array übertragen werden soll, wäre nur der Lese-Algorithmus geringfügig zu ändern (Schlüssel-Werte-Paare).

    Der Serializer

      
    sub control{  
        my $self = shift;  
      
        use bytes; # important!!! Byte-Semantic  
        my @data = ('Preis', '99.99 €', 'Zahlart' , 'Bar');  
        foreach my $e(@data){  
            $self->{CONTENT} .= pack("C", length $e).$e;  
        }  
        $self->header("Content-Type" => "application/octet-stream");  
    }  
    
    

    schreibt abwechselnd Länge/Wert in die Bytesequenz. Der Response-Buffer wird dann sukzessive abgearbeitet.

    Vielen Dank an Alle hier Beteiligte. Am Ende wirds eher einfach als kompliziert, es hängt nur am Algorithmus (siehe Quellcode).

    Horst

    PS: Das über Blob und FileReader-Zeugs hab ich mir mal angeschaut. Das ist genau das, was ich nicht haben wollte, weil da die Daten wieder mit textlichen Mitteln strukturiert sind.