001package org.unix4j.unix.sed; 002 003import org.unix4j.line.Line; 004import org.unix4j.line.SimpleLine; 005import org.unix4j.processor.LineProcessor; 006import org.unix4j.util.StringUtil; 007 008class TranslateProcessor extends AbstractSedProcessor { 009 private final CharMap charMap; 010 public TranslateProcessor(Command command, SedArguments args, LineProcessor output) { 011 super(command, args, output); 012 this.charMap = new CharMap(args.getString1(), args.getString2()); 013 } 014 public TranslateProcessor(Command command, String script, SedArguments args, LineProcessor output) { 015 this(command, deriveArgs(command, script, args), output); 016 } 017 018 private static SedArguments deriveArgs(Command command, String script, SedArguments args) { 019 final int start = StringUtil.findStartTrimWhitespace(script) + 1; 020 final int mid = indexOfNextDelimiter(script, start); 021 final int end = indexOfNextDelimiter(script, mid); 022 if (mid < 0 || end < 0) { 023 throw new IllegalArgumentException("invalid script for sed " + command + " command: " + script); 024 } 025 final int scriptEnd = StringUtil.findEndTrimWhitespace(script); 026 if (end + 1 < scriptEnd) { 027 throw new IllegalArgumentException("non-whitespace characters found after " + command + " command in sed script: " + script); 028 } 029 args.setString1(script.substring(start + 1, mid)); 030 args.setString2(script.substring(mid + 1, end)); 031 return args; 032 } 033 @Override 034 public boolean processLine(Line line) { 035 char[] changed = null; 036 final int len = line.getContentLength();//or whole line length? 037 for (int i = 0; i < len; i++) { 038 final char src = line.charAt(i); 039 final char dst = charMap.map(src); 040 if (dst != 0) { 041 if (changed == null) { 042 changed = new char[len]; 043 for (int j = 0; j < i; j++) { 044 changed[j] = line.charAt(j); 045 } 046 } 047 changed[i] = dst; 048 } else { 049 if (changed != null) { 050 changed[i] = src; 051 } 052 } 053 } 054 if (changed != null) { 055 final Line changedLine = new SimpleLine(String.valueOf(changed), line.getLineEnding()); 056 return output.processLine(changedLine); 057 } else { 058 return output.processLine(line); 059 } 060 } 061}