OpenCPN Partial API docs
Loading...
Searching...
No Matches
ais_bitstring.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2010 by David S. Register *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
16 **************************************************************************/
17
24#include <cstring>
25
26#include "model/ais_bitstring.h"
27
28AisBitstring::AisBitstring(const char *str) {
29 // Never trust the caller's length: copy at most AIS_MAX_MESSAGE_LEN bytes and
30 // leave every bit beyond the payload defined (zero) so that GetInt()/GetStr()
31 // on a short message return 0 instead of whatever the stack held.
32 memset(bitbytes, 0, sizeof(bitbytes));
33 size_t len = strlen(str);
34 if (len > AIS_MAX_MESSAGE_LEN) len = AIS_MAX_MESSAGE_LEN;
35 byte_length = static_cast<int>(len);
36 for (int i = 0; i < byte_length; i++) {
37 bitbytes[i] = to_6bit(str[i]);
38 }
39}
40
41int AisBitstring::GetBitCount() { return byte_length * 6; }
42
43// Convert printable characters to IEC 6 bit representation
44// according to rules in IEC AIS Specification
45unsigned char AisBitstring::to_6bit(const char c) {
46 if (c < 0x30) return (unsigned char)-1;
47 if (c > 0x77) return (unsigned char)-1;
48 if ((0x57 < c) && (c < 0x60)) return (unsigned char)-1;
49
50 unsigned char cp = c;
51 cp += 0x28;
52
53 if (cp > 0x80)
54 cp += 0x20;
55 else
56 cp += 0x28;
57
58 return (unsigned char)(cp & 0x3f);
59}
60
61int AisBitstring::GetInt(int sp, int len, bool signed_flag) {
62 int acc = 0;
63 int s0p = sp - 1; // to zero base
64
65 int cp, cx, c0;
66
67 for (int i = 0; i < len; i++) {
68 acc = acc << 1;
69 cp = (s0p + i) / 6;
70 cx = (cp >= 0 && cp < byte_length) ? bitbytes[cp] : 0;
71 c0 = (cx >> (5 - ((s0p + i) % 6))) & 1;
72 if (i == 0 && signed_flag &&
73 c0) // if signed value and first bit is 1, pad with 1's
74 acc = ~acc;
75 acc |= c0;
76 }
77
78 return acc;
79}
80
81int AisBitstring::GetStr(int sp, int bit_len, char *dest, int max_len) {
82 // char temp_str[85];
83 char *temp_str = dest;
84
85 char acc = 0;
86 int s0p = sp - 1; // to zero base
87
88 int k = 0;
89 int cp, cx, c0, cs;
90
91 int i = 0;
92 while (i < bit_len && k < max_len) {
93 acc = 0;
94 for (int j = 0; j < 6; j++) {
95 acc = acc << 1;
96 cp = (s0p + i) / 6;
97 cx = (cp >= 0 && cp < byte_length) ? bitbytes[cp] : 0;
98 cs = 5 - ((s0p + i) % 6);
99 c0 = (cx >> cs) & 1;
100 acc |= c0;
101
102 i++;
103 }
104 temp_str[k] = (char)(acc & 0x3f);
105
106 if (acc < 32) temp_str[k] += 0x40;
107 k++;
108 }
109
110 temp_str[k] = 0;
111
112 return k;
113}
AIS use bitstring.
int GetInt(int sp, int len, bool signed_flag=false)
sp is starting bit, 1-based