bug bytes

B

Bill Guindon

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?
 
M

Markus

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
 
B

Bill Guindon

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

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 ;)
 
M

Markus

I'm still hating the 'pack'
statement, so I refuse to apologise to it ;)

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.

*********************************************************************
** 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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,414
Latest member
GayleWedel

Latest Threads

Top