sub
anyevent_read_type {
my
(
$handle
,
$cb
) =
@_
;
return
sub
{
$handle
->push_read(
line
=>
sub
{
my
$line
=
$_
[1];
my
$type
=
substr
(
$line
, 0, 1);
my
$value
=
substr
(
$line
, 1);
if
(
$type
eq
'*'
) {
my
$remaining
=
$value
;
if
(
$remaining
== 0) {
$cb
->([]);
}
elsif
(
$remaining
== -1) {
$cb
->(
undef
);
}
else
{
my
$results
= [];
$handle
->unshift_read(
sub
{
my
$need_more_data
= 0;
do
{
if
(
$handle
->{rbuf} =~ /^(\$(-?\d+)\015\012)/) {
my
(
$match
,
$vallen
) = ($1, $2);
if
(
$vallen
== -1) {
substr
(
$handle
->{rbuf}, 0,
length
(
$match
),
''
);
push
@$results
,
undef
;
unless
(--
$remaining
) {
$cb
->(
$results
);
return
1;
}
}
elsif
(
length
$handle
->{rbuf} >= (
length
(
$match
) +
$vallen
+ 2)) {
substr
(
$handle
->{rbuf}, 0,
length
(
$match
),
''
);
my
$value
=
substr
(
$handle
->{rbuf}, 0,
$vallen
,
''
);
$value
=
$handle
->{encoding}->decode(
$value
)
if
$handle
->{encoding} &&
$vallen
;
push
@$results
,
$value
;
substr
(
$handle
->{rbuf}, 0, 2,
''
);
unless
(--
$remaining
) {
$cb
->(
$results
);
return
1;
}
}
else
{
$need_more_data
= 1;
}
}
elsif
(
$handle
->{rbuf} =~ s/^([\+\-:])([^\015\012]*)\015\012//) {
my
(
$type
,
$value
) = ($1, $2);
if
(
$type
eq
'+'
||
$type
eq
':'
) {
push
@$results
,
$value
;
}
elsif
(
$type
eq
'-'
) {
push
@$results
,
bless
\
$value
,
'AnyEvent::Redis::Error'
;
}
unless
(--
$remaining
) {
$cb
->(
$results
);
return
1;
}
}
elsif
(
substr
(
$handle
->{rbuf}, 0, 1) eq
'*'
) {
my
$reader
;
$reader
=
sub
{
$handle
->unshift_read(
"AnyEvent::Redis::Protocol"
=>
sub
{
push
@$results
,
$_
[0];
if
(--
$remaining
) {
$reader
->();
}
else
{
undef
$reader
;
$cb
->(
$results
);
}
});
};
$reader
->();
return
1;
}
else
{
$need_more_data
= 1;
}
}
until
$need_more_data
;
return
;
});
}
}
elsif
(
$type
eq
'+'
||
$type
eq
':'
) {
$cb
->(
$value
);
}
elsif
(
$type
eq
'-'
) {
$cb
->(
$value
, 1);
}
elsif
(
$type
eq
'$'
) {
my
$length
=
$value
;
if
(
$length
== -1) {
$cb
->(
undef
);
}
else
{
$handle
->unshift_read(
chunk
=>
$length
+ 2,
sub
{
my
$data
=
$_
[1];
my
$value
=
substr
(
$data
, 0,
$length
);
$value
=
$handle
->{encoding}->decode(
$value
)
if
$handle
->{encoding} &&
$length
;
$cb
->(
$value
);
});
}
}
return
1;
});
return
1;
};
}
1;