001package org.unix4j.unix.sed; 002 003import java.util.HashMap; 004import java.util.Map; 005 006/** 007 * A map from char to char. The mappings for the most common 256 source 008 * characters are simply kept in a char array. For all other more exotic source 009 * characters, a proper hash map is used to store the mapping. 010 */ 011class CharMap { 012 013 private final char[] map = new char[256]; 014 private final Map<Character, Character> extendedMap = new HashMap<Character, Character>(); 015 016 /** 017 * Creates a char map with the given source and destination characters. If 018 * the strings do not have the same length, subsequent characters in the 019 * longer string are ignored. The first mapping is defined as 020 * {@code source[0] --> destination[0]}, all other mappings in an analogous 021 * way with matching character indices in the two strings. 022 * 023 * @param source 024 * source characters 025 * @param destination 026 * destination characters 027 * @throws IllegalArgumentException 028 * if any of the destination characters is the zero character 029 */ 030 public CharMap(String source, String destination) { 031 add(source, destination); 032 } 033 034 /** 035 * Adds the given source and destination characters to this char map.. If 036 * the strings do not have the same length, subsequent characters in the 037 * longer string are ignored. The first mapping is defined as 038 * {@code source[0] --> destination[0]}, all other mappings in an analogous 039 * way with matching character indices in the two strings. 040 * 041 * @param source 042 * source characters 043 * @param destination 044 * destination characters 045 * @throws IllegalArgumentException 046 * if any of the destination characters is the zero character 047 */ 048 public void add(String source, String destination) { 049 final int len = Math.min(source.length(), destination.length()); 050 for (int i = 0; i < len; i++) { 051 add(source.charAt(i), destination.charAt(i)); 052 } 053 } 054 055 /** 056 * Adds the given mapping {@code source --> destination} to this char map. 057 * 058 * @param source 059 * source character 060 * @param destination 061 * destination character 062 * @throws IllegalArgumentException 063 * if the destination character is the zero character 064 */ 065 public void add(char source, char destination) { 066 if (destination == 0) { 067 throw new IllegalArgumentException("cannot map to zero character"); 068 } 069 if (source < 256) { 070 map[source] = destination; 071 } else { 072 extendedMap.put(source, destination); 073 } 074 } 075 076 public char map(char source) { 077 if (source < 256) { 078 return map[source]; 079 } 080 final Character mapped = extendedMap.get(source); 081 return mapped == null ? 0 : mapped.charValue(); 082 } 083}