So first one: Bit Shifting
I guess you've heard about binary numbers. Most people nowadays use the decimal number system in our day-to-day business, where you have digits ranging from 0-9. Every number you use is made up of digits from 0-9. The binary system only uses the digits 0 and 1, which is very convenient for computer to use since then you can represent numbers with power easily:
0 = no power
1 = power
Same as the decimal number system you can make larger numbers just by putting digits next to each other: in decimal 10 is 9+1. In binary 10 is 1+1.
Binary = Decimal
0 = 0
1 = 1
10 = 2
11 = 3
100 = 4
101 = 5
110 = 6
111 = 7
and so on.
Computers usually work with fixed-length numbers (at least with integer-type nubers, like int, long, short, byte, ...), so they fill all remaining digits on the left with 0:
5 in decimal = 101 in binary = 00000101 in 8-bit (byte) = 0000000000000101 in 16-bit (short)
and so on.
What bit shifting does is it moves all bits into one direction:
Right-Shift by two digits:
00001101 >> 2 = 00000011
Left-Shift by three digits:
00001101 << 3 = 01101000
A left shift is equivalent to multiplying by 2 while a right shift equivalent to dividing by 2 (talking about positive numbers here, since negative numbers are a bit different).
Now to the second one: Masking
This is now about this part:
sData[i] & 0x00FF
At first, here we have another numbers notation: the hexadecimal numbers. It works quite similarly as the binary numbers just now there are 16 different digits: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F. Each of them stands for four digits in binary, so you can convert between the two by just replacing each digit by the following digits:
Hex = Binary
0 = 0000
1 = 0001
2 = 0010
3 = 0011
4 = 0100
5 = 0101
6 = 0110
7 = 0111
8 = 1000
9 = 1001
A = 1010
B = 1011
C = 1100
D = 1101
E = 1110
F = 1111
So the number given here as 0x00FF equals 0000000011111111 in 16-bit binary.
Now to the &, or the actual masking. The &-Operator returns 1 for every bit where both inputs are 1 and 0 for each bit where either of the inputs are 0:
0101010101010101
&
0000000011111111
=
0000000001010101
So you see, you can use the &-operator to mask out all the bits that are 0 in the one input-string.
So what that part of the function does is it splits the short (which is 16-bit long) into two separate 8-bit-bytes. Lets say sData[i] contains this number: 0011001101010101
bytes[i * 2] = (byte) (sData[i] & 0x00FF);
=
bytes[i * 2] = (byte) (0011001101010101 & 0000000011111111);
=
bytes[i * 2] = (byte) (0000000001010101); //lower 8 bit
bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
=
bytes[(i * 2) + 1] = (byte) (0011001101010101 >> 8); //Right shift by 8 spaces
=
bytes[(i * 2) + 1] = (byte) (0000000000110011); //upper 8 bit