OpenCPN Partial API docs
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 "model/ais_bitstring.h"
28 
29 AisBitstring::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 
37 int AisBitstring::GetBitCount() { return byte_length * 6; }
38 
39 // Convert printable characters to IEC 6 bit representation
40 // according to rules in IEC AIS Specification
41 unsigned 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 
57 int 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 
77 int 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