[SP-pm] Separar o primeiro do resto

Tiago Peczenyj tiago.peczenyj at gmail.com
Tue Apr 30 20:28:05 PDT 2013


Agora sim

Bom, deixem me explicar o que eu quero fazer: o Riak tem uma interface que
usa Protocol Buffers. por exemplo

0x14,0,0,0,0xa,0xa,0x11,0xa,0xf,0x7b,0x20,0x66,0x6f,0x6f,0x20,0x3d,0x3e,0x20,0x27,0x62,0x61,0x72,0x27,0x7d

essa tralha toda representa uma resposta de um "GET", basicamente temos

4 bytes para o tamanho da mensagem
resto da mensagem

o resto da mensagem tem

1 byte para o codigo de retorno (em caso de erro é 0)
o resto para ser decodificado via protocol buffers.

logo temos

0x14,0,0,0|0xa|0xa,0x11,0xa,0xf,0x7b,0x20 ..
    size | code | message

então eu preciso fazer o seguinte

ler os primeiros 4 bytes para saber o tamanho da mensagem
ler o quinto byte para saber o codigo de retorno
ler do sexto em diante para decodificar.

basicamente um

$socket->sysread($len, 4); # leio os 4 primeiros bytes
my $len = unpack('L', $len); # converto pra inteiro 32 bits

socket->sysread($buff, $len) # leio o resto

my($code, $encoded_message) = unpack('c a*', $buff);

E tudo aparentemente funciona. Eu estava fazendo 3 sysread's só para pegar
toda a mensagem.

porem eu não sei se estou fazendo isso da forma mais eficiente. Na real eu
poderia ler até 1024 bytes (por exemplo) e fazer unpack de tudo:

my ($len, $code, $msg) = unpack('L c a*', $msg);

if ( bytes::lenght($code . $msg) == $len) {
  # decode message
 } else {
  # read more bytes
 }
}

Eu realmente não sei o que é melhor. Por um lado ler 2 vezes me garante que
eu vou passar um numero mais exato para o sysread, por outro eu não sei
qual é o impacto de fazer um

sysread($buffer, 2048); # ou qq numero "grandão"

sendo que a mensagem teve uns 20 bytes. meu medo é que isso "trave",
independente do tamanho que eu estou "chutando". e como estou testando com
um riak local eu estou eliminando varios problemas de rede.

ALIAS qual a melhor maneira de implementar um timeout nessa operação de
leitura? Tipo em 0.2 segundos se não veio nada quero que retorne undef e
bola pra frente. Acho que vou ter que apelar para alarm do Time::HiRes ...

Desculpem o email confuso.

Tiago







2013/4/30 Stanislaw Pusep <creaktive at gmail.com>

> $ perl -E 'say for unpack "a a*", "hello"'
> h
> ello
> $
>
>
> ABS()
>
>
> 2013/4/30 Tiago Peczenyj <tiago.peczenyj at gmail.com>
>
>> Nao posso resolver com unpack ???
>> Em 30/04/2013 19:51, "Lucas Moraes" <lucastiagodemoraes at gmail.com>
>> escreveu:
>>
>>  Só muda a expressão
>>> m{^([\d\w]{1})(.*?)}s
>>> $1 $2
>>>
>>>
>>> Em 30 de abril de 2013 19:46, Tiago Peczenyj <tiago.peczenyj at gmail.com>escreveu:
>>>
>>>> Bytes!
>>>>
>>>> Na verdade eh algo como
>>>>
>>>> 09 00 AF 1D..
>>>> Em 30/04/2013 19:41, "Lucas Moraes" <lucastiagodemoraes at gmail.com>
>>>> escreveu:
>>>>
>>>>  com regex você faz isso
>>>>> m{(\d{1})(\d{1,})}s;
>>>>> $1, $2
>>>>>
>>>>>
>>>>> Em 30 de abril de 2013 19:37, Tiago Peczenyj <tiago.peczenyj at gmail.com
>>>>> > escreveu:
>>>>>
>>>>>> Seguinte: tenho X bytes como
>>>>>>
>>>>>> $x="12345"
>>>>>>
>>>>>> E quero pegar o primeiro e o resto:
>>>>>>
>>>>>> ($a,$b) = magica $x;
>>>>>>
>>>>>> $a = 1
>>>>>> $b = 2345
>>>>>>
>>>>>> Comofas?
>>>>>>
>>>>>> Eu posso fazer bytes::substr 2 vezes mas ta feio...
>>>>>>
>>>>>> =begin disclaimer
>>>>>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>>  SaoPaulo-pm mailing list: SaoPaulo-pm at pm.org
>>>>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>> =end disclaimer
>>>>>>
>>>>>>
>>>>>
>>>>> =begin disclaimer
>>>>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>  SaoPaulo-pm mailing list: SaoPaulo-pm at pm.org
>>>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>> =end disclaimer
>>>>>
>>>>>
>>>> =begin disclaimer
>>>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>  SaoPaulo-pm mailing list: SaoPaulo-pm at pm.org
>>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>> =end disclaimer
>>>>
>>>>
>>>
>>> =begin disclaimer
>>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>  SaoPaulo-pm mailing list: SaoPaulo-pm at pm.org
>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>> =end disclaimer
>>>
>>>
>> =begin disclaimer
>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>  SaoPaulo-pm mailing list: SaoPaulo-pm at pm.org
>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>> =end disclaimer
>>
>>
>
> =begin disclaimer
>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>  SaoPaulo-pm mailing list: SaoPaulo-pm at pm.org
>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
> =end disclaimer
>
>


-- 
Tiago B. Peczenyj
Linux User #405772

http://about.me/peczenyj
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20130501/411f3958/attachment-0001.html>


More information about the SaoPaulo-pm mailing list