From: Fabio Vitale Date: 2006-07-24T23:06:44+09:00 Subject: Re: How can I parse binary files? 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| # 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/.