package org.simpleflatmapper.csv.parser;

public class UnescapeCellPreProcessor extends CellPreProcessor {

    private char escapeChar;
    private char quoteChar;

    public UnescapeCellPreProcessor(char escapeChar, char quoteChar) {
        this.escapeChar = escapeChar;
        this.quoteChar = quoteChar;
    }


    public final void newCell(char[] chars, int start, int end, CellConsumer cellConsumer, int state) {
        if ((state & CharConsumer.QUOTED) == 0) {
            cellConsumer.newCell(chars, start, end - start);
        } else {
            unescape(chars, start + 1, end, cellConsumer);
        }
    }

    private void unescape(final char[] chars, int start, int end, CellConsumer cellConsumer) {
        for(int i = start; i < end - 1; i++) {
            if (chars[i] == escapeChar) {
                int destIndex = i;
                boolean escaped = true;
                for(i = i +1 ;i < end -1; i++) {
                    char c = chars[i];
                    if (!escaped) {
                        if (c != escapeChar) {
                            chars[destIndex++] = c;
                        } else {
                            escaped = true;
                        }
                    } else {
                        chars[destIndex++] = unescapeChar(c);
                        escaped = false;
                    }
                }
                char c = chars[end - 1];
                if (c != quoteChar || escaped) {
                    chars[destIndex++] = c;
                }
                cellConsumer.newCell(chars, start, destIndex - start);
                return;
            }
        }

        int l = end - start;
        if (l >0 && chars[end -1] == quoteChar) {
            l --;
        }
        cellConsumer.newCell(chars, start, l);
    }

    private char unescapeChar(char c) {
        if (escapeChar == '\\') {
            switch (c) {
                case 'n':
                    return '\n';
                case 'r':
                    return '\r';
                case 't':
                    return '\t';
                case 'b':
                    return '\b';
                case 'f':
                    return '\f';
                case 'v':
                    return 0x0B;
            }
        }
        return c;
    }

    @Override
    public final boolean ignoreLeadingSpace() {
        return false;
    }

}

@@ -824,25 +824,206 @@
     
-int destIndex = i
+shiftEscapedChar(chars, start, end, cellConsumer, i);%0A                return;%0A            %7D%0A        %7D%0A%0A        int l = end - start;%0A        if (l %3E0 && chars%5Bend -1%5D == quoteChar) %7B%0A            l --
 ;%0A  
@@ -1028,24 +1028,26 @@
         
+%7D%0A
         
 boolean 
@@ -1042,57 +1042,271 @@
     
-boolean escaped = true;%0A                for(i = i
+cellConsumer.newCell(chars, start, l);%0A    %7D%0A%0A    private void shiftEscapedChar(char%5B%5D chars, int start, int end, CellConsumer cellConsumer, int currentIndex) %7B%0A        int destIndex = currentIndex;%0A        boolean escaped = true;%0A        for(int i = currentIndex
  +1 
@@ -1333,32 +1333,24 @@
             
-        
 char c = cha
@@ -1364,32 +1364,24 @@
             
- 
-       
 if (!escaped
@@ -1396,32 +1396,24 @@
             
-     
-   
 if (c != esc
@@ -1419,32 +1419,24 @@
 capeChar) %7B%0A
-        
             
@@ -1479,32 +1479,24 @@
             
- 
-       
 %7D else %7B%0A   
@@ -1488,32 +1488,24 @@
    %7D else %7B%0A
-        
             
@@ -1528,24 +1528,16 @@
 = true;%0A
-        
         
@@ -1554,32 +1554,24 @@
             
-        
 %7D else %7B%0A   
@@ -1563,32 +1563,24 @@
    %7D else %7B%0A
-        
             
@@ -1621,24 +1621,16 @@
 har(c);%0A
-        
         
@@ -1658,32 +1658,34 @@
 se;%0A            
+%7D%0A
         %7D%0A      
@@ -1682,41 +1682,16 @@
   %7D%0A
-                %7D%0A       
         
  cha
@@ -1678,33 +1678,32 @@
       %7D%0A        
- 
 char c = chars%5Be
@@ -1711,24 +1711,16 @@
 d - 1%5D;%0A
-        
         
@@ -1760,32 +1760,24 @@
             
-   
-     
 chars%5BdestIn
@@ -1796,34 +1796,18 @@
         
-       
- 
 %7D%0A
-        
         
@@ -1865,211 +1865,8 @@
 t);%0A
-                return;%0A            %7D%0A        %7D%0A%0A        int l = end - start;%0A        if (l %3E0 && chars%5Bend -1%5D == quoteChar) %7B%0A            l --;%0A        %7D%0A        cellConsumer.newCell(chars, start, l);%0A
     

move char shifting in its own method