Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117885267
eimap_command.erl
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
5 KB
Referenced Files
None
Subscribers
None
eimap_command.erl
View Options
-
module
(
eimap_command
).
-
export
([
parse_response
/
4
,
formulate_response
/
2
,
process_status_line
/
2
]).
-
type
more_tuple
()
::
{
more
,
ParseContinuation
::
parse_continuation
(),
State
::
term
}.
-
type
finished_tuple
()
::
{
fini
,
Results
::
term
}.
-
type
error_tuple
()
::
{
error
,
Reason
::
binary
()
}.
-
type
parse_continuation
()
::
fun
((
Data
::
binary
(),
Tag
::
binary
(),
State
::
term
())
->
more_tuple
()
|
finished_tuple
()
|
error_tuple
()).
-
callback
new_command
(
Args
::
any
())
->
{
binary
(),
single_line_response
|
multiline_reponse
|
blob_response
}.
% TODO:bring back when we can depend on OTP 18 which introduced optional_callback
% also define parse/2 (for blob_response), formulate_response/2
%-callback process_line(Data :: binary(), Acc :: any()) ->
% more_tuple() | finished_tuple() | error_tuple() | starttls.
parse_response
(
multiline_response
,
Data
,
Tag
,
ParseState
)
->
multiline_parse
(
false
,
Data
,
Tag
,
ParseState
);
parse_response
(
all_multiline_response
,
Data
,
Tag
,
ParseState
)
->
multiline_parse
(
parse_tagged
,
Data
,
Tag
,
ParseState
);
parse_response
(
single_line_response
,
Data
,
Tag
,
Module
)
->
Module
:
formulate_response
(
Data
,
Tag
);
parse_response
(
blob_response
,
Data
,
Tag
,
{
Continuation
,
ParseState
})
->
Continuation
(
Data
,
Tag
,
ParseState
);
parse_response
(
blob_response
,
Data
,
Tag
,
Module
)
->
case
Module
:
parse
(
Data
,
Tag
)
of
{
more
,
Continuation
,
ParseState
}
->
{
more
,
{
Continuation
,
ParseState
}
};
Response
->
Response
end
.
multiline_parse
(
ParseTaggedLine
,
Data
,
Tag
,
{
LastPartialLine
,
Acc
,
Module
})
->
FullBuffer
=
<<
LastPartialLine
/
binary
,
Data
/
binary
>>
,
{
FullLinesBuffer
,
NewLastPartialLine
}
=
eimap_utils
:
only_full_lines
(
FullBuffer
),
Lines
=
binary
:
split
(
FullLinesBuffer
,
<<
"
\r\n
"
>>
,
[
global
]),
process_lines
(
ParseTaggedLine
,
Tag
,
NewLastPartialLine
,
Lines
,
Acc
,
Module
);
multiline_parse
(
ParseTaggedLine
,
Data
,
Tag
,
Module
)
->
multiline_parse
(
ParseTaggedLine
,
Data
,
Tag
,
{
<<>>
,
[],
Module
}).
process_lines
(_
ParseTaggedLine
,
_
Tag
,
LastPartialLine
,
[],
Acc
,
Module
)
->
{
more
,
{
LastPartialLine
,
Acc
,
Module
}
};
process_lines
(
ParseTaggedLine
,
Tag
,
LastPartialLine
,
[
Line
|
MoreLines
],
Acc
,
Module
)
->
{
FirstLine
,
ContinuationBytes
}
=
eimap_utils
:
num_literal_continuation_bytes
(
Line
),
process_line
(
ContinuationBytes
,
ParseTaggedLine
,
eimap_utils
:
is_tagged_response
(
FirstLine
,
Tag
),
Tag
,
LastPartialLine
,
FirstLine
,
MoreLines
,
Acc
,
Module
).
process_line
(
ContinuationBytes
,
ParseTaggedLine
,
IsTagged
,
Tag
,
LastPartialLine
,
Line
,
[
<<>>
|
MoreLines
],
Acc
,
Module
)
->
%% skip empty lines
process_line
(
ContinuationBytes
,
ParseTaggedLine
,
IsTagged
,
Tag
,
LastPartialLine
,
Line
,
MoreLines
,
Acc
,
Module
);
process_line
(
0
,
ParseTaggedLine
,
tagged
,
Tag
,
_
LastPartialLine
,
Line
,
_
MoreLines
,
Acc
,
Module
)
->
Checked
=
eimap_utils
:
check_response_for_failure
(
Line
,
Tag
),
Module
:
formulate_response
(
Checked
,
parse_tagged
(
Checked
,
ParseTaggedLine
,
Line
,
Acc
,
Module
));
process_line
(
0
,
ParseTaggedLine
,
untagged
,
Tag
,
LastPartialLine
,
Line
,
MoreLines
,
Acc
,
Module
)
->
%io:format("Calling it here with ~p~n~n...", [Line]),
process_lines
(
ParseTaggedLine
,
Tag
,
LastPartialLine
,
MoreLines
,
Module
:
process_line
(
Line
,
Acc
),
Module
);
process_line
(
ContinuationBytes
,
ParseTaggedLine
,
_
IsTagged
,
Tag
,
LastPartialLine
,
Line
,
[],
Acc
,
Module
)
->
%% the line was continued, but there is no more lines ... so this line is now our last partial line. more must be on its way
io
:
format
(
"Missing lines!
~p~n~n
"
,
[
Acc
]),
BytesAsBinary
=
integer_to_binary
(
ContinuationBytes
),
process_lines
(
ParseTaggedLine
,
Tag
,
<<
Line
/
binary
,
${
,
BytesAsBinary
/
binary
,
$}
,
LastPartialLine
/
binary
>>
,
[],
Acc
,
Module
);
process_line
(_
ContinuationBytes
,
ParseTaggedLine
,
IsTagged
,
Tag
,
LastPartialLine
,
Line
,
[
NextLine
|
MoreLines
],
Acc
,
Module
)
->
{
StrippedNextLine
,
NextContinuationBytes
}
=
eimap_utils
:
num_literal_continuation_bytes
(
NextLine
),
io
:
format
(
"Connected up the next line:
~p
~i~n
"
,
[
StrippedNextLine
,
NextContinuationBytes
]),
FullLine
=
<<
Line
/
binary
,
StrippedNextLine
/
binary
>>
,
process_line
(
NextContinuationBytes
,
ParseTaggedLine
,
IsTagged
,
Tag
,
LastPartialLine
,
FullLine
,
MoreLines
,
Acc
,
Module
).
formulate_response
(
ok
,
Data
)
->
{
fini
,
Data
};
formulate_response
({
_,
Reason
},
_
Data
)
->
{
error
,
Reason
}.
parse_tagged
(_,
false
,
_
Line
,
Acc
,
_
Module
)
->
Acc
;
% we are not passing the tagged line forward (no content, e.g)
parse_tagged
(
ok
,
_,
Line
,
Acc
,
Module
)
->
Module
:
process_tagged_line
(
Line
,
Acc
);
% success, so pass it forward
parse_tagged
(_
Checked
,
_
ParsedTaggedLine
,
_
Line
,
Acc
,
_
Module
)
->
Acc
.
% error, don't bother passing it forward
-
spec
process_status_line
(
Line
::
binary
(),
Acc
::
list
())
->
NewAcc
::
list
().
process_status_line
(
<<
"* "
,
Rest
/
binary
>>
,
Acc
)
->
process_matched_status_line
(
binary
:
split
(
Rest
,
<<
" "
>>
,
[
global
]),
Acc
);
process_status_line
(_,
Acc
)
->
Acc
.
process_matched_status_line
([
Number
,
Key
|_],
Acc
)
->
[{
eimap_utils
:
binary_to_atom
(
Key
),
binary_to_integer
(
Number
)
}|
Acc
];
process_matched_status_line
(_,
Acc
)
->
Acc
.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 6, 1:57 AM (1 w, 7 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18825356
Default Alt Text
eimap_command.erl (5 KB)
Attached To
Mode
rEI eimap
Attached
Detach File
Event Timeline