Class: RCS::AddressBookSerializer

Inherits:
Object
  • Object
show all
Includes:
Tracer
Defined in:
lib/rcs-common/serializer.rb

Overview

CalendarSerializer

Constant Summary collapse

POOM_V1_0_PROTO =
0x01000000
POOM_V2_0_PROTO =
0x01000001
LOCAL_CONTACT =
0x80000000
ADDRESSBOOK_TYPES =
{ 0x1 => :first_name,
0x2 => :last_name,
0x3 => :company,
0x4 => :business_fax_number,
0x5 => :department,
0x6 => :email_1,
0x7 => :mobile_phone_number,
0x8 => :office_location,
0x9 => :pager_number,
0xA => :business_phone_number,
0xB => :job_title,
0xC => :home_phone_number,
0xD => :email_2,
0xE => :spouse,
0xF => :email_3,
0x10 => :home_2_phone_number,
0x11 => :home_fax_number,
0x12 => :car_phone_number,
0x13 => :assistant_name,
0x14 => :assistant_phone_number,
0x15 => :children,
0x16 => :categories,
0x17 => :web_page,
0x18 => :business_2_phone_number,
0x19 => :radio_phone_number,
0x1A => :file_as,
0x1B => :yomi_company_name,
0x1C => :yomi_first_name,
0x1D => :yomi_last_name,
0x1E => :title,
0x1F => :middle_name,
0x20 => :suffix,
0x21 => :home_address_street,
0x22 => :home_address_city,
0x23 => :home_address_state,
0x24 => :home_address_postal_code,
0x25 => :home_address_country,
0x26 => :other_address_street,
0x27 => :other_address_city,
0x28 => :other_address_postal_code,
0x29 => :other_address_country,
0x2A => :business_address_street,
0x2B => :business_address_city,
0x2C => :business_address_state,
0x2D => :business_address_postal_code,
0x2E => :business_address_country,
0x2F => :other_address_state,
0x30 => :body,
0x31 => :birthday,
0x32 => :anniversary,
0x33 => :screen_name,
0x34 => :phone_numbers,
0x35 => :address,
0x36 => :notes,
0x37 => :unknown,
0x38 => :facebook_page,
0x40 => :handle}
ADDRESSBOOK_PROGRAM =
{
    0x01 => :outlook,
    0x02 => :skype,
    0x03 => :facebook,
    0x04 => :twitter,
    0x05 => :gmail,
    0x06 => :bbm,
    0x07 => :whatsapp,
    0x08 => :phone,
    0x09 => :mail,
    0x0a => :linkedin,
    0x0b => :viber,
    0x0c => :wechat,
    0x0d => :line,
    0x0e => :telegram,
    0x0f => :yahoo,
    0x10 => :messages,
    0x11 => :contacts
}
TYPE_FLAGS =
{
    twitter: {0x00 => :friend, 0x01 => :follower}
}

Constants included from Tracer

Tracer::TRACE_YAML_NAME

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Tracer

#thread_name, #trace, #trace_ensure_log_folders, #trace_init, #trace_named_put, #trace_named_remove, #trace_nested_pop, #trace_nested_push, #trace_setup

Constructor Details

#initializeAddressBookSerializer

Returns a new instance of AddressBookSerializer.



300
301
302
303
304
305
306
307
308
# File 'lib/rcs-common/serializer.rb', line 300

def initialize
  @fields = {}
  @handles = []
  @poom_strings = {}
  ADDRESSBOOK_TYPES.each_pair do |k, v|
    @poom_strings[v] = v.to_s.gsub(/_/, " ").capitalize.encode('UTF-8')
  end
  @poom_strings[:unknown] = nil # when unknown, field name is given by agent
end

Instance Attribute Details

#contactObject (readonly)

Returns the value of attribute contact.



211
212
213
# File 'lib/rcs-common/serializer.rb', line 211

def contact
  @contact
end

#handlesObject (readonly)

Returns the value of attribute handles.



211
212
213
# File 'lib/rcs-common/serializer.rb', line 211

def handles
  @handles
end

#infoObject (readonly)

Returns the value of attribute info.



