2013-02-20 11 views
5

Sto lavorando alla conversione di un gruppo di vecchi file di dump di database MySQL con separatori di tabulazione in Buffer di protocollo e sono rimasti intrappolati. La tabella MySQL include un campo di tipo int(11) unsigned, che ho mappato a protobuf uint32 nel file .proto. Quando si analizzano i record MySQL e si tenta di convertirli in un messaggio protobuf, si è tentati di analizzare il campo utilizzando Integer.valueOf(String) (o Long.valueOf(String) per evitare gli overflow). Tuttavia, lo Protocol Buffers Language Guide indica here che in Java, uint32 s sono rappresentati utilizzando il tipo di dati int, ma con il primo bit che viene reinterpretato come il bit di ordine più alto anziché come bit di segno.Come convertire gli interi non firmati MySQL nel protocollo Buffer uint32s in Java?

Quindi prima di andare scrivere il mio String ->uint32 -flavored- int parser, ho pensato che fosse la pena chiedere se qualcun altro ha già risolto questo problema particolare. Qual è il modo corretto di convertire una rappresentazione String di MySQL int unsigned in un buffer di protocollo uint32 in Java?

risposta

1

String a int che rappresenta Uint32

mi piacerebbe provare il parsing come long e poi la conversione in int:

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

Utilizzando long per la conversione evita un NumberFormatException a causa di una gamma superato. Il successivo narrowing conversion eliminerà la metà più significativa dei bit risultanti, lasciandovi esattamente la rappresentazione richiesta dal buffer del protocollo.

stringa a rappresentare lungo uint64

Una conversione simile per uint64 utilizzando BigInteger potrebbe probabilmente essere scritto come segue (codice non testato):

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

Questa si basa su un troncamento implicita, proprio come nel sopra Astuccio. I documentation afferma:

Se questo BigInteger è troppo grande per entrare in un lungo, solo il basso per 64 bit vengono restituiti.

Int rappresenta uint lungo

Se si desidera convertire un tale int che rappresenta in realtà un uint32 ad un long con segno positivo, si dovrebbe fare in modo di cancellare i 32 bit più significativi, in quanto questi saranno essere riempito con copie del bit più significativo del valore int, a causa della natura di estensione del segno dello widening conversion.

long uintValue = intValue & 0xffffffffL; 
+0

Ero giunto a una conclusione simile, ma l'hai implementato in modo più pulito di quanto non facessi io. Questo suggerisce una domanda simile: come analizzare 'bigint unsigned 'su protobuf' uint64' tramite Java? –

+0

La tua soluzione suggerisce anche che la non-conversione può essere fatta semplicemente rimandando da 'int' a' long', che è bello. –

+0

@JoshHansen, ho aggiornato la mia risposta in risposta a entrambi i vostri commenti. – MvG

0

Se il endianness non è un problema, è possibile minacciare unsigned uns come matrici di byte di lunghezza fissa.