# # Тест парсинга файлов, в которых каждая строка содержит один из следующих # тегов: # # {sent-sms {timestamp <str>} {cprov <str>} {trx-id <str>} {op-id <str>} {msisdn <str>} {message-id <str>} } # {incoming-sms {timestamp <str>} {op-id <str>} {msisdn <str>} {dest-addr <str>} {trx-id <str>} } # {routed {timestamp <str>} {op-id <str>} {trx-id <str>} {recipient-trx-id <str>} {cprov <str>} } # {delivery-receipt {timestamp <str>} {op-id <str>} {message-id <str>} {status <uint>} {trx-id <str>} } # # Каждый тег обязательно записывается в одну строку -- это механизм защиты от # сбоев при записи файла -- если строка записана не полностью, то она просто # игнорируется при чтении. # # Пример считывает все строки из ARGF и: # * подсчитывает общее количество строк; # * подсчитывает количество строк с каждым из типов тегов. # require 'cls-ruby' require 'cls-ruby/tag_no_value' require 'cls-ruby/tag_scalar' # Класс тега SentSms. class TagSentSms < ClsRuby::TagNoValue mandatory_child_tag :timestamp, ClsRuby::TagStringScalar mandatory_child_tag :cprov, ClsRuby::TagStringScalar mandatory_child_tag :trx_id, ClsRuby::TagStringScalar, :name => 'trx-id' mandatory_child_tag :op_id, ClsRuby::TagStringScalar, :name => 'op-id' mandatory_child_tag :msisdn, ClsRuby::TagStringScalar mandatory_child_tag :message_id, ClsRuby::TagStringScalar, :name => 'message-id' default_tag_params :name => 'sent-sms' end # Класс тега incoming-sms. class TagIncomingSms < ClsRuby::TagNoValue mandatory_child_tag :timestamp, ClsRuby::TagStringScalar mandatory_child_tag :trx_id, ClsRuby::TagStringScalar, :name => 'trx-id' mandatory_child_tag :op_id, ClsRuby::TagStringScalar, :name => 'op-id' mandatory_child_tag :msisdn, ClsRuby::TagStringScalar mandatory_child_tag :dest_addr, ClsRuby::TagStringScalar, :name => 'dest-addr' default_tag_params :name => 'incoming-sms' end # Класс тега routed. class TagRoutedSms < ClsRuby::TagNoValue mandatory_child_tag :timestamp, ClsRuby::TagStringScalar mandatory_child_tag :trx_id, ClsRuby::TagStringScalar, :name => 'trx-id' mandatory_child_tag :op_id, ClsRuby::TagStringScalar, :name => 'op-id' mandatory_child_tag :recipient_trx_id, ClsRuby::TagStringScalar, :name => 'recipient-trx-id' mandatory_child_tag :cprov, ClsRuby::TagStringScalar default_tag_params :name => 'routed' end # Класс тега delivery-receipt. class TagDeliveryReceipt < ClsRuby::TagNoValue mandatory_child_tag :timestamp, ClsRuby::TagStringScalar mandatory_child_tag :trx_id, ClsRuby::TagStringScalar, :name => 'trx-id' mandatory_child_tag :op_id, ClsRuby::TagStringScalar, :name => 'op-id' mandatory_child_tag :message_id, ClsRuby::TagStringScalar, :name => 'message-id' mandatory_child_tag :status, ClsRuby::TagUintScalar default_tag_params :name => 'delivery-receipt' end class LineParser attr_reader :stats def initialize @stats = { :lines => 0, :processed => 0, :sent => 0, :incoming => 0, :routed => 0, :delivery => 0 } @tag_sent = TagSentSms.new( {} ) @tag_incoming = TagIncomingSms.new( {} ) @tag_routed = TagRoutedSms.new( {} ) @tag_delivery = TagDeliveryReceipt.new( {} ) @all_tags = [ @tag_sent, @tag_incoming, @tag_routed, @tag_delivery ] @tags_and_stats_keys = { :sent => @tag_sent, :incoming => @tag_incoming, :routed => @tag_routed, :delivery => @tag_delivery } end def next_line( line ) @stats[ :lines ] += 1 begin ClsRuby::parse_string( line, *@all_tags ) @stats[ :processed ] += 1 detect_defined_tag rescue Exception => x $stderr.puts "Exception caught: #{x.message}\n" + "Stacktrace:\n" + '-'*30 + "\n#{x.backtrace.join("\n")}\n" + '-'*30 + "\n" + "Problematic line (number #{@stats[:lines]}):\n" + line # В случае ошибки мы не знаем, какой именно тег разбирался, # поэтому операцию reset нужно вызывать для всех тегов. @all_tags.each do |tag| tag.tag_reset end end end private def detect_defined_tag @tags_and_stats_keys.each_pair do |key, tag| if tag.tag_defined? @stats[ key ] += 1 tag.tag_reset break end end end end parser = LineParser.new ARGF.each do |line| parser.next_line( line ) end p parser.stats
# vim:ts=2:sts=2:sw=2:expandtab:ft=txt:tw=78
Generated with the Darkfish Rdoc Generator 2.