211
212
213
# File 'lib/rcs-common/serializer.rb', line 211

def info
  @info
end

#nameObject (readonly)

Returns the value of attribute name.



211
212
213
# File 'lib/rcs-common/serializer.rb', line 211

def name
  @name
end

#programObject (readonly)

Returns the value of attribute program.



211
212
213
# File 'lib/rcs-common/serializer.rb', line 211

def program
  @program
end

#typeObject (readonly)

Returns the value of attribute type.



211
212
213
# File 'lib/rcs-common/serializer.rb', line 211

def type
  @type
end

Instance Method Details

#add_to_handles(key, value) ⇒ Object



396
397
398
399
400
401
# File 'lib/rcs-common/serializer.rb', line 396

def add_to_handles(key, value)
  # only take the phones and mails
  return if key['phone'].nil? and key['mail'].nil?
  @handles << {type: 'phone', handle: value} if key['phone']
  @handles << {type: 'mail', handle: value} if key['mail']
end

#serialize(fields) ⇒ Object



310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/rcs-common/serializer.rb', line 310

def serialize(fields)
  stream = StringIO.new
  fields.each_pair do |type, str|
    utf16le_str = str.to_utf16le_binary_null
    stream.write Serialization.prefix(ADDRESSBOOK_TYPES.invert[type], utf16le_str.bytesize)
    stream.write utf16le_str
  end
  header = [stream.pos + 20, POOM_V2_0_PROTO, 0].pack('L*')
  header += [ADDRESSBOOK_PROGRAM.invert[:contacts], [0, LOCAL_CONTACT].sample].pack('L*')

  return header + stream.string
end

#unserialize(stream) ⇒ Object



323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
# File 'lib/rcs-common/serializer.rb', line 323

def unserialize(stream)

  header_begin = stream.pos

  # discard header
  tot_size = stream.read(4).unpack("L").shift
  version = stream.read(4).unpack("L").shift
  oid = stream.read(4).unpack("L").shift

  if version != POOM_V1_0_PROTO and version != POOM_V2_0_PROTO
    raise EvidenceDeserializeError.new("Invalid addressbook version (#{version})")
  end

  case version
    when POOM_V1_0_PROTO
      program = 0
      flags = 0
    when POOM_V2_0_PROTO
      program = stream.read(4).unpack("L").shift
      flags = stream.read(4).unpack("L").shift
  end

  # initialize the values to array
  @fields = Hash.new {|h,k| h[k] = []}

  # BODY
  header_length = stream.pos - header_begin
  content = stream.read(tot_size - header_length)
  until content.empty?
    type, size = Serialization.decode_prefix content.slice!(0, 4)
    str = content.slice!(0, size).utf16le_to_utf8
    #trace :debug, "ADDRESSBOOK FIELD #{ADDRESSBOOK_TYPES[type]} = #{str}"
    @fields[ADDRESSBOOK_TYPES[type]] << str if ADDRESSBOOK_TYPES.has_key? type
  end

  # name
  @name = ""
  @name = @fields[:first_name].first if @fields.has_key? :first_name
  @name += " " + @fields[:last_name].first if @fields.has_key? :last_name

  @program = ADDRESSBOOK_PROGRAM[program]
  @program ||= :unknown

  @type = TYPE_FLAGS[@program][flags] if TYPE_FLAGS.has_key? @program
  @type ||= :peer
  @type = :target if (flags & LOCAL_CONTACT != 0)

  # choose the most significant contact field (the handle)
  @contact = ""
  if @fields.has_key? :handle
    @contact = @fields[:handle].first
    @handles << {type: @program, handle: @fields[:handle].first}
  end

  #trace :debug, "FIELDS: #{@fields.inspect}"

  # info
  @info = ""
  omitted_fields = [:first_name, :last_name, :body, :file_as]
  @fields.each_pair do |k, v|
    next if omitted_fields.include? k
    v.each do |entry|
      str = @poom_strings[k]
      add_to_handles(str, entry) if str and entry
      @info += str.nil? ? "" : "#{str}: "
      @info += entry
      @info += "\n"
    end
  end

  self
end