1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example.android.apis.os;
18 
19 /** Class that implements the text to morse code coversion */
20 class MorseCodeConverter {
21     private static final long SPEED_BASE = 100;
22     static final long DOT = SPEED_BASE;
23     static final long DASH = SPEED_BASE * 3;
24     static final long GAP = SPEED_BASE;
25     static final long LETTER_GAP = SPEED_BASE * 3;
26     static final long WORD_GAP = SPEED_BASE * 7;
27 
28     /** The characters from 'A' to 'Z' */
29     private static final long[][] LETTERS = new long[][] {
30         /* A */ new long[] { DOT, GAP, DASH },
31         /* B */ new long[] { DASH, GAP, DOT, GAP, DOT, GAP, DOT },
32         /* C */ new long[] { DASH, GAP, DOT, GAP, DASH, GAP, DOT },
33         /* D */ new long[] { DASH, GAP, DOT, GAP, DOT },
34         /* E */ new long[] { DOT },
35         /* F */ new long[] { DOT, GAP, DOT, GAP, DASH, GAP, DOT },
36         /* G */ new long[] { DASH, GAP, DASH, GAP, DOT },
37         /* H */ new long[] { DOT, GAP, DOT, GAP, DOT, GAP, DOT },
38         /* I */ new long[] { DOT, GAP, DOT },
39         /* J */ new long[] { DOT, GAP, DASH, GAP, DASH, GAP, DASH },
40         /* K */ new long[] { DASH, GAP, DOT, GAP, DASH },
41         /* L */ new long[] { DOT, GAP, DASH, GAP, DOT, GAP, DOT },
42         /* M */ new long[] { DASH, GAP, DASH },
43         /* N */ new long[] { DASH, GAP, DOT },
44         /* O */ new long[] { DASH, GAP, DASH, GAP, DASH },
45         /* P */ new long[] { DOT, GAP, DASH, GAP, DASH, GAP, DOT },
46         /* Q */ new long[] { DASH, GAP, DASH, GAP, DOT, GAP, DASH },
47         /* R */ new long[] { DOT, GAP, DASH, GAP, DOT },
48         /* S */ new long[] { DOT, GAP, DOT, GAP, DOT },
49         /* T */ new long[] { DASH },
50         /* U */ new long[] { DOT, GAP, DOT, GAP, DASH },
51         /* V */ new long[] { DOT, GAP, DOT, GAP, DOT, GAP, DASH },
52         /* W */ new long[] { DOT, GAP, DASH, GAP, DASH },
53         /* X */ new long[] { DASH, GAP, DOT, GAP, DOT, GAP, DASH },
54         /* Y */ new long[] { DASH, GAP, DOT, GAP, DASH, GAP, DASH },
55         /* Z */ new long[] { DASH, GAP, DASH, GAP, DOT, GAP, DOT },
56     };
57 
58     /** The characters from '0' to '9' */
59     private static final long[][] NUMBERS = new long[][] {
60         /* 0 */ new long[] { DASH, GAP, DASH, GAP, DASH, GAP, DASH, GAP, DASH },
61         /* 1 */ new long[] { DOT, GAP, DASH, GAP, DASH, GAP, DASH, GAP, DASH },
62         /* 2 */ new long[] { DOT, GAP, DOT, GAP, DASH, GAP, DASH, GAP, DASH },
63         /* 3 */ new long[] { DOT, GAP, DOT, GAP, DOT, GAP, DASH, GAP, DASH },
64         /* 4 */ new long[] { DOT, GAP, DOT, GAP, DOT, GAP, DOT, GAP, DASH },
65         /* 5 */ new long[] { DOT, GAP, DOT, GAP, DOT, GAP, DOT, GAP, DOT },
66         /* 6 */ new long[] { DASH, GAP, DOT, GAP, DOT, GAP, DOT, GAP, DOT },
67         /* 7 */ new long[] { DASH, GAP, DASH, GAP, DOT, GAP, DOT, GAP, DOT },
68         /* 8 */ new long[] { DASH, GAP, DASH, GAP, DASH, GAP, DOT, GAP, DOT },
69         /* 9 */ new long[] { DASH, GAP, DASH, GAP, DASH, GAP, DASH, GAP, DOT },
70     };
71 
72     private static final long[] ERROR_GAP = new long[] { GAP };
73 
74     /** Return the pattern data for a given character */
pattern(char c)75     static long[] pattern(char c) {
76         if (c >= 'A' && c <= 'Z') {
77             return LETTERS[c - 'A'];
78         }
79         if (c >= 'a' && c <= 'z') {
80             return LETTERS[c - 'a'];
81         }
82         else if (c >= '0' && c <= '9') {
83             return NUMBERS[c - '0'];
84         }
85         else {
86             return ERROR_GAP;
87         }
88     }
89 
pattern(String str)90     static long[] pattern(String str) {
91         boolean lastWasWhitespace;
92         int strlen = str.length();
93 
94         // Calculate how long our array needs to be.
95         int len = 1;
96         lastWasWhitespace = true;
97         for (int i=0; i<strlen; i++) {
98             char c = str.charAt(i);
99             if (Character.isWhitespace(c)) {
100                 if (!lastWasWhitespace) {
101                     len++;
102                     lastWasWhitespace = true;
103                 }
104             } else {
105                 if (!lastWasWhitespace) {
106                     len++;
107                 }
108                 lastWasWhitespace = false;
109                 len += pattern(c).length;
110             }
111         }
112 
113         // Generate the pattern array.  Note that we put an extra element of 0
114         // in at the beginning, because the pattern always starts with the pause,
115         // not with the vibration.
116         long[] result = new long[len+1];
117         result[0] = 0;
118         int pos = 1;
119         lastWasWhitespace = true;
120         for (int i=0; i<strlen; i++) {
121             char c = str.charAt(i);
122             if (Character.isWhitespace(c)) {
123                 if (!lastWasWhitespace) {
124                     result[pos] = WORD_GAP;
125                     pos++;
126                     lastWasWhitespace = true;
127                 }
128             } else {
129                 if (!lastWasWhitespace) {
130                     result[pos] = LETTER_GAP;
131                     pos++;
132                 }
133                 lastWasWhitespace = false;
134                 long[] letter = pattern(c);
135                 System.arraycopy(letter, 0, result, pos, letter.length);
136                 pos += letter.length;
137             }
138         }
139         return result;
140     }
141 }
142