Godot: Send signed, 32-bit integer (as variant) over the stream.

Created on 6 Jan 2018  路  11Comments  路  Source: godotengine/godot

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)
bug core

Most helpful comment

Good to hear ! And sorry for my incorrect action, its lesson for me to be more careful.

All 11 comments

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

Was this page helpful?
0 / 5 - 0 ratings