Reputation: 111
I'm trying to get the position of the STX (0x02) from the byte array message below. If you see the message, it has 0x2 in a number of places but the only position I want is the STX one. I've been looping through it backwards using a for loop. I have to loop backwards btw. I've tried a number of ways but I'm having difficulty getting that position. One way I've tried but has not worked is, wherever a 0x2 is, and has elements of 3 or more between that and an ETX (0x3) in front of it get that position of that STX. But I'm doing something wrong because I keep on getting an error which I am having difficulty resolving. Can you please help?
EDIT: If there is a better way then my logic of finding that position (STX) by distinguishing it from the other 0x2, please can you provide that.
EDIT: I have to loop backwards as that is required by the instructions given to me.
EDIT: Here is the code:
//Test 3:
public String Test3(List<Byte> byteList) {
//checking positions of the STX and ETX
//looping through the array backwards
for (int i = byteList.size() - 1; i >= 0; i--) {
if (byteList.get(i) == STX && (i >= 3 && byteList.get(i) == ETX)) {
STXpos = i;
}
}
return STXpos;
}
byte[] validMsgWithRandomData = {0x32,0x32,0x32, //Random data
0x02, // STX
0x31,0x32,0x10,0x02,0x33, // Data 31 32 02 33
0x03, // ETX
0x31^0x32^0x02^0x33^0x03,// LRC calculated from the data (with the DLE removed) plus the ETX
0x2,0x3,0x00,0x02 //Random data
};
Upvotes: 0
Views: 491
Reputation: 917
My first attempt with backward loop and in O(n) complexity.
EDIT : getting rid of candidate for STX.
EDIT 2 : This solution works at least for a few cases including OP's one (but it has not been tested extensively...).
final int NOTFOUND = -1;
final int ETX = 0x03;
final int STX = 0x02;
int stxpos = NOTFOUND;
int etxpos = NOTFOUND;
int etxcandidatepos = NOTFOUND;
for (int i = validMsgWithRandomData.length - 1; i >=0; --i)
{
if (ETX == validMsgWithRandomData[i])
{
etxcandidatepos = i;
if (NOTFOUND == etxpos)
{
etxpos = i;
stxpos = NOTFOUND;
}
}
else if (STX == validMsgWithRandomData[i])
{
if (NOTFOUND != etxpos)
{
stxpos = i;
if (NOTFOUND != etxcandidatepos)
{
etxpos = etxcandidatepos;
etxcandidatepos = NOTFOUND;
}
}
}
}
Upvotes: 2
Reputation: 3860
Since the amount of elements between STX and ETX is not a constant, i'd search in normal order and look for ETX after I find STX:
public String Test3(List<Byte> byteList) {
// find potential STX
for (int i = 0; i < byteList.size(); ++i) {
if (byteList.get(i) == STX) {
// make sure matching ETX exists
for (int j = i + 1; j < byteList.size(); ++j) {
if (byteList.get(j) == ETX) {
return i;
}
}
}
}
}
You can also do it in reverse order if you really want:
public String Test3(List<Byte> byteList) {
// find potential ETX
for (int i = byteList.size() - 1; i > 0; --i) {
if (byteList.get(i) == ETX) {
// make sure matching STX exists
for (int j = i - 1; j > 0; --j) {
if (byteList.get(j) == STX) {
return j;
}
}
}
}
}
By the way if you want to force a distance of elements between STX and ETX you can do it by changing j
's initialization.
Upvotes: 1