OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
181 ilm 1
/*
2
 * Copyright 2014 Robin Stuart
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5
 * in compliance with the License. You may obtain a copy of the License at
6
 *
7
 * http://www.apache.org/licenses/LICENSE-2.0
8
 *
9
 * Unless required by applicable law or agreed to in writing, software distributed under the License
10
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
 * or implied. See the License for the specific language governing permissions and limitations under
12
 * the License.
13
 */
14
package uk.org.okapibarcode.backend;
15
 
16
/**
17
 * <p>
18
 * Implements Telepen (also known as Telepen Alpha).
19
 *
20
 * <p>
21
 * Telepen can encode ASCII text input and includes a modulo-127 check digit. Telepen Numeric allows
22
 * compression of numeric data into a Telepen symbol. Data can consist of pairs of numbers or pairs
23
 * consisting of a numerical digit followed by an X character. Telepen Numeric also includes a
24
 * modulo-127 check digit.
25
 *
26
 * @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
27
 */
28
public class Telepen extends Symbol {
29
 
30
    public static enum Mode {
31
        NORMAL, NUMERIC
32
    }
33
 
34
    private static final String[] TELE_TABLE = { "1111111111111111", "1131313111", "33313111", "1111313131", "3111313111", "11333131", "13133131", "111111313111", "31333111", "1131113131", "33113131",
35
            "1111333111", "3111113131", "1113133111", "1311133111", "111111113131", "3131113111", "11313331", "333331", "111131113111", "31113331", "1133113111", "1313113111", "1111113331",
36
            "31131331", "113111113111", "3311113111", "1111131331", "311111113111", "1113111331", "1311111331", "11111111113111", "31313311", "1131311131", "33311131", "1111313311", "3111311131",
37
            "11333311", "13133311", "111111311131", "31331131", "1131113311", "33113311", "1111331131", "3111113311", "1113131131", "1311131131", "111111113311", "3131111131", "1131131311",
38
            "33131311", "111131111131", "3111131311", "1133111131", "1313111131", "111111131311", "3113111311", "113111111131", "3311111131", "111113111311", "311111111131", "111311111311",
39
            "131111111311", "11111111111131", "3131311111", "11313133", "333133", "111131311111", "31113133", "1133311111", "1313311111", "1111113133", "313333", "113111311111", "3311311111",
40
            "11113333", "311111311111", "11131333", "13111333", "11111111311111", "31311133", "1131331111", "33331111", "1111311133", "3111331111", "11331133", "13131133", "111111331111",
41
            "3113131111", "1131111133", "33111133", "111113131111", "3111111133", "111311131111", "131111131111", "111111111133", "31311313", "113131111111", "3331111111", "1111311313",
42
            "311131111111", "11331313", "13131313", "11111131111111", "3133111111", "1131111313", "33111313", "111133111111", "3111111313", "111313111111", "131113111111", "111111111313",
43
            "313111111111", "1131131113", "33131113", "11113111111111", "3111131113", "113311111111", "131311111111", "111111131113", "3113111113", "11311111111111", "331111111111", "111113111113",
44
            "31111111111111", "111311111113", "131111111113" };
45
 
46
    private Mode mode = Mode.NORMAL;
47
 
48
    public void setMode(final Mode mode) {
49
        this.mode = mode;
50
    }
51
 
52
    public Mode getMode() {
53
        return this.mode;
54
    }
55
 
56
    @Override
57
    protected void encode() {
58
        if (this.mode == Mode.NORMAL) {
59
            normal_mode();
60
        } else {
61
            numeric_mode();
62
        }
63
    }
64
 
65
    private void normal_mode() {
66
        int count = 0, asciicode, check_digit;
67
        String p = "";
68
        String dest;
69
 
70
        final int l = this.content.length();
71
 
72
        if (!this.content.matches("[\u0000-\u007F]+")) {
73
            throw new OkapiException("Invalid characters in input data");
74
        }
75
 
76
        dest = TELE_TABLE['_']; // Start
77
        for (int i = 0; i < l; i++) {
78
            asciicode = this.content.charAt(i);
79
            p += TELE_TABLE[asciicode];
80
            count += asciicode;
81
        }
82
 
83
        check_digit = 127 - count % 127;
84
        if (check_digit == 127) {
85
            check_digit = 0;
86
        }
87
 
88
        p += TELE_TABLE[check_digit];
89
 
90
        infoLine("Check Digit: " + check_digit);
91
 
92
        dest += p;
93
        dest += TELE_TABLE['z']; // Stop
94
 
95
        this.readable = this.content;
96
        this.pattern = new String[1];
97
        this.pattern[0] = dest;
98
        this.row_count = 1;
99
        this.row_height = new int[1];
100
        this.row_height[0] = -1;
101
    }
102
 
103
    private void numeric_mode() {
104
        int count = 0, check_digit;
105
        String p = "";
106
        String t;
107
        String dest;
108
        final int l = this.content.length();
109
        int tl, glyph;
110
        char c1, c2;
111
 
112
        // FIXME: Ensure no extended ASCII or Unicode characters are entered
113
        if (!this.content.matches("[0-9X]+")) {
114
            throw new OkapiException("Invalid characters in input");
115
        }
116
 
117
        /* If input is an odd length, add a leading zero */
118
        if ((l & 1) == 1) {
119
            t = "0" + this.content;
120
            tl = l + 1;
121
        } else {
122
            t = this.content;
123
            tl = l;
124
        }
125
 
126
        dest = TELE_TABLE['_']; // Start
127
        for (int i = 0; i < tl; i += 2) {
128
 
129
            c1 = t.charAt(i);
130
            c2 = t.charAt(i + 1);
131
 
132
            /* Input nX is allowed, but Xn is not */
133
            if (c1 == 'X') {
134
                throw new OkapiException("Invalid position of X in data");
135
            }
136
 
137
            if (c2 == 'X') {
138
                glyph = c1 - '0' + 17;
139
                count += glyph;
140
            } else {
141
                glyph = 10 * (c1 - '0') + c2 - '0' + 27;
142
                count += glyph;
143
            }
144
 
145
            p += TELE_TABLE[glyph];
146
        }
147
 
148
        check_digit = 127 - count % 127;
149
        if (check_digit == 127) {
150
            check_digit = 0;
151
        }
152
 
153
        p += TELE_TABLE[check_digit];
154
 
155
        infoLine("Check Digit: " + check_digit);
156
 
157
        dest += p;
158
        dest += TELE_TABLE['z']; // Stop
159
        this.readable = this.content;
160
        this.pattern = new String[1];
161
        this.pattern[0] = dest;
162
        this.row_count = 1;
163
        this.row_height = new int[1];
164
        this.row_height[0] = -1;
165
    }
166
}