Morse Encoder/Decoder Library. Transforms char array to binary array and vice-versa.

A Morse Encoding/Decoding Library \n Transforms char arrays into bool arrays and vice-versa

Morse code taken from http://en.wikipedia.org/wiki/Morse_code Added some more characters :
- : DOT DOT DASH DASH
_ : DASH DASH DASH DOT
. : DASH DASH DASH DASH
/ : DOT DASH DOT DASH
@ : DOT DOT DOT DASH DOT
? : DOT DOT DASH DOT DOT

Here is an quick hello-world that show how to use this library

#include "mbed.h
#include "Morse.h"
    
Serial pc(USBTX, USBRX);
    
int main() {
    int i;
    Morse_data* data;
    char message[] = "Hello World";
    
    data = morse_create(morse_getBoolSize(message));
    morse_encode(message, data);
    for (i=0; i<data->length; i++) pc.printf("%d", data->data[i]);
    
    morse_decode(data, message);
    pc.printf("\nMessage was : %s\n", message);
    
    while(1);
}
Revision:
1:84ef66bf435d
Parent:
0:4648894e0d80
--- a/MorseEncoder.cpp	Tue Sep 16 16:51:31 2014 +0000
+++ b/MorseEncoder.cpp	Thu Sep 18 17:26:24 2014 +0000
@@ -1,29 +1,150 @@
-#include "MorseEncoder.h"
+/* 
+    Copyright (c) 2014 Romain Berrada
+    
+    Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
+    and associated documentation files (the "Software"), to deal in the Software without restriction, 
+    including without limitation the rights to use, copy, modify, merge, publish, distribute, 
+    sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in all copies or 
+    substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
+    BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
+    DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
 #include "Morse.h"
 
-const unsigned int MorseEncoder::_values_size[36] = {MORSE_0_SIZE, MORSE_1_SIZE, MORSE_2_SIZE, MORSE_3_SIZE, MORSE_4_SIZE, MORSE_5_SIZE, MORSE_6_SIZE, MORSE_7_SIZE, MORSE_8_SIZE, MORSE_9_SIZE, 
-                                                     MORSE_A_SIZE, MORSE_B_SIZE, MORSE_C_SIZE, MORSE_D_SIZE, MORSE_E_SIZE, MORSE_F_SIZE, MORSE_G_SIZE, MORSE_H_SIZE, MORSE_I_SIZE, MORSE_J_SIZE,
-                                                     MORSE_K_SIZE, MORSE_L_SIZE, MORSE_M_SIZE, MORSE_N_SIZE, MORSE_O_SIZE, MORSE_P_SIZE, MORSE_Q_SIZE, MORSE_R_SIZE, MORSE_S_SIZE, MORSE_T_SIZE,
-                                                     MORSE_U_SIZE, MORSE_V_SIZE, MORSE_W_SIZE, MORSE_X_SIZE, MORSE_Y_SIZE, MORSE_Z_SIZE};
+// Definitions of encoder/decoder data and Morse letter definitions
+#define DOT  false
+#define DASH true
+
+#define MORSE_MN {DOT,  DOT,  DASH, DASH, 0   }
+#define MORSE_DO {DASH, DASH, DASH, DASH, 0   }
+#define MORSE_SL {DOT,  DASH, DOT,  DASH, 0   }
+#define MORSE_0 {DASH, DASH, DASH, DASH, DASH}
+#define MORSE_1 {DOT,  DASH, DASH, DASH, DASH}
+#define MORSE_2 {DOT,  DOT,  DASH, DASH, DASH}
+#define MORSE_3 {DOT,  DOT,  DOT,  DASH, DASH}
+#define MORSE_4 {DOT,  DOT,  DOT,  DOT,  DASH}
+#define MORSE_5 {DOT,  DOT,  DOT,  DOT,  DOT }
+#define MORSE_6 {DASH, DOT,  DOT,  DOT,  DOT }
+#define MORSE_7 {DASH, DASH, DOT,  DOT,  DOT }
+#define MORSE_8 {DASH, DASH, DASH, DOT,  DOT }
+#define MORSE_9 {DASH, DASH, DASH, DASH, DOT }
+#define MORSE_IN {DOT,  DOT,  DASH, DOT,  DOT }
+#define MORSE_AR {DOT,  DOT,  DOT,  DASH, DOT }
+#define MORSE_A {DOT,  DASH, 0,    0,    0   }
+#define MORSE_B {DASH, DOT,  DOT,  DOT,  0   }
+#define MORSE_C {DASH, DOT,  DASH, DOT,  0   }
+#define MORSE_D {DASH, DOT,  DOT,  0,    0   }
+#define MORSE_E {DOT,  0,    0,    0,    0   }
+#define MORSE_F {DOT,  DOT,  DASH, DOT,  0   }
+#define MORSE_G {DASH, DASH, DOT,  0,    0   }
+#define MORSE_H {DOT,  DOT,  DOT,  DOT,  0   }
+#define MORSE_I {DOT,  DOT,  0,    0,    0   }
+#define MORSE_J {DOT,  DASH, DASH, DASH, 0   }
+#define MORSE_K {DASH, DOT, DASH,  0,    0   }
+#define MORSE_L {DOT,  DASH, DOT,  DOT,  0   }
+#define MORSE_M {DASH, DASH, 0,    0,    0   }
+#define MORSE_N {DASH, DOT,  0,    0,    0   }
+#define MORSE_O {DASH, DASH, DASH, 0,    0   }
+#define MORSE_P {DOT,  DASH, DASH, DOT,  0   }
+#define MORSE_Q {DASH, DASH, DOT,  DASH, 0   }
+#define MORSE_R {DOT,  DASH, DOT,  0,    0   }
+#define MORSE_S {DOT,  DOT,  DOT,  0,    0   }
+#define MORSE_T {DASH, 0,    0,    0,    0   }
+#define MORSE_U {DOT,  DOT,  DASH, 0,    0   }
+#define MORSE_V {DOT,  DOT,  DOT,  DASH, 0   }
+#define MORSE_W {DOT,  DASH, DASH, 0   , 0   }
+#define MORSE_X {DASH, DOT,  DOT,  DASH, 0   }
+#define MORSE_Y {DASH, DOT,  DASH, DASH, 0   }
+#define MORSE_Z {DASH, DASH, DOT,  DOT,  0   }
+#define MORSE_UN {DASH, DASH, DASH, DOT,  0   }
 
-const bool MorseEncoder::_values[36][5] =     {MORSE_0, MORSE_1, MORSE_2, MORSE_3, MORSE_4, MORSE_5, MORSE_6, MORSE_7, MORSE_8, MORSE_9, 
-                                               MORSE_A, MORSE_B, MORSE_C, MORSE_D, MORSE_E, MORSE_F, MORSE_G, MORSE_H, MORSE_I, MORSE_J,
-                                               MORSE_K, MORSE_L, MORSE_M, MORSE_N, MORSE_O, MORSE_P, MORSE_Q, MORSE_R, MORSE_S, MORSE_T,
-                                               MORSE_U, MORSE_V, MORSE_W, MORSE_X, MORSE_Y, MORSE_Z};
-                                                   
-unsigned int MorseEncoder::find(char c) {
-    unsigned int i=37;
-    if (c>='0' && c<='9') i=c-'0';
-    else if (c>='A' && c<='Z') i=c-'A'+10;
-    else if (c>='a' && c<='z') i=c-'a'+10;
+#define MORSE_MN_SIZE 11
+#define MORSE_DO_SIZE 15
+#define MORSE_SL_SIZE 11
+#define MORSE_0_SIZE 19
+#define MORSE_1_SIZE 17
+#define MORSE_2_SIZE 15
+#define MORSE_3_SIZE 13
+#define MORSE_4_SIZE 11
+#define MORSE_5_SIZE 9
+#define MORSE_6_SIZE 11
+#define MORSE_7_SIZE 13
+#define MORSE_8_SIZE 15
+#define MORSE_9_SIZE 17
+#define MORSE_IN_SIZE 11
+#define MORSE_AR_SIZE 11
+#define MORSE_A_SIZE 5
+#define MORSE_B_SIZE 9
+#define MORSE_C_SIZE 11
+#define MORSE_D_SIZE 7
+#define MORSE_E_SIZE 1
+#define MORSE_F_SIZE 9
+#define MORSE_G_SIZE 9
+#define MORSE_H_SIZE 7
+#define MORSE_I_SIZE 3
+#define MORSE_J_SIZE 13
+#define MORSE_K_SIZE 9
+#define MORSE_L_SIZE 9
+#define MORSE_M_SIZE 7
+#define MORSE_N_SIZE 5
+#define MORSE_O_SIZE 11
+#define MORSE_P_SIZE 11
+#define MORSE_Q_SIZE 13
+#define MORSE_R_SIZE 7
+#define MORSE_S_SIZE 5
+#define MORSE_T_SIZE 3
+#define MORSE_U_SIZE 7
+#define MORSE_V_SIZE 9
+#define MORSE_W_SIZE 9
+#define MORSE_X_SIZE 11
+#define MORSE_Y_SIZE 13
+#define MORSE_Z_SIZE 11
+#define MORSE_UN_SIZE 13
+
+// Array containing the morse letter definitions and the size of each letter (size is in bits) 
+// Example: A = DOT-DASH.
+// DOT has size 1 and DASH 3. Plus the blank between the DOT and the DASH
+// So A has size 1+3+1 = 5
+static const unsigned int _morse_values_size[42] = {MORSE_MN_SIZE, MORSE_DO_SIZE, MORSE_SL_SIZE, MORSE_0_SIZE, MORSE_1_SIZE, MORSE_2_SIZE,
+                                                    MORSE_3_SIZE, MORSE_4_SIZE, MORSE_5_SIZE, MORSE_6_SIZE, MORSE_7_SIZE, MORSE_8_SIZE,
+                                                    MORSE_9_SIZE, MORSE_IN_SIZE, MORSE_AR_SIZE, MORSE_A_SIZE, MORSE_B_SIZE, MORSE_C_SIZE,
+                                                    MORSE_D_SIZE, MORSE_E_SIZE, MORSE_F_SIZE, MORSE_G_SIZE, MORSE_H_SIZE, MORSE_I_SIZE,
+                                                    MORSE_J_SIZE, MORSE_K_SIZE, MORSE_L_SIZE, MORSE_M_SIZE, MORSE_N_SIZE, MORSE_O_SIZE,
+                                                    MORSE_P_SIZE, MORSE_Q_SIZE, MORSE_R_SIZE, MORSE_S_SIZE, MORSE_T_SIZE, MORSE_U_SIZE,
+                                                    MORSE_V_SIZE, MORSE_W_SIZE, MORSE_X_SIZE, MORSE_Y_SIZE, MORSE_Z_SIZE, MORSE_UN_SIZE};
+
+static const bool _morse_values[42][5] = {MORSE_MN, MORSE_DO, MORSE_SL, MORSE_0, MORSE_1, MORSE_2,
+                                          MORSE_3, MORSE_4, MORSE_5, MORSE_6, MORSE_7, MORSE_8,
+                                          MORSE_9, MORSE_IN, MORSE_AR, MORSE_A, MORSE_B, MORSE_C,
+                                          MORSE_D, MORSE_E, MORSE_F, MORSE_G, MORSE_H, MORSE_I,
+                                          MORSE_J, MORSE_K, MORSE_L, MORSE_M, MORSE_N, MORSE_O,
+                                          MORSE_P, MORSE_Q, MORSE_R, MORSE_S, MORSE_T, MORSE_U,
+                                          MORSE_V, MORSE_W, MORSE_X, MORSE_Y, MORSE_Z, MORSE_UN};
+
+// Returns the index of the letter in the above arrays. returns -1 if not found
+static int _morse_find(char c) {
+    int i=-1;
+    if (c>='-' && c<='9') i=c-'-';
+    else if (c>='?' && c<='Z') i=c-'?'+13;
+    else if (c>='a' && c<='z') i=c-'a'+15;
+    else if (c=='_') i=41;
     return i;                                             
 }
 
-unsigned int MorseEncoder::addChar(unsigned int index_value, bool* result, unsigned int place) {
+// Add a single char (index array) to the result array at the specified position
+static unsigned int _morse_addChar(unsigned int index_value, bool* result, unsigned int place) {
     unsigned char i,j;
     i=0;
-    for (j=0; j<_values_size[index_value]; j++) {
-        if (_values[index_value][i]==DOT) { // if DOT
+    for (j=0; j<_morse_values_size[index_value]; j++) {
+        if (_morse_values[index_value][i]==DOT) { // if DOT
             result[place+j] = true; 
         } else { // else DASH
             result[place+j] = true;
@@ -37,24 +158,19 @@
     
     return j-1;
 }
-                                              
-MorseEncoder_data* MorseEncoder::encode(char* word) {
-    int char_i;
-    unsigned int size;
-    unsigned int morse_i;
-    unsigned int res_counter;
-    MorseEncoder_data* data = new MorseEncoder_data;
-    bool* res;
+
+unsigned int morse_getBoolSize(char* word) {
+    unsigned int char_i;
+    int morse_i;
+    unsigned int size = 0;
     
-    // first loop to know the size
-    size = 0;
     for (char_i=0; word[char_i]!='\0'; char_i++) {
         if (word[char_i]!=' ') { // if not space
-            morse_i = find(word[char_i]);
-            if (morse_i==37) continue; // if not found
+            morse_i = _morse_find(word[char_i]);
+            if (morse_i==-1) continue; // if not found
             
-            size += _values_size[morse_i];
-            size += 3;
+            size += _morse_values_size[morse_i];
+            size += 3; // plus the 3 blanks between chars
         }
         else { // else space
             if (char_i==0 || word[char_i-1]==' ') size+=7;
@@ -63,31 +179,39 @@
     }
     if (word[char_i-1]!=' ') size -= 3; // remove last space between elements (but not if space)
     
-    res = new bool[size]();
+    return size;
+}
+                             
+void morse_encode(char* word, Morse_data* data) {
+    unsigned int char_i;
+    int morse_i;
+    unsigned int res_counter;
     
-    // second loop to fill the result
     res_counter = 0;
     for (char_i=0; word[char_i]!='\0'; char_i++) {
         if (word[char_i]!=' ') {
-            morse_i = find(word[char_i]);
-            if (morse_i==37) continue; // if not found
+            morse_i = _morse_find(word[char_i]);
+            if (morse_i==-1) continue; // if not found
             
-            res_counter += addChar(morse_i, res, res_counter); // if not space
+            res_counter += _morse_addChar(morse_i, data->data, res_counter); // if not space
             res_counter += 3; // add space between elements
         }
         else { // else space
-            if (char_i==0 || word[char_i-1]==' ') res_counter+=3; // if not char last time
-            res_counter += 4;
-        }
-        
+            if (char_i==0 || word[char_i-1]==' ') res_counter+=7; // if not char last time
+            else res_counter += 4;
+        }  
     }
-    
-    data->length = size;
-    data->data = res;
+    if (word[char_i-1]!=' ') res_counter -= 3; // remove last space between elements (but not if space)
+    data->length = res_counter;
+}
+
+Morse_data* morse_create(unsigned int length) {
+    Morse_data* data = new Morse_data;
+    data->length = length;
+    data->data = new bool[length]();
     return data;
 }
-
-void MorseEncoder::destroy(MorseEncoder_data* data) {
+void morse_destroy(Morse_data* data) {
     delete[] data->data;
     delete data;
 }