I am trying to do some parsing of binary data.
Here is the psuedo code that parses what i'm looking for:
private int readInteger() throws IOException {
int n = 0;
int b = in.readUnsignedByte();
int result = 0;
while ((b & 0x80) != 0 && n < 3) {
result <<= 7;
result |= (b & 0x7f);
b = in.readUnsignedByte();
n++;
}
if (n < 3) {
result <<= 7;
result |= b;
} else {
/* Use all 8 bits from the 4th byte */
result <<= 8;
result |= b;
/* Check if the integer should be negative */
if ((result & 0x10000000) != 0) {
/* and extend the sign bit */
result |= 0xe0000000;
}
}
return result;
}
Here is how I wrote it with Ruby:
def read_int
n = 0;
b = @input_stream.read_special(1,'C')
result = 0
while((b & 0x80) != 0 && n < 3)
result <<= 7
result |= (b & 0x7f)
b = @input_stream.read_special(1,'C')
n = n + 1
end
if (n < 3)
result <<= 7
result |= b
else
# Use all 8 bits from the 4th byte
result <<= 8
result |= b
#Check if the integer should be negative
if ((result & 0x10000000) != 0)
# and extend the sign bit
result |= 0xe0000000
end
end
STDOUT.puts "READ INT: #{result}"
return result
end
When translating the Pseudo Code to PHP, it's verbatim except for
syntax. With ruby, I think i've found the problem with it not parsing
correclty. the |= operator. With PHP
$i |= 0xe0000000; //= -536870912
Now with Ruby:
i |= 0xe000000 #= true
Any ideas on a solution?
thanks.
···
--
Posted via http://www.ruby-forum.com/.
Errm, how about providing some evidence for that claim?
irb(main):010:0> 5 | 3
=> 7
irb(main):011:0> i = 0
=> 0
irb(main):012:0> i |= 0xe000000
=> 234881024
···
On Thu, Mar 08, 2007 at 01:36:38PM +0900, Aaron Smith wrote:
When translating the Pseudo Code to PHP, it's verbatim except for
syntax. With ruby, I think i've found the problem with it not parsing
correclty. the |= operator. With PHP
$i |= 0xe0000000; //= -536870912
Now with Ruby:
i |= 0xe000000 #= true
i wasn't 'claiming' anything. I was asking about why that was happening.
I figured it out though.
···
--
Posted via http://www.ruby-forum.com/.
Hey Matz
I ended up writing the method a bit different,
int = @input_stream.read_special(1,'C')
if(int < 128)
STDOUT.puts "READ INT: #{int}"
return int
else
int = (int & 0x7f) << 7
tmp = @input_stream.read_special(1,'C')
if(tmp < 128)
STDOUT.puts "READ INT: #{int}"
return int | tmp
else
int = (int | (tmp & 0x7f)) << 7
tmp = @input_stream.read_special(1,'C')
if(tmp < 128)
STDOUT.puts "READ INT: #{int}"
return int | tmp
else
int = (int | (tmp & 0x7f)) << 8
tmp = @input_stream.read_special(1,'C')
int |= tmp
#Check if the integer should be negative
if ((int & 0x10000000) != 0)
## and extend the sign bit
int |= 0xe0000000
end
STDOUT.puts "READ INT: #{int}"
int
end
end
end
this seems to be working fine.
···
--
Posted via http://www.ruby-forum.com/.
would it make sense that in php:
$int |= 0x10000000
is just shorthand for
$int = $int | 0x10000000
···
--
Posted via http://www.ruby-forum.com/.
It's the same in Ruby, except it goes further:
int |= 0x10000000
is short for
int = int | 0x10000000
is short for
int = int.|(0x10000000) # infix operator is really method call on LHS
is short for
int = int.send(:|, 0x10000000) # explicit method call by symbolic name
···
On Fri, Mar 09, 2007 at 07:36:55AM +0900, Aaron Smith wrote:
would it make sense that in php:
$int |= 0x10000000
is just shorthand for
$int = $int | 0x10000000
It's the same in Ruby, except it goes further:
int |= 0x10000000
is short for
int = int | 0x10000000
is short for
int = int.|(0x10000000) # infix operator is really method call on
LHS
is short for
int = int.send(:|, 0x10000000) # explicit method call by symbolic name
pretty flippin cool.
in this example:
int = int.send(:|,0x1000000)
is it neccessary to have assignment portion? as in:
int.send(:|,0x1000000), does this take out the need for (int=)
···
--
Posted via http://www.ruby-forum.com/\.
You don't need to make use of the return value. Every expression in Ruby
returns a value, but you can simply ignore it.
In your particular example, if you write
int = 4
int.send(:|, 0x10000000)
it's valid Ruby but isn't very useful, as it calculates a result and then
throws it away. But many methods do have side effects:
str = "hello"
str.send(:concat, " world")
puts str
Actually you'd normally write the middle line as
str.concat(" world")
or
str.concat " world"
or
str << " world"
(since the << infix operator expands to a << method call on str, and for
Strings the << method does the same as concat)
This stems from the fact that a String in Ruby is a mutable object (it can
change). Most objects are. However a few objects, in particular numbers and
symbols, are immutable. That is, you can't send a message to the number 5
telling it to change its value
Regards,
Brian.
···
On Sat, Mar 10, 2007 at 01:55:19PM +0900, Aaron Smith wrote:
> It's the same in Ruby, except it goes further:
>
> int |= 0x10000000
>
> is short for
>
> int = int | 0x10000000
>
> is short for
>
> int = int.|(0x10000000) # infix operator is really method call on
> LHS
>
> is short for
>
> int = int.send(:|, 0x10000000) # explicit method call by symbolic name
pretty flippin cool.
in this example:
int = int.send(:|,0x1000000)
is it neccessary to have assignment portion? as in:
int.send(:|,0x1000000), does this take out the need for (int=)