OS/device including version:
OS X 10.13.x
Client: Godot 3.0.beta.build1
Server: NodeJS v8.9.3
Issue description:
Put a Variant into the stream. Binary serialization
streamPeerTCP.put_var(true) sends <Buffer 08 00 00 00 01 00 00 00 01 00 00 00> - OK
streamPeerTCP.put_var(5) sends <Buffer 0c 00 00 00 02 00 01 00 05 00 00 00 00 00 00 00> - ???
streamPeerTCP.put_var(5.5) sends <Buffer 08 00 00 00 03 00 00 00 00 00 b0 40> - OK
streamPeerTCP.put_var("test") sends <Buffer 0c 00 00 00 04 00 00 00 04 00 00 00 74 65 73 74> - OK
The part that i think there is something wrong:
I expected to receive something like this:
Is this a bug, or am I doing something wrong?
Steps to reproduce:
var streamPeerTCP = StreamPeerTCP.new()
streamPeerTCP.connect_to_host(IP, PORT)
# after connect
streamPeerTCP.put_var(5)
5 is encoded as 64 bit int.
Comparison here core/io/marshalls.cpp#L833 and here core/io/marshalls.cpp#L876 works incorrectly and is true for int64_t(5).
I'm not sure how exactly -0x80000000 type conversion works, but here some tests (with clang5 and gcc7 on macOS and Linux):
/*5*/
int64_t(5) > INT32_MAX //false
int64_t(5) < INT32_MIN //false
int64_t(5) < -INT32_MIN //false - warning: integer overflow in expression
int64_t(5) > 0x7FFFFFFF //false
int64_t(5) < 0x80000000 //true !!!
int64_t(5) < -0x80000000 //true !!!
/*overflow*/
int64_t(2147483648) > INT32_MAX //true
int64_t(-2147483649) < INT32_MIN //true
int64_t(-2147483649) < -INT32_MIN; //true - warning: integer overflow in expression
int64_t(2147483648) > 0x7FFFFFFF //true
int64_t(-2147483649) < 0x80000000 //true
int64_t(-2147483649) < -0x80000000 //true
/*max values*/
int64_t(2147483647) > INT32_MAX //false
int64_t(-2147483648) < INT32_MIN //false
int64_t(-2147483648) < -INT32_MIN //false - warning: integer overflow in expression
int64_t(2147483647) > 0x7FFFFFFF //false
int64_t(-2147483648) < 0x80000000 //true !!!
int64_t(-2147483648) < -0x80000000 //true !!!
Update
In floats the situation there also looks a bit strange.
streamPeerTCP.put_var(5.5) sends <Buffer 08 00 00 00 03 00 00 00 00 00 b0 40>
but
streamPeerTCP.put_var(5.6) sends <Buffer 0c 00 00 00 03 00 01 00 66 66 66 66 66 66 16 40>
Is this a normal/good encoding?
5.5 can be precisely represented as IEEE-754 single precision float -> 0x40B00000
and as IEEE-754 double precision float -> 0x4016000000000000.
if (double(f) != d) at core/io/marshalls.cpp#L841 and core/io/marshalls.cpp#L895 is false and 5.5 is encoded single precision float (32-bit).
5.6 can't be precisely represented as single precision float it is rounded to 5.599999904632568359375 -> 0x40B33333, but it can be precisely represented as double precision float -> 0x4016666666666666.
if (double(f) != d) is true and 5.6 is encoded as double precision float (64-bit).
@Fulkman if you know the type, and you want to have a specific size (e.g. for performance or interoperability), you can use a StreamPeerBuffer which in turn is a StreamPeer and call put_int32, put_int64, put_float, put_double, ecc. directly.
I think its solved by @Faless. Closed.
Sorry @Chaosus, but it's not solved anything. The easy example was deliberately given and put_int32 is NOT an answer.
streamPeerTCP.put_var(5) sends <Buffer 0c 00 00 00 02 00 01 00 05 00 00 00 00 00 00 00>
5 is encoded as 64 bit int.
In that case, is this the correct behavior for coding? In my opinion, it is not.
@Fulkman , you are right, I didn't realize at first that it was actually supposed to be encoded as 32bits.
Check out the patch if you can.
The test I did:
extends Node
const MAX = int(pow(2, 31) - 1)
const MIN = -int(pow(2, 31))
const ZERO = 0
const FIVE = 5
func _ready():
printt(MAX, MIN)
prints(var2bytes(MAX).size(), 8)
prints(var2bytes(MAX-1).size(), 8)
prints(var2bytes(MAX+1).size(), 12)
prints(var2bytes(MIN).size(), 8)
prints(var2bytes(MIN+1).size(), 8)
prints(var2bytes(MIN-1).size(), 12)
prints(var2bytes(ZERO).size(), 8)
prints(var2bytes(FIVE).size(), 8)
```
2147483647 -2147483648
8 8
8 8
12 12
8 8
8 8
12 12
8 8
8 8
Now I can tell its solved by @Faless.
I tested and as far as I can tell it working as expected.
Thank you very much for your work.
Good to hear ! And sorry for my incorrect action, its lesson for me to be more careful.
Ahem. PR is not merged yet.
^^ Ah, didnt notice
Most helpful comment
Good to hear ! And sorry for my incorrect action, its lesson for me to be more careful.