[SP-pm] Separar o primeiro do resto

Stanislaw Pusep creaktive at gmail.com
Wed May 1 17:41:24 PDT 2013


Exatamente!

среда, 1 мая 2013 г. пользователь Tiago Peczenyj писал:

> Vc fala desse exemplo:
>
>   # in the default state, expect some header bytes
>  $handle->on_read (sub {
>     # some data is here, now queue the length-header-read (4 octets)
>     shift->unshift_read (chunk => 4, sub {
>        # header arrived, decode
>        my $len = unpack "N", $_[1];
>
>       # now read the payload
>        shift->unshift_read (chunk => $len, sub {
>           my $xml = $_[1];
>           # handle xml
>        });
>     });
>  });
>
>
> 2013/5/1 Stanislaw Pusep <creaktive em gmail.com <javascript:_e({}, 'cvml',
> 'creaktive em gmail.com');>>
>
>> Epa, 4 bytes para armazenar o tamanho da mensagem?! Isso sugere que o
>> protocolo pressupõe a leitura em chunks. O jeito eficiente seria ler em
>> blocos de, digamos, 4KB, e tratar o 1o bloco da forma diferenciada. Isso é,
>> lê o primeiro bloco, pega o tamanho da mensagem e o status, e armazena no
>> buffer o "resto". Depois, continua lendo e concatenando. Bons exemplos
>> disso você encontra na documentação do AnyEvent::Handle (ser ou não ser
>> assíncrono é irrelevante; é que essa documentação em especial entra em
>> detalhes bem desse nível).
>>
>> среда, 1 мая 2013 г. пользователь Tiago Peczenyj писал:
>>
>>> 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 em gmail.com>
>>>
>>> $ perl -E 'say for unpack "a a*", "hello"'
>>> h
>>> ello
>>> $
>>>
>>>
>>> ABS()
>>>
>>>
>>> 2013/4/30 Tiago Peczenyj <tiago.peczenyj em gmail.com>
>>>
>>> Nao posso resolver com unpack ???
>>> Em 30/04/2013 19:51, "Lucas Moraes" <lucastiagodemoraes em 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 em gmail.com>escreveu:
>>>
>>> Bytes!
>>>
>>> Na verdade eh algo como
>>>
>>> 09 00 AF 1D..
>>> Em 30/04/2013 19:41, "Lucas Moraes" <lucastiagodemoraes em 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 em 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 em 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 em 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 em 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 em pm.org
>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>> =end disclaimer
>>>
>>> --
>>> Tiago B. Peczenyj
>>> Linux User #405772
>>>
>>> http://about.me/peczenyj
>>>
>>
>>
>> --
>>
>> ABS()
>>
>>
>> =begin disclaimer
>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>  SaoPaulo-pm mailing list: SaoPaulo-pm em pm.org <javascript:_e({}, 'cvml',
>> 'SaoPaulo-pm em pm.org');>
>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>> =end disclaimer
>>
>>
>
>
> --
> Tiago B. Peczenyj
> Linux User #405772
>
> http://about.me/peczenyj
>


-- 

ABS()
-------------- Pr�xima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20130501/8b8f0f1a/attachment-0001.html>


More information about the SaoPaulo-pm mailing list