[SP-pm] Separar o primeiro do resto

Tiago Peczenyj tiago.peczenyj at gmail.com
Wed May 1 17:29:27 PDT 2013


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 at 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 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
>>
>> --
>> 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 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/6497eebb/attachment-0001.html>


More information about the SaoPaulo-pm mailing list