diff options
author | Alexey Shchepin <alexey@process-one.net> | 2002-11-18 20:39:47 +0000 |
---|---|---|
committer | Alexey Shchepin <alexey@process-one.net> | 2002-11-18 20:39:47 +0000 |
commit | e0b348319ad6902ffcbb663e81c29b229c551b61 (patch) | |
tree | 22d6117a353d510f2dd6aa5569ae82a324454e24 /src/xml_stream.erl | |
parent | New repository initialized by cvs2svn. (diff) |
Initial revision
SVN Revision: 2
Diffstat (limited to 'src/xml_stream.erl')
-rw-r--r-- | src/xml_stream.erl | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/xml_stream.erl b/src/xml_stream.erl new file mode 100644 index 000000000..b21ae13c0 --- /dev/null +++ b/src/xml_stream.erl @@ -0,0 +1,77 @@ +%%%---------------------------------------------------------------------- +%%% File : xml_stream.erl +%%% Author : Alexey Shchepin <alexey@sevcom.net> +%%% Purpose : +%%% Created : 17 Nov 2002 by Alexey Shchepin <alexey@sevcom.net> +%%% Id : $Id$ +%%%---------------------------------------------------------------------- + +-module(xml_stream). +-author('alexey@sevcom.net'). +-vsn('$Revision$ '). + +-export([start/1, init/1, send_text/2]). + +start(CallbackPid) -> + spawn(?MODULE, init, [CallbackPid]). + +init(CallbackPid) -> + ok = erl_ddll:load_driver(".", expat_erl), + Port = open_port({spawn, expat_erl}, [binary]), + loop(CallbackPid, Port, []). + +loop(CallbackPid, Port, Stack) -> + receive + {Port, {data, Bin}} -> + %CallbackPid ! binary_to_term(Bin), + Data = binary_to_term(Bin), + loop(CallbackPid, Port, process_data(CallbackPid, Stack, Data)); + {From, {send, Str}} -> + Port ! {self(), {command, Str}}, + loop(CallbackPid, Port, Stack) + end. + +process_data(CallbackPid, Stack, Data) -> + case Data of + {xmlstart, {Name, Attrs}} -> + if Stack == [] -> + gen_fsm:send_event(CallbackPid, + {xmlstreamstart, Name, Attrs}); + true -> true + end, + [{xmlelement, Name, Attrs, []} | Stack]; + {xmlend, EndName} -> + case Stack of + [{xmlelement, Name, Attrs, Els} | Tail] -> + NewEl = {xmlelement, Name, Attrs, lists:reverse(Els)}, + Len = length(Tail), + if + Len > 1 -> add_subelement(NewEl, Tail); + Len == 1 -> + gen_fsm:send_event(CallbackPid, + {xmlstreamelement, NewEl}), + Tail; + Len == 0 -> + gen_fsm:send_event(CallbackPid, + {xmlstreamend, EndName}), + Tail + end + end; + {xmlcdata, CData} -> + add_subelement({xmlcdata, CData}, Stack); + {xmlerror, Err} -> gen_fsm:send_event(CallbackPid, + {xmlstreamerror, Err}) + end. + + +add_subelement(El, Stack) -> + case Stack of + [{xmlelement, Name, Attrs, Els} | Tail] -> + [{xmlelement, Name, Attrs, [El | Els]} | Tail]; + [] -> [] + end. + + +send_text(Pid, Text) -> + Pid ! {self(), {send, Text}}. + |