Android Question [Solved]Help to convert code from c to B4A or Java

stefanoxjx

Active Member
Licensed User
Longtime User
Hi, I've this code written in "c":
B4X:
uint16_t CRC16Calc(uint8_t *data, uint16_t size)
{
    #define CRC16 0x8005

    uint16_t out = 0;
    uint16_t bits_read = 0, bit_flag;
    uint16_t idx = 0;

    while (size > 0)
    {
        bit_flag = out >> 15;

        out <<= 1;
        out |= (data[idx] >> bits_read) & 1;

        bits_read++;
        if (bits_read > 7)
        {
            bits_read = 0;
            idx++;
            size--;
        }

        if (bit_flag) out ^= CRC16;
    }

    uint16_t i;
    for (i = 0; i < 16; ++i)
    {
        bit_flag = out >> 15;
        out <<= 1;
        if (bit_flag) out ^= CRC16;
    }

    uint16_t crc = 0;
    i = 0x8000;
    uint16_t j = 0x0001;
    for (; i != 0; i >>= 1, j <<= 1)
    {
        if (i & out) crc |= j;
    }

    return crc;
}

I need to convert it in B4A or Java to embed in test app.
Unfortunately I don't know Java and B4A don't very well.
I think converting this code to java is easier that in B4A.
Someone can help me?
Thanks.
 

stefanoxjx

Active Member
Licensed User
Longtime User
I tried to convert in B4A and the result is:
B4X:
Sub CRC16Calc(data() As Byte) As Short
'Public short CRC16Calc(uint8_t *data, short size)

    '#define CRC16 0x8005 //Polinomio
    Dim CRC16 As Short = 0x8005
    
    'uint16_t out = 0;
    Dim out As Short
    
    'uint16_t bits_read = 0, bit_flag;
    Dim bits_read As Short = 0
    Dim bit_flag As Short
    
    'uint16_t idx = 0;
    Dim idx As Short = 0
    
    Dim size As Short = data.Length
    
    Do While size > 0
        'bit_flag = out >> 15;
        bit_flag = Bit.ShiftRight(out, 15)
        
        Log("first while")
        
        'out <<= 1;
        'out |= (data[idx] >> bits_read) & 1;
        out = Bit.ShiftLeft(out, 1)
        out = Bit.Or(out, Bit.And(Bit.ShiftRight(data(idx), bits_read), 1))
        
        bits_read=bits_read+1
        'If (bits_read > 7)
        If(Bit.ShiftRight(bits_read, 7) <> 0) Then
            bits_read = 0
            idx=idx+1
            size=size-1
            Log("*********************** first if")
        End If
    
        'If (bit_flag) out ^= CRC16;
        If(bit_flag > 0) Then out = Bit.Xor(out, CRC16)
    Loop
    
    
    'uint16_t i;
    Dim i As Short
    'For (i = 0; i < 16; ++i)
    For i = 0 To 16
        Log("first for")
        'bit_flag = out >> 15;
        bit_flag = Bit.ShiftRight(out, 15)
        'out <<= 1;
        out = Bit.ShiftLeft(out, 1)
    
        'If (bit_flag) out ^= CRC16;
        If(bit_flag <> 0) Then out = Bit.Xor(out, CRC16)
    Next
    
    'uint16_t crc = 0;
    Dim crc As Short = 0
    i = 0x8000
    'uint16_t j = 0x0001;
    Dim j As Short = 0x0001
    'For (; i != 0; i >>= 1, j <<= 1)
    Do While i <> 0
        'Log("second while")
    
        'If (i & out) crc |= j;
        If(Bit.And(i, out) <> 0) Then crc = Bit.Or(crc, j)
        
        i = Bit.ShiftRight(i, 1)
        j = Bit.ShiftLeft(j, 1)
        
'        Dim bc As String
'        bc = i
'        bc = bc & " " & j
'        Log(bc)
    Loop
    
    Return crc
End Sub
but, the elaboration time is very very very long and the app goes in infinite loop during last loop with i=-1 and j=0
I believe the problem is generated from signed variables.
Is possible to create an unsigned variables?

Thanks.
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
I think there is some translation error. I only saw superficially, but i think:
B4X:
For i = 0 To 16
As
B4X:
For i = 0 To 15
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
I haven't got time to go through it all but try Bit.UnsignedShiftRight
or
B4X:
out = Bit.Or(out, Bit.And(Bit.ShiftRight(Bit.And(0xFF,data(idx)), bits_read), 1))
Note: After looking at all the code again, @agraham is still correct in using UnsignedShiftRight in several places instead of ShiftRight. The Bit.And I'm introducing here is to convert the signed byte value (as seen by B4X) to an unsigned equivalent Int value (the Bit operations operate on Int values). Since at max you'll have 7 bit shifts (bits_read will never be greater than 7), the ShiftRight is all that is needed in this particular case/statement.
 
