// 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.Data; using System.Drawing; namespace Spludlow.Drawing { /// /// Delivery Point Suffix (DPS), a checksum character, and a stop character. The DPS is a two-character code ranging from 1A to 9T, with codes 9U to 9Z being accepted as default codes when no DPS has been allocated /// public class RM4SCC : IBarCode { private static DataTable Data; private static DataTable CheckSums; // change to use dictionaries !!!!!!!!!!!!!!!!!!!!!!!!!!!! private static string CacheKey = "Spludlow.RM4SCC"; static RM4SCC() { DataSet dataSet = (DataSet)Spludlow.Caching.Get(CacheKey); if (dataSet == null) { dataSet = new DataSet(); DataTable table; table = Spludlow.Data.TextTable.ReadFile(Spludlow.Config.ProgramData + @"\Data\BarCodeRM4SCC.txt"); table.TableName = "Data"; dataSet.Tables.Add(table); table = Spludlow.Data.TextTable.ReadFile(Spludlow.Config.ProgramData + @"\Data\BarCodeRM4SCCchecksum.txt"); table.TableName = "CheckSums"; dataSet.Tables.Add(table); Spludlow.Caching.Set(CacheKey, dataSet); } Data = dataSet.Tables["Data"]; CheckSums = dataSet.Tables["CheckSums"]; } public RM4SCC() { } public string EncodeData(string data) { data = PreparePostCode(data); // Aloow passing of DPS StringBuilder result = new StringBuilder(); foreach (char character in data) { DataRow row = Data.Rows.Find(character.ToString()); if (row == null) throw new ApplicationException("BarCodeRM4SCC Encode character not found:\t" + character.ToString()); result.Append((string)row[1]); } return result.ToString(); } public bool[][] Encode(string data) { data = this.EncodeData(data); bool[][] result = new bool[3][]; for (int row = 0; row < 3; ++row) result[row] = new bool[data.Length * 2 + 1]; for (int index = 0; index < data.Length; ++index) { int targetIndex = index * 2 + 1; switch (data[index]) { case 'T': result[0][targetIndex] = true; result[1][targetIndex] = true; //result[2][targetIndex] = false; break; case 'B': //result[0][targetIndex] = false; result[1][targetIndex] = true; result[2][targetIndex] = true; break; case 'L': result[0][targetIndex] = true; result[1][targetIndex] = true; result[2][targetIndex] = true; break; case 'S': //result[0][targetIndex] = false; result[1][targetIndex] = true; //result[2][targetIndex] = false; break; default: throw new ApplicationException("RM4SCC Encode Unknown character: " + data[index].ToString()); } } return result; } public static string PreparePostCode(string postcode) { return PreparePostCode(postcode, "9Z"); } public static string PreparePostCode(string postcode, string dps) { StringBuilder result = new StringBuilder(postcode.ToUpper()); result.Replace(" ", ""); result.Append(dps); string postCodeAndDps = result.ToString(); result.Length = 0; result.Append("("); result.Append(postCodeAndDps); result.Append(CheckSum(postCodeAndDps)); result.Append(")"); return result.ToString(); } private static string CheckSum(string checkString) { int rowTotal = 0; int columnTotal = 0; foreach (char ch in checkString) { bool found = false; foreach (DataRow row in CheckSums.Rows) { for (int colIndex = 1; colIndex < CheckSums.Columns.Count; ++colIndex) { if (ch == ((string)row[colIndex])[0]) { rowTotal += (int)row["Row"]; columnTotal += Int32.Parse(row.Table.Columns[colIndex].ColumnName); found = true; break; } } if (found == true) break; } if (found == false) throw new ApplicationException("BarCodeRM4SCC Could not find CheckSum:\t" + ch.ToString() + "\t" + checkString); } int rowRemainder = rowTotal % 6; int columnRemainder = columnTotal % 6; DataRow checkRow = CheckSums.Rows.Find(rowRemainder.ToString()); return (string)checkRow[columnRemainder.ToString()]; } } }