Bug bytes

for starters, I have my cheesy little debugger, forgive the globals, I
was too lazy to make it a class (yes, really, that lazy! yes, I know,
I just typed more than it would've taken).

It works wonderfully tho', output below...

# just a debugging toy atm.
$hex_idx = 0
def show_hex(val)
  val.each_byte do |byte|
    print "%02x ".upcase % byte
    $hex_idx += 1
    print " " if $hex_idx == 8
    if $hex_idx == 16
      print "\n"
      $hex_idx = 0
    end
  end
end

Here's what it shows (which is exactly what I need):
44 45 53 43 00 00 00 00 00 00 00 4D 00 00 00 00
0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      ^^

But this is what ends up in the file:
44 45 53 43 00 00 00 00 00 00 00 4D 00 00 00 00
0D 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      ^^

after beating my brains out on this, I think I see the problem, but
not the solution.

The value that I'm packing is a FixNum
I'm using pack("c") which converts it to the '0D' that I need.
Printing with an @file_name.print statement to a file that's opened
with .binmode
I'm doing this on Win32
'0D' is 13 (aka CR)

Either Windows (most likely) or Ruby (less likely, but possible) is
generously converting my perfect little '0D' to an incredibly annoying
'0D 0A' (aka CR LF)

any suggestions? Should I convert this somehow, and use a different
pack spec to avoid this problem?

···

--
Bill Guindon (aka aGorilla -- who's just a _little_ tired of 'pack')

Bill --

     In addition to the code for hex dumping you just posted (which I
gather is working as you'd like it to) could you post the code that
_isn't_ working the way you want? Specifically, it might be instructive
to see how the file is opened, set to binmode, written to, reread, and
dumped, since any of these may be the source of the problem.

     Also:

      * Are you setting "$\"?
      * Are you using print (not puts)?
      * Have you tried using syswrite instead (if you try it, be sure to
        change _all_ writes to the file, since (IIRC) it is unbuffered).
      * Have you tried using write?

        -- Markus

···

On Sat, 2004-09-18 at 20:21, Bill Guindon wrote:

for starters, I have my cheesy little debugger, forgive the globals, I
was too lazy to make it a class (yes, really, that lazy! yes, I know,
I just typed more than it would've taken).

It works wonderfully tho', output below...

# just a debugging toy atm.
$hex_idx = 0
def show_hex(val)
  val.each_byte do |byte|
    print "%02x ".upcase % byte
    $hex_idx += 1
    print " " if $hex_idx == 8
    if $hex_idx == 16
      print "\n"
      $hex_idx = 0
    end
  end
end

Here's what it shows (which is exactly what I need):
44 45 53 43 00 00 00 00 00 00 00 4D 00 00 00 00
0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      ^^

But this is what ends up in the file:
44 45 53 43 00 00 00 00 00 00 00 4D 00 00 00 00
0D 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      ^^

after beating my brains out on this, I think I see the problem, but
not the solution.

The value that I'm packing is a FixNum
I'm using pack("c") which converts it to the '0D' that I need.
Printing with an @file_name.print statement to a file that's opened
with .binmode
I'm doing this on Win32
'0D' is 13 (aka CR)

Either Windows (most likely) or Ruby (less likely, but possible) is
generously converting my perfect little '0D' to an incredibly annoying
'0D 0A' (aka CR LF)

any suggestions? Should I convert this somehow, and use a different
pack spec to avoid this problem?

Turns out I was wrong... it lacked the (very important for Win) .binmode
Seems I lost it while refactoring, when added back, one of my many
test files had the correct field specs, and was able to save data.

My apologies for the false alarm -- but I'm still hating the 'pack'
statement, so I refuse to apologise to it :wink:

···

On Sun, 19 Sep 2004 12:45:56 +0900, Markus <markus@reality.com> wrote:

Bill --

     In addition to the code for hex dumping you just posted (which I
gather is working as you'd like it to) could you post the code that
_isn't_ working the way you want? Specifically, it might be instructive
to see how the file is opened, set to binmode, written to, reread, and
dumped, since any of these may be the source of the problem.

     Also:

      * Are you setting "$\"?
      * Are you using print (not puts)?
      * Have you tried using syswrite instead (if you try it, be sure to
        change _all_ writes to the file, since (IIRC) it is unbuffered).
      * Have you tried using write?

        -- Markus

--
Bill Guindon (aka aGorilla)

I suppose writing a wrapper of some sort doesn't work for you? For
example, when I had to read & write some Pascal records (native format
binary goo) I wrote a little thing that I stuck in "module Module"
(IIRC) to define the fields, and get_record and put_record methods that
schleped the data to/from the format, and forgot about the internals as
quickly as I could.

     A quick check just now failed to turn up the code, but I can sketch
it.

···

On Sat, 2004-09-18 at 21:05, Bill Guindon wrote:

I'm still hating the 'pack'
statement, so I refuse to apologise to it :wink:

*********************************************************************
** WARNING: THE FOLLOWING CODE HAS BEEN TYPED FROM MEMORY BY SOMEONE
** WHO SHOULD HAVE GONE TO BED SEVERAL HOURS AGO.
*********************************************************************

      * Add something that looks something like
        
        $packing_formats = {
            :integer => 'i',
            :real => 'f',
            --etc, to suit
            }
        class Module
            #
            # To automate the reading and writing of objects
            #
            def columns
                @columns ||=
                end
            def pack_format
                @pack_format ||= ''
                end
            private
                def field(id,type)
                    @columns ||=
                    id = id.to_s
                    attr_accessor id unless
                       instances_respond_to? id+'='
                    @columns << id
                    @pack_format = pack_format + $packing_formats[type]
                    end
            end
        
      * then define a pack/unpack methods something like
        
        class Object
            def pack
                self.class.fields.collect { |field|
                    self.send(field)
                    }.pack(self.class.pack_format)
                end
            def unpack(s)
                v = s.unpack(self.class.pack_format)
                self.class.fields.each { |field|
                    self.send(field+'=',v.shift)
                    }
                end
            end
        
      * look into the pen with the bright red light and forget about how
        it works. Use "field" instead of "attr_accessor" when defining
        objects that need to match external record formats

IIRC, the version I wrote for myself wound up having another level of
abstraction that made it look like an SQL-based object persistence
interface that was in use in the same program. Then as the data storage
back-end got cleaned up it shriveled up and eventually blew away.

-- MarkusQ