Last edited:
Upvote 0

stefanoxjx

Active Member
Licensed User
Longtime User
Tried, but the situation does not improve :(
At the moment, the real problem is here:
B4X:
    Do While i <> 0
        Log("second while")
    
        'If (i & out) crc |= j;
        If(Bit.And(i, out) <> 0) Then crc = Bit.Or(crc, j)
        
        i = Bit.UnsignedShiftRight(i, 1)
        j = Bit.ShiftLeft(j, 1)
        
'        Dim bc As String
'        bc = i
'        bc = bc & " " & j
'        Log(bc)
    Loop

This is infinite loop.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
You need to declare i an Int. Anything in the original code that is an unsigned short value, declare it in B4X as an Int. Unless you see something in the code that relies on over/under flowing a short, this will take care of the unsigned/signed issue (in regards to shorts in the original code).
 
Upvote 0

stefanoxjx

Active Member
Licensed User
Longtime User
With "Int" the situation i improved.
The result is wrong (I passed "10, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0" and result should be 0xEC0D instead it is 0xC001) but infinite loop is solved.
The elaboration time still too long.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
you may end up re-writing your function in b4x, so forge ahead with that. but just as you can code in inline java for b4x, you can code in inline c/c++.
have you used the search box at the top of the page? try "inline c++". i scanned a few hits. most involved a unfamiliar format destined for b4r, but, a couple gave the impression you could put your toolbox of general handy c functions inline.
 
Upvote 0

stefanoxjx

Active Member
Licensed User
Longtime User
I made a little search and I found anything about B4R, but I've not insist because I was convinced that isn't possible embed C code in B4A.
I try another accurate search.
Thanks.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
I made a little search and I found anything about B4R, but I've not insist because I was convinced that isn't possible embed C code in B4A.
I try another accurate search.
Thanks.
there's this link some discussion about errors in the thread, but the last post seems to imply it works. there aren't many posts from people looking to convert their c/c++ to b4a. some of the big c/c++ code out there has already been converted to java with javacpp presets. probably math libraries. i've used javacpppresets in b4a projects. it was easy to refer to the original c/c++ code and to then make sense of the java version to the point where you can edit the java version. but as was mentioned above, whatever it is you're trying to do, it's probably already been done in b4a. search
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
The elaboration time still too long.
Make sure you test the code in release mode. Debug mode will give you the wrong impression of speed. I've translated ulaw encoding to pure B4X, and there were hardly any speed differences between Java and B4X
 
Upvote 0

stefanoxjx

Active Member
Licensed User
Longtime User
Good!!!
This code works:
B4X:
Sub CRC16Calc(data() As Byte) As Int
    Dim CRC16 As Int = 0x8005
    Dim out As Int
    Dim bits_read As Int = 0
    Dim bit_flag As Int
    Dim idx As Int = 0
    Dim size As Int = data.Length
    
    Do While size > 0
        bit_flag = Bit.UnsignedShiftRight(out, 15)
        out = Bit.And(Bit.ShiftLeft(out, 1), 0xFFFF)
        out = Bit.Or(out, Bit.And(Bit.UnsignedShiftRight(Bit.And(0xFF,data(idx)), bits_read), 1))
        bits_read=bits_read+1

        If(bits_read > 7) Then
            bits_read = 0
            idx=idx+1
            size=size-1
        End If

        If(bit_flag > 0) Then out = Bit.Xor(out, CRC16)
    Loop
    
    Dim i As Int
    For i = 0 To 15
        bit_flag = Bit.UnsignedShiftRight(out, 15)
        out = Bit.And(Bit.ShiftLeft(out, 1), 0xFFFF)
    
        If(bit_flag <> 0) Then out = Bit.Xor(out, CRC16)
    Next

    Dim crc_result As Int = 0
    Dim j As Int = 0x0001
    i = 0x8000

    Do While i <> 0
        If(Bit.And(i, out) <> 0) Then crc_result = Bit.Or(crc_result, j)
        
        i = Bit.UnsignedShiftRight(i, 1)
        j = Bit.ShiftLeft(j, 1)
    Loop
    
    Return crc_result
End Sub

Thanks at all for help :)
 
Upvote 0
Top