2013-02-20 4 views
5

Ich arbeite an der Umwandlung einer Reihe von alten Tab-getrennte MySQL-Datenbank-Dump-Dateien in Protocol Buffers und haben in einen Haken geraten. Die MySQL-Tabelle enthält ein Feld vom Typ int(11) unsigned, das ich in der .proto-Datei dem Protobuf uint32 zugeordnet habe. Wenn Sie die MySQL-Datensätze analysieren und versuchen, sie in eine protobuf-Nachricht zu konvertieren, ist es verlockend, dieses Feld mit Integer.valueOf(String) (oder Long.valueOf(String) zu analysieren, um Überläufe zu vermeiden). Die Protocol Buffers Language Guide zeigt jedoch here an, dass in Java uint32 s unter Verwendung des int-Datentyps dargestellt sind, wobei jedoch das erste Bit als höchstwertiges Bit und nicht als Vorzeichenbit umgedeutet wird.Wie konvertiere ich MySQL nicht signierte Ints in Protocol Buffer uint32s in Java?

Also, bevor ich meine eigenen String schreiben gehen ->uint32 -flavored- int Parser, dachte ich es wert war, zu fragen, ob jemand anderes bereits dieses spezielle Problem gelöst hat. Was ist die korrekte Art, eine String Darstellung von MySQL int unsigned in einen Protokollpuffer uint32 in Java zu konvertieren?

Antwort

1

String in int Uint32

darstellt. Die folgende narrowing conversion wird die signifikantere Hälfte der resultierenden Bits fallenlassen und Sie genau mit der Darstellung verlassen, die von dem Protokollpuffer benötigt wird.

String zu lang uint64

Eine ähnliche Umwandlung für uint64 darstellen mit BigInteger wahrscheinlich wie folgt geschrieben werden kann (ungetestet Code):

long l = (new BigInteger(str)).longValue(); 

Dies auf einer implizite Abschneiden beruht, genau wie in den obigen Fall. Die documentation Staaten:

Wenn diese BigInteger zu groß ist, eine lange, nur die niedrige Ordnung 64 Bits zurückgegeben werden, passen.

Int darstellt uint zu lange

Wenn Sie eine solche int konvertieren möchten, die tatsächlich eine uint32 zu einem long mit positivem Vorzeichen darstellt, sollten Sie sicherstellen, dass die 32 höchstwertigen Bits zu löschen, da diese mit Kopien des höchstwertigen Bits des Wertes int gefüllt werden, aufgrund der Zeichenerweiterungsnatur des widening conversion.

long uintValue = intValue & 0xffffffffL; 
+0

Ich war zu einer ähnlichen Schlussfolgerung gekommen, aber Sie implementieren es sauberer als ich es getan habe. Dies deutet auf eine ähnliche Frage hin: Wie kann man "unsigned bigint" mit Hilfe von Java zu protobuf "uint64" parsen? –

+0

Ihre Lösung schlägt auch vor, dass das Konvertieren einfach ausgeführt werden kann, indem Sie von "int" zu "long" zurückwerfen, was nett ist. –

+0

@JoshHansen, habe ich meine Antwort als Antwort auf beide Kommentare aktualisiert. – MvG

0

Wenn die Endianität kein Problem ist, können Sie unsignierte Ints als Byte-Arrays mit fester Länge bedrohen.

int i = (int)Long.parseLong(str); 

Mit long für die Umwandlung eines NumberFormatException aufgrund einer Überschreitung Bereich vermeidet: Ich würde versuchen, so long Parsen und dann die Umwandlung zu int

Verwandte Themen