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