CODE128.js 3.2 KB

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