2016-04-13 4 views
1

Bitte beachten Sie, dieser Pseudo-Code ist, und ich bin summarising.I ist etwas Quellcode aus dem Innern einer Funktion zu lesen:Wie weiß diese binary.read, wann sie aufhören soll?

maxKeyLen := 100 * 1024 * 1024 
maxValueLen := 100 * 1024 * 1024 
var klen, vlen uint32 
binary.Read(p.buffer, binary.BigEndian, &klen) 

if klen > maxKeyLen { 
    return nil, nil, fmt.Errorf("key exceeds max len %d, got %d bytes", maxKeyLen, klen) 
} 

An welchem ​​Punkt hört die binary.Read? Denn gerade danach gibt es eine andere Lese:

key := make([]byte, klen) 
_, err := p.buffer.Read(key) 
if err != nil { 
    return nil, nil, err 
} 

binary.Read(p.buffer, binary.BigEndian, &vlen) 
if vlen > maxValueLen { 
    return nil, nil, fmt.Errorf("value exceeds max len %d, got %d bytes", maxValueLen, vlen) 
} 

Wo p.buffer über definiert:.

buff := new(bytes.Buffer) 
io.Copy(buff, r) 
p.buffer = buff 

und r einige Daten, die übergeben wurde

Zuerst dachte ich, Die Antwort war bei 4 Bytes, es stoppt. Aber das ist nicht wahr, weil das Maxkeylen nach mehr als das sucht. Wie also weiß die binary.read wann zu stoppen, da mehr Daten voraus sind, weil die nächste für den vlen gelesene binäre dann Sachen findet?

+5

binary.Read liest genau die Größe der Daten, die benötigt werden, um das Argument 'data' zu füllen. Also ja, es liest genau 4 Bytes für ein 'uint32' und stoppt. – JimB

+0

'klen' wird den Wert von 4 Bytes (uint32) zugewiesen, gelesen von' p.buffer', interpretiert als Big-Endian. Es wird nicht die Anzahl der gelesenen Bytes zugewiesen. – thwd

+0

@jimB Bist du sicher, weil das bedeuten würde, dass die Bedingung klen> maxKeyLen niemals wahr wäre, weil klen höchstens 4 Bytes hat? –

Antwort

3

Wenn die Superhelden von Go in Frage, beziehen sich immer auf ihre eigentlichen Quellcode in Frage:

https://golang.org/src/encoding/binary/binary.go?s=4201:4264#L132

142 func Read(r io.Reader, order ByteOrder, data interface{}) error { 
143  // Fast path for basic types and slices. 
144  if n := intDataSize(data); n != 0 { 

Linie 144 zeigt ein Beispiel für das Lesen der Anfangsgröße Typen kennen und Iterieren oder Kopieren nach Bedarf später in diesem Bereich.

In Ihrem obigen Codebeispiel ist dies die 4-Byte-Länge von klen, die eine uint32 ist. Das heißt, es wird 4 Bytes von p.buffer in klen lesen.

Es gibt einen Hinweis in der Dokumentation:

https://golang.org/pkg/encoding/binary/#Read

func Read(r io.Reader, order ByteOrder, data interface{}) error 

lesen liest strukturierte Binärdaten von r in Daten. Die Daten müssen ein Zeiger auf einen Wert fester Größe oder ein Segment fester Größe sein. Bytes, die von r gelesen werden, werden unter Verwendung der spezifizierten Byte-Reihenfolge decodiert und in aufeinanderfolgende Felder der Daten geschrieben.

+0

Die Read-Funktion überprüft nicht die "feste Größe" von p.buffer, es überprüft die Größe des Typs für "Daten". Das 'r' Argument ist nur ein' io.Reader' und benötigt keine Größe. – JimB

+0

ah. Du hast Recht. das bekomme ich, wenn ich auf einem Handy antworte und zu schnell lese. aktualisiert. – eduncan911

Verwandte Themen