2016-03-28 14 views
0

Bu nedenle, bir bayt akışını ayrıştırmak için iki gen_fsm sürümü yazdım. snp dizesi ile başlayan bir paket arıyorum ve sonra p sonra sonraki 20 bayt kaydetmek istiyorum. Bu kod sadece başlığı bulmakla ilgilidir. Daha çok idiyomik Erlang veya daha iyi bir yol yazmak için tavsiyeye ihtiyacım var.Daha ne deyimsel?

Seçenek 1

parse_header({parse, Byte}, {Header, [Next | Rest]}) -> 
    case Byte of 
    Next when length(Rest) > 0 -> {next_state, parse_header, {Header, Rest}}; 
    Next when length(Rest) == 0 -> {next_state, parse_data, []}; 
    $s  -> parse_header({parse, Byte}, {Header, Header}); 
    _   -> {next_state, parse_header, {Header, Header}} 
end. 

Seçenek 2

parse_start({parse, Byte}, State) when Byte == $s -> 
    {next_state, parse_new, State}; 
parse_start({parse, Byte}, State) when Byte /= $s -> 
    {next_state, parse_start, State}. 

parse_new({parse, Byte}, State) when Byte == $n -> 
    {next_state, parse_packet, State}; 
parse_new({parse, Byte}, State) when Byte == $s -> 
    parse_start({parse, Byte}, State); 
parse_new({parse, _Byte}, State) -> 
    {next_state, parse_start, State}. 

parse_packet({parse, Byte}, State) when Byte == $p -> 
    {next_state, parse_data, State}; 
parse_packet({parse, Byte}, State) when Byte == $s -> 
    parse_start({parse, Byte}, State); 
parse_packet({parse, _Byte}, State) -> 
    {next_state, parse_start, State}. 

cevap

1

Hem uygulamaları nasıl istiyorsa gen_fsm döngü geziler minimize bir uygulama tercih etmeliyiz, gayet böylece etraflıca verileri ayrıştırır ayrıştırmak için başka bir şey kalmayıncaya kadar ve yalnızca kontrol gen_fsm'a geri verilir. Dolayısıyla, ilk uygulama bu açıdan daha iyi olacaktır. Ayrıca, daha kısa bir uygulama genellikle akılda tutulması kolaydır, bu yüzden ilk çözüm için bir nokta. Bununla birlikte, ikinci uygulama (muhtemelen) gen_fsm yaklaşımına göre daha açık ve daha iyi bir yaklaşımdır, bu yüzden gerekirse daha kolay ve uzatmak daha kolay olacaktır.

Belki her ikisinden de en iyi parçaları alan bir çözüm bulabilir misiniz? Örneğin, nasıl bir bu konuda: O etraflıca girişini okumaya çalışır ve sadece okumak için daha fazla veri varsa geri gen_fsm denetimi döner

parse_header([ $s, $n, $p | Rest]) -> copy_data(Rest, 20, []); 
parse_header([ _ | T ]) -> parse_header(T); 
parse_header(List) when length(List) < 3 -> {next_state, parse_header}. 

copy_data(_, 0, Acc) -> lists:reverse(Acc); 
copy_data([], X, Acc) -> {next_state, {copy_data, X, Acc}}; 
copy_data([H | T], X, Acc) -> copy_data(T, X - 1, [H | Acc]). 

. Ve ikinci çözümde olduğu gibi, başlığın ayrıştırılmasından veriyi okumayı ayırır.

Tabii ki bu sadece bir örneğidir, çünkü siz kodun geri kalanını ve tam gereksinimlerinizi bilmediğim için sorunun nasıl ele alınabileceğine dair bir örnek.

İlgili konular