gr-satnogs/lib/morse_tree.cc

305 lines
7.7 KiB
C++

/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include <satnogs/morse_tree.h>
#include <satnogs/log.h>
#include <string.h>
namespace gr
{
namespace satnogs
{
/*!
* Constructs a Morse code tree for Morse code decoding
*/
morse_tree::morse_tree () :
d_unrecognized_symbol('#'),
d_root (new tree_node(0)),
d_current (d_root),
d_buff_len(4096),
d_word_len(0),
d_word_buffer(new char[d_buff_len])
{
construct_tree ();
}
/*!
* Constructs a Morse code tree for Morse code decoding
* @param unrecognized the character that will be placed
* in the place of unrecognized symbols
*/
morse_tree::morse_tree (char unrecognized) :
d_unrecognized_symbol(unrecognized),
d_root (new tree_node(0)),
d_current (d_root),
d_buff_len(4096),
d_word_len(0),
d_word_buffer(new char[d_buff_len])
{
construct_tree ();
}
morse_tree::~morse_tree ()
{
delete_tree(d_root);
}
/*!
* Resets the pointer to the initial root node
*/
void
morse_tree::reset ()
{
d_current = d_root;
d_word_len = 0;
memset(d_word_buffer.get(), 0, d_buff_len);
}
/*!
* Creates and initializes the Morse code decoder tree
*/
void
morse_tree::construct_tree ()
{
tree_node *e = new tree_node ('E');
tree_node *t = new tree_node ('T');
tree_node *i = new tree_node ('I');
tree_node *a = new tree_node ('A');
tree_node *n = new tree_node ('N');
tree_node *m = new tree_node ('M');
tree_node *s = new tree_node ('S');
tree_node *u = new tree_node ('U');
tree_node *r = new tree_node ('R');
tree_node *w = new tree_node ('W');
tree_node *d = new tree_node ('D');
tree_node *k = new tree_node ('K');
tree_node *g = new tree_node ('G');
tree_node *o = new tree_node ('O');
tree_node *h = new tree_node ('H');
tree_node *v = new tree_node ('V');
tree_node *f = new tree_node ('F');
tree_node *u_u = new tree_node ('U');
tree_node *l = new tree_node ('L');
tree_node *u_a = new tree_node ('A');
tree_node *p = new tree_node ('P');
tree_node *j = new tree_node ('J');
tree_node *b = new tree_node ('B');
tree_node *x = new tree_node ('X');
tree_node *c = new tree_node ('C');
tree_node *y = new tree_node ('Y');
tree_node *z = new tree_node ('Z');
tree_node *q = new tree_node ('Q');
tree_node *u_o = new tree_node ('O');
tree_node *null0 = new tree_node (0);
tree_node *n5 = new tree_node ('5');
tree_node *n4 = new tree_node ('4');
tree_node *a_s = new tree_node ('S');
tree_node *n3 = new tree_node ('3');
tree_node *a_e = new tree_node ('E');
tree_node *d_d = new tree_node ('D');
tree_node *n2 = new tree_node ('2');
tree_node *d_e = new tree_node ('E');
tree_node *plus = new tree_node ('+');
tree_node *d_a = new tree_node ('A');
tree_node *d_j = new tree_node ('J');
tree_node *n1 = new tree_node ('1');
tree_node *n6 = new tree_node ('6');
tree_node *eq = new tree_node ('=');
tree_node *slash = new tree_node ('/');
tree_node *null1 = new tree_node (0);
tree_node *n7 = new tree_node ('7');
tree_node *null2 = new tree_node (0);
tree_node *n8 = new tree_node ('8');
tree_node *n9 = new tree_node ('9');
tree_node *n0 = new tree_node ('0');
d_root->set_left_child (e);
d_root->set_right_child (t);
e->set_left_child (i);
e->set_right_child (a);
t->set_left_child (n);
t->set_right_child (m);
i->set_left_child (s);
i->set_right_child (u);
a->set_left_child (r);
a->set_right_child (w);
n->set_left_child (d);
n->set_right_child (k);
m->set_left_child (g);
m->set_right_child (o);
s->set_left_child (h);
s->set_right_child (v);
u->set_left_child (f);
u->set_right_child (u_u);
r->set_left_child (l);
r->set_right_child (u_a);
w->set_left_child (p);
w->set_right_child (j);
d->set_left_child (b);
d->set_right_child (x);
k->set_left_child (c);
k->set_right_child (y);
g->set_left_child (z);
g->set_right_child (q);
o->set_left_child (u_o);
o->set_right_child (null0);
h->set_left_child (n5);
h->set_right_child (n4);
v->set_left_child (a_s);
v->set_right_child (n3);
f->set_left_child (a_e);
u_u->set_left_child (d_d);
u_u->set_right_child (n2);
l->set_right_child (d_e);
u_a->set_left_child (plus);
p->set_right_child (d_a);
j->set_left_child (d_j);
j->set_right_child (n1);
b->set_left_child (n6);
b->set_right_child (eq);
x->set_left_child (slash);
c->set_right_child (null1);
z->set_left_child (n7);
z->set_right_child (null2);
u_o->set_left_child (n8);
null0->set_left_child (n9);
null0->set_right_child (n0);
}
bool
morse_tree::received_symbol (morse_symbol_t s)
{
char c = 0;
bool ret = false;
/* Check for overflow */
if (d_word_len == d_buff_len) {
return false;
}
switch (s)
{
case MORSE_DOT:
if (d_current->get_left_child ()) {
d_current = d_current->get_left_child ();
ret = true;
}
break;
case MORSE_DASH:
if (d_current->get_right_child ()) {
d_current = d_current->get_right_child ();
ret = true;
}
break;
case MORSE_S_SPACE:
c = d_current->get_char ();
d_current = d_root;
/*
* Some nodes are null transitions and do not correspond to
* a specific character
*/
if (c != 0) {
d_word_buffer[d_word_len] = c;
d_word_len++;
ret = true;
}
break;
default:
LOG_ERROR("Unsupported Morse symbol");
return false;
}
return ret;
}
std::string
morse_tree::get_word ()
{
return std::string(d_word_buffer.get(), d_word_len);
}
size_t
morse_tree::get_max_word_len () const
{
return d_buff_len;
}
size_t
morse_tree::get_word_len ()
{
return d_word_len;
}
void
morse_tree::delete_tree (tree_node *node)
{
if (!node) {
return;
}
delete_tree (node->get_left_child ());
delete_tree (node->get_right_child ());
delete node;
}
tree_node::tree_node (char c) :
d_char (c), d_left (NULL), d_right (NULL)
{
}
void
tree_node::set_left_child (tree_node* child)
{
d_left = child;
}
void
tree_node::set_right_child (tree_node* child)
{
d_right = child;
}
tree_node*
tree_node::get_left_child ()
{
return d_left;
}
tree_node*
tree_node::get_right_child ()
{
return d_right;
}
char
tree_node::get_char ()
{
return d_char;
}
} /* namespace satnogs */
} /* namespace gr */