// Spludlow Software // Copyright © Samuel P. Ludlow 2020 All Rights Reserved // Distributed under the terms of the GNU General Public License version 3 // Distributed WITHOUT ANY WARRANTY; without implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE // https://www.spludlow.co.uk/LICENCE.TXT // The Spludlow logo is a registered trademark of Samuel P. Ludlow and may not be used without permission // v1.14 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Data; using System.Drawing; namespace Spludlow.Drawing { public class BarCode128 : IBarCode { private class LookupDictionaries { public LookupDictionaries() { this.ValueWeights = new Dictionary(); this.CharacterValue = new Dictionary>(); foreach (string code in new string[] { "A", "B", "C" }) this.CharacterValue.Add(code, new Dictionary()); } public Dictionary ValueWeights; public Dictionary> CharacterValue; } private LookupDictionaries Lookup; private string CodeSet; private string CacheKey = "Spludlow.BarCode128"; public BarCode128() { this.CodeSet = "B"; this.Load(); } public BarCode128(string codeSet) { this.CodeSet = codeSet; this.Load(); } private void Load() { this.Lookup = (LookupDictionaries)Spludlow.Caching.Get(this.CacheKey); if (this.Lookup == null) { this.Lookup = new LookupDictionaries(); string fileName = Spludlow.Config.ProgramData + @"\Data\BarCode128.txt"; if (System.IO.File.Exists(fileName) == false) throw new ApplicationException("BarCode128 Data File not there.\t" + fileName); DataTable table = Spludlow.Data.TextTable.ReadFile(fileName); foreach (DataRow row in table.Rows) { int value = (int)row["Value"]; string weights = (string)row["Weights"]; this.Lookup.ValueWeights.Add(value, weights); foreach (string code in new string[] { "A", "B", "C" }) { string character = (string)row[code]; this.Lookup.CharacterValue[code].Add(character, value); } } Spludlow.Caching.Set(this.CacheKey, this.Lookup); } } public bool[][] Encode(string data) { return new bool[][] { this.EncodeBars(data) }; } public bool[] EncodeBars(string data) { int[] values = this.EncodeValues(data); List result = new List(); foreach (int value in values) result.AddRange(this.EncodeValue(value)); return result.ToArray(); } private int[] EncodeValues(string data) { int[] values; if (this.CodeSet == "C") { if (data.Length % 2 != 0) data = "0" + data; values = new int[(data.Length / 2) + 3]; for (int index = 0; index < data.Length; index += 2) values[1 + index / 2] = this.FindValue(new string(new char[] { data[index], data[index + 1] })); } else { values = new int[data.Length + 3]; for (int index = 0; index < data.Length; ++index) { string character = data[index].ToString(); values[index + 1] = this.FindValue(character); } } values[0] = this.FindValue("START " + this.CodeSet); values[values.Length - 2] = this.CheckSum(values); values[values.Length - 1] = this.FindValue("STOP"); return values; } private bool[] EncodeValue(int value) { string weights = this.Lookup.ValueWeights[value]; List result = new List(); bool on = true; foreach (char weightChar in weights) { int weight = Int32.Parse(weightChar.ToString()); for (int index = 0; index < weight; ++index) result.Add(on); on = !on; } return result.ToArray(); } private int FindValue(string data) { if (this.Lookup.CharacterValue[this.CodeSet].ContainsKey(data) == false) throw new ApplicationException("BarCode128; character not Found: '" + data + "', codeset:" + this.CodeSet); return this.Lookup.CharacterValue[this.CodeSet][data]; } private int CheckSum(int[] values) { int checkLength = values.Length - 2; int total = 0; for (int index = 0; index < checkLength; ++index) { int value = values[index]; if (index == 0) total += value; else total += value * index; } return total % 103; } } }