Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manually decoding the Size presend on a CodedInputStream

So I have a dotNet CoreCLR application for hololens and it's my understanding that standard sockets aren't supported in CoreCLR and the recommended avenue is to use StreamSocket.

It's also my understanding that CodedInputStream and StreamSocket aren't compatible.

So I've been manually trying to decode the size pre-send but it's a varInt32 which can be anything from 2-4 bytes.

This is as far as I've gotten but that variable size issue is giving me problems.

int bytenum = 0;
int num = 0;
while((bytes[bytenum] & 0x80) == 0x80){
    bytenum++;
}
while(bytenum >= 0)
{
    int tem = bytes[bytenum] & 0x7F;
    num = num << 7;
    num = num | tem;
    bytenum--;
}

Any suggestions on how I might fix this code or alternatives I might use?

Edit: I've also had a look at the CodedInputStream.cs SlowReadRawVarint32() and tried this with no success... I'm thinking the DataReader is doing something non-standard.

var dr = new DataReader(socket.InputStream);

await dr.LoadAsync(1);

int result = -1;
int tmp = dr.ReadByte();

if (tmp >= 128)
{
    result = tmp & 0x7f;
    await dr.LoadAsync(1);
    if ((tmp = dr.ReadByte()) < 128)
    {
        result |= tmp << 7;
    }
    else
    {

        result |= (tmp & 0x7f) << 7;
        await dr.LoadAsync(1);
        if ((tmp = dr.ReadByte()) < 128)
        {
            result |= tmp << 14;
        }
        else
        {
            result |= (tmp & 0x7f) << 14;
            await dr.LoadAsync(1);
            if ((tmp = dr.ReadByte()) < 128)
            {
                result |= tmp << 21;
            }
            else
            {
                result |= (tmp & 0x7f) << 21;
                await dr.LoadAsync(1);
                result |= (tmp = dr.ReadByte()) << 28;
                if (tmp >= 128)
                {
                    // Discard upper 32 bits.
                    for (int i = 0; i < 5; i++)
                    {
                        await dr.LoadAsync(1);
                        if (dr.ReadByte() < 128)
                        {
                        }
                    }
                }
            }
        }
    }
}
else
{
    result = tmp;
}
like image 814
Mytheral Avatar asked Feb 23 '18 15:02

Mytheral


1 Answers

This code looks oddly similar, although a bit off at times to (https://github.com/deephacks/westty/blob/master/westty-protobuf/src/main/java/org/deephacks/westty/protobuf/Varint32.java) have you seen it? Are you trying to translate it?

public int read() throws IOException {

byte tmp = bytes.get();
if (tmp >= 0) {
        return tmp;
    }
    int result = tmp & 0x7f;
    if ((tmp = bytes.get()) >= 0) {
        result |= tmp << 7;
    } else {
        result |= (tmp & 0x7f) << 7;
        if ((tmp = bytes.get()) >= 0) {
            result |= tmp << 14;
        } else {
            result |= (tmp & 0x7f) << 14;
            if ((tmp = bytes.get()) >= 0) {
                result |= tmp << 21;
            } else {
                result |= (tmp & 0x7f) << 21;
                result |= (tmp = bytes.get()) << 28;
                if (tmp < 0) {
                    // Discard upper 32 bits.
                    for (int i = 0; i < 5; i++) {
                        if (bytes.get() >= 0) {
                            return result;
                        }
                    }
                    throw new IllegalArgumentException();
                }
            }
        }
    }
    return result;
}

If not, perhaps you could use it as inspiration. Since your values are 40 times larger than expected, I suspect shifting errors. If you do not solve it, I can help further by translating that class for you, but it is a big time investment!

like image 153
Alexandru Clonțea Avatar answered Oct 18 '22 20:10

Alexandru Clonțea