Completed
Push — master ( cd5721...aa00db )
by Johan
14s
created

CODE128.js ➔ ???   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 1
c 5
b 0
f 0
nc 1
nop 2
dl 0
loc 7
rs 9.4285

1 Function

Rating   Name   Duplication   Size   Complexity  
A CODE128.js ➔ ... ➔ ??? 0 1 1
1
import Barcode from "../Barcode.js";
2
import { SHIFT, SET_A, SET_B, MODULO, STOP, SET_BY_CODE, SWAP, BARS } from './constants';
3
4
// This is the master class,
5
// it does require the start code to be included in the string
6
class CODE128 extends Barcode {
7
	constructor(data, options) {
8
		super(data.substring(1), options);
9
10
		// Get array of ascii codes from data
11
		this.bytes = data.split('')
12
			.map(char => char.charCodeAt(0));
13
	}
14
15
	valid() {
16
		// ASCII value ranges 0-127, 200-211
17
		return /^[\x00-\x7F\xC8-\xD3]+$/.test(this.data);
18
	}
19
20
	// The public encoding function
21
	encode() {
22
		const bytes = this.bytes;
23
		// Remove the start code from the bytes and set its index
24
		const startIndex = bytes.shift() - 105;
25
		// Get start set by index
26
		const startSet = SET_BY_CODE[startIndex];
27
28
		if (startSet === undefined) {
29
			throw new RangeError('The encoding does not start with a start character.');
30
		}
31
32
		// Start encode with the right type
33
		const encodingResult = CODE128.next(bytes, 1, startSet);
34
35
		return {
36
			text:
37
				this.text === this.data
38
					? this.text.replace(/[^\x20-\x7E]/g, '')
39
					: this.text,
40
			data:
41
				// Add the start bits
42
				CODE128.getBar(startIndex) +
43
				// Add the encoded bits
44
				encodingResult.result +
45
				// Add the checksum
46
				CODE128.getBar((encodingResult.checksum + startIndex) % MODULO) +
47
				// Add the end bits
48
				CODE128.getBar(STOP)
49
		};
50
	}
51
52
	// Get a bar symbol by index
53
	static getBar(index) {
54
		return BARS[index] ? BARS[index].toString() : '';
55
	}
56
57
	// Correct an index by a set and shift it from the bytes array
58
	static correctIndex(bytes, set) {
59
		if (set === SET_A) {
60
			const charCode = bytes.shift();
61
			return charCode < 32 ? charCode + 64 : charCode - 32;
62
		} else if (set === SET_B) {
63
			return bytes.shift() - 32;
64
		} else {
65
			return (bytes.shift() - 48) * 10 + bytes.shift() - 48;
66
		}
67
	}
68
69
	static next(bytes, pos, set) {
70
		if (!bytes.length) {
71
			return { result: '', checksum: 0 };
72
		}
73
74
		let nextCode, index;
75
76
		// Special characters
77
		if (bytes[0] >= 200){
78
			index = bytes.shift() - 105;
79
			const nextSet = SWAP[index];
80
81
			// Swap to other set
82
			if (nextSet !== undefined) {
83
				nextCode = CODE128.next(bytes, pos + 1, nextSet);
84
			}
85
			// Continue on current set but encode a special character
86
			else {
87
				// Shift
88
				if ((set === SET_A || set === SET_B) && index === SHIFT) {
89
					// Convert the next character so that is encoded correctly
90
					bytes[0] = (set === SET_A)
91
						? bytes[0] > 95 ? bytes[0] - 96 : bytes[0]
92
						: bytes[0] < 32 ? bytes[0] + 96 : bytes[0];
93
				}
94
				nextCode = CODE128.next(bytes, pos + 1, set);
95
			}
96
		}
97
		// Continue encoding
98
		else {
99
			index = CODE128.correctIndex(bytes, set);
100
			nextCode = CODE128.next(bytes, pos + 1, set);
101
		}
102
103
		// Get the correct binary encoding and calculate the weight
104
		const enc = CODE128.getBar(index);
105
		const weight = index * pos;
106
107
		return {
108
			result: enc + nextCode.result,
109
			checksum: weight + nextCode.checksum
110
		};
111
	}
112
}
113
114
export default CODE128;
115