"use strict";
|
Object.defineProperty(exports, "__esModule", { value: true });
|
exports.C40Encoder = void 0;
|
var StringBuilder_1 = require("../../util/StringBuilder");
|
var HighLevelEncoder_1 = require("./HighLevelEncoder");
|
var constants_1 = require("./constants");
|
var C40Encoder = /** @class */ (function () {
|
function C40Encoder() {
|
}
|
C40Encoder.prototype.getEncodingMode = function () {
|
return constants_1.C40_ENCODATION;
|
};
|
C40Encoder.prototype.encodeMaximal = function (context) {
|
var buffer = new StringBuilder_1.default();
|
var lastCharSize = 0;
|
var backtrackStartPosition = context.pos;
|
var backtrackBufferLength = 0;
|
while (context.hasMoreCharacters()) {
|
var c = context.getCurrentChar();
|
context.pos++;
|
lastCharSize = this.encodeChar(c, buffer);
|
if (buffer.length() % 3 === 0) {
|
backtrackStartPosition = context.pos;
|
backtrackBufferLength = buffer.length();
|
}
|
}
|
if (backtrackBufferLength !== buffer.length()) {
|
var unwritten = Math.floor((buffer.length() / 3) * 2);
|
var curCodewordCount = Math.floor(context.getCodewordCount() + unwritten + 1); // +1 for the latch to C40
|
context.updateSymbolInfo(curCodewordCount);
|
var available = context.getSymbolInfo().getDataCapacity() - curCodewordCount;
|
var rest = Math.floor(buffer.length() % 3);
|
if ((rest === 2 && available !== 2) ||
|
(rest === 1 && (lastCharSize > 3 || available !== 1))) {
|
// buffer.setLength(backtrackBufferLength);
|
context.pos = backtrackStartPosition;
|
}
|
}
|
if (buffer.length() > 0) {
|
context.writeCodeword(constants_1.LATCH_TO_C40);
|
}
|
this.handleEOD(context, buffer);
|
};
|
C40Encoder.prototype.encode = function (context) {
|
// step C
|
var buffer = new StringBuilder_1.default();
|
while (context.hasMoreCharacters()) {
|
var c = context.getCurrentChar();
|
context.pos++;
|
var lastCharSize = this.encodeChar(c, buffer);
|
var unwritten = Math.floor(buffer.length() / 3) * 2;
|
var curCodewordCount = context.getCodewordCount() + unwritten;
|
context.updateSymbolInfo(curCodewordCount);
|
var available = context.getSymbolInfo().getDataCapacity() - curCodewordCount;
|
if (!context.hasMoreCharacters()) {
|
// Avoid having a single C40 value in the last triplet
|
var removed = new StringBuilder_1.default();
|
if (buffer.length() % 3 === 2 && available !== 2) {
|
lastCharSize = this.backtrackOneCharacter(context, buffer, removed, lastCharSize);
|
}
|
while (buffer.length() % 3 === 1 &&
|
(lastCharSize > 3 || available !== 1)) {
|
lastCharSize = this.backtrackOneCharacter(context, buffer, removed, lastCharSize);
|
}
|
break;
|
}
|
var count = buffer.length();
|
if (count % 3 === 0) {
|
var newMode = HighLevelEncoder_1.default.lookAheadTest(context.getMessage(), context.pos, this.getEncodingMode());
|
if (newMode !== this.getEncodingMode()) {
|
// Return to ASCII encodation, which will actually handle latch to new mode
|
context.signalEncoderChange(constants_1.ASCII_ENCODATION);
|
break;
|
}
|
}
|
}
|
this.handleEOD(context, buffer);
|
};
|
C40Encoder.prototype.backtrackOneCharacter = function (context, buffer, removed, lastCharSize) {
|
var count = buffer.length();
|
var test = buffer.toString().substring(0, count - lastCharSize);
|
buffer.setLengthToZero();
|
buffer.append(test);
|
// buffer.delete(count - lastCharSize, count);
|
/*for (let i = count - lastCharSize; i < count; i++) {
|
buffer.deleteCharAt(i);
|
}*/
|
context.pos--;
|
var c = context.getCurrentChar();
|
lastCharSize = this.encodeChar(c, removed);
|
context.resetSymbolInfo(); // Deal with possible reduction in symbol size
|
return lastCharSize;
|
};
|
C40Encoder.prototype.writeNextTriplet = function (context, buffer) {
|
context.writeCodewords(this.encodeToCodewords(buffer.toString()));
|
var test = buffer.toString().substring(3);
|
buffer.setLengthToZero();
|
buffer.append(test);
|
// buffer.delete(0, 3);
|
/*for (let i = 0; i < 3; i++) {
|
buffer.deleteCharAt(i);
|
}*/
|
};
|
/**
|
* Handle "end of data" situations
|
*
|
* @param context the encoder context
|
* @param buffer the buffer with the remaining encoded characters
|
*/
|
C40Encoder.prototype.handleEOD = function (context, buffer) {
|
var unwritten = Math.floor((buffer.length() / 3) * 2);
|
var rest = buffer.length() % 3;
|
var curCodewordCount = context.getCodewordCount() + unwritten;
|
context.updateSymbolInfo(curCodewordCount);
|
var available = context.getSymbolInfo().getDataCapacity() - curCodewordCount;
|
if (rest === 2) {
|
buffer.append('\0'); // Shift 1
|
while (buffer.length() >= 3) {
|
this.writeNextTriplet(context, buffer);
|
}
|
if (context.hasMoreCharacters()) {
|
context.writeCodeword(constants_1.C40_UNLATCH);
|
}
|
}
|
else if (available === 1 && rest === 1) {
|
while (buffer.length() >= 3) {
|
this.writeNextTriplet(context, buffer);
|
}
|
if (context.hasMoreCharacters()) {
|
context.writeCodeword(constants_1.C40_UNLATCH);
|
}
|
// else no unlatch
|
context.pos--;
|
}
|
else if (rest === 0) {
|
while (buffer.length() >= 3) {
|
this.writeNextTriplet(context, buffer);
|
}
|
if (available > 0 || context.hasMoreCharacters()) {
|
context.writeCodeword(constants_1.C40_UNLATCH);
|
}
|
}
|
else {
|
throw new Error('Unexpected case. Please report!');
|
}
|
context.signalEncoderChange(constants_1.ASCII_ENCODATION);
|
};
|
C40Encoder.prototype.encodeChar = function (c, sb) {
|
if (c === ' '.charCodeAt(0)) {
|
sb.append(3);
|
return 1;
|
}
|
if (c >= '0'.charCodeAt(0) && c <= '9'.charCodeAt(0)) {
|
sb.append(c - 48 + 4);
|
return 1;
|
}
|
if (c >= 'A'.charCodeAt(0) && c <= 'Z'.charCodeAt(0)) {
|
sb.append(c - 65 + 14);
|
return 1;
|
}
|
if (c < ' '.charCodeAt(0)) {
|
sb.append(0); // Shift 1 Set
|
sb.append(c);
|
return 2;
|
}
|
if (c <= '/'.charCodeAt(0)) {
|
sb.append(1); // Shift 2 Set
|
sb.append(c - 33);
|
return 2;
|
}
|
if (c <= '@'.charCodeAt(0)) {
|
sb.append(1); // Shift 2 Set
|
sb.append(c - 58 + 15);
|
return 2;
|
}
|
if (c <= '_'.charCodeAt(0)) {
|
sb.append(1); // Shift 2 Set
|
sb.append(c - 91 + 22);
|
return 2;
|
}
|
if (c <= 127) {
|
sb.append(2); // Shift 3 Set
|
sb.append(c - 96);
|
return 2;
|
}
|
sb.append(1 + "\u001E"); // Shift 2, Upper Shift
|
var len = 2;
|
len += this.encodeChar(c - 128, sb);
|
return len;
|
};
|
C40Encoder.prototype.encodeToCodewords = function (sb) {
|
var v = 1600 * sb.charCodeAt(0) + 40 * sb.charCodeAt(1) + sb.charCodeAt(2) + 1;
|
var cw1 = v / 256;
|
var cw2 = v % 256;
|
var result = new StringBuilder_1.default();
|
result.append(cw1);
|
result.append(cw2);
|
return result.toString();
|
};
|
return C40Encoder;
|
}());
|
exports.C40Encoder = C40Encoder;
|