This time I'm trying to write a binary file.

Q1: why does the structure MRKMessageFlags does not get the apropriate 
values?

Q2: how do I convert a date to seconds-since-1970?

require 'bit-struct'
class MRKHeader < BitStruct
    unsigned :version,            32, "Version",          :endian => 
:native
    unsigned :uid_Validity,       32, "UIDValidity",      :endian => 
:native
    unsigned :uid_next,           32, "UIDNext",          :endian => 
:native
    unsigned :last_write_counter, 32, "LastWriteCounter", :endian => 
:native
    rest     :unused,             "Unused"
    # Override so that it gets padded properly
    def MRKHeader.round_byte_length
      super
      36
    end
end

# Ideally, I'd construct some sort of "flags" bit-struct field
# Or define a boolean field type and make this a series of boolean
# fields.

# However, for now we can deal with a series of 0s and 1s

class MRKMessageFlags < BitStruct
  unsigned :flagUnused,   2, "Unused"
  unsigned :flagSeen,     1, "Seen"
  unsigned :flagAnswered, 1, "Answered"
  unsigned :flagFlagged,  1, "Flagged"
  unsigned :flagDeleted,  1, "Deleted"
  unsigned :flagDraft,    1, "Draft"
  unsigned :flagRecent,   1, "Recent"
end

class MRKMessage < BitStruct
  # Note "text" for nul-terminated strings
  text      :filename,  23*8, "FileName", :endian => :native
  nest      :flags,     MRKMessageFlags, "Flags"
  unsigned  :uid,       32,   "UID",      :endian => :native
  unsigned  :msg_size,  32,   "MsgSize",  :endian => :native
  unsigned  :date,      32,   "Date",     :endian => :native

  # Now we futz with the way that date is set and gotten.
  # we rename the existing date field to __date, and
  # then we supply our own meaning for "date" that does
  # translation into and out of seconds-since-1970

  # Again, the ideal solution would be to define a new bit-struct
  # field type that did this stuff itself.

  alias_method :__date=, :date=
  alias_method :__date, :date
  def date=(time)
    self.__date= time.to_i
  end
  def date
    Time.at(self.__date)
  end
  # we don't need to override the length computation here
end

File.open("imap2.mrk", "wb") {|f|
#<MRKHeader version=1, uid_Validity=1106138982, uid_next=5887, 
last_write_counter=9962, 
unused="\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\r\n">

  mrk_header = MRKHeader.new()
  mrk_header.version = 1
  mrk_header.uid_Validity = 1106138982
  mrk_header.uid_next = 5887
  mrk_header.last_write_counter = 9962
  mrk_header.unused = 
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\r\n"
  puts mrk_header.inspect

  msg = MRKMessage.new()
  msg.filename = "md50000006021.msg"

  msg.flags.flagSeen      = 1
  msg.flags.flagAnswered  = 0
  msg.flags.flagFlagged   = 1
  msg.flags.flagDeleted   = 0
  msg.flags.flagDraft     = 0
  msg.flags.flagRecent    = 0
  puts msg.flags.inspect

  msg.uid = 5885
  msg.msg_size = 4184
  msg.date = "Mon Jul 24 12:34:04 2006"

  puts MRKMessage.new(msg).inspect
}

-- 
Posted via http://www.ruby-forum.com/.