/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

package foam.lib.json;

import foam.lib.parse.*;

public class StringParser implements Parser {
  public final static char ESCAPE = '\\';

  protected char delim_;

  public StringParser() {
  }

  public PStream parse(PStream ps, ParserContext x) {
    delim_ = ps.head();

    if ( delim_ != '"' && delim_ != '\'' ) {
      return null;
    }

    ps = ps.tail();
    char lastc = delim_;

    StringBuilder sb = new StringBuilder();

    while ( ps.valid() ) {
      char c = ps.head();
      if ( c == delim_ && lastc != ESCAPE ) {
        break;
      }

      if ( c != ESCAPE ) sb.append(c);

      PStream tail = ps.tail();

      if ( c == '\\' ) {
        char nextChar = ps.tail().head();
        Parser escapeSeqParser = null;

        if ( nextChar == 'u' ) {
          escapeSeqParser = new UnicodeParser();
        } else if ( nextChar == 'n' ) {
          escapeSeqParser = new ASCIIEscapeParser();
        }

        if ( escapeSeqParser != null ) {
          PStream escapePS = escapeSeqParser.parse(ps, x);

          if ( escapePS != null ) {
            sb.append(escapePS.value());
            tail = escapePS;

            c = ((Character) escapePS.value()).charValue();
          }
        }
      }

      ps = tail;
      lastc = c;
    }

    return ps.tail().setValue(sb.toString());
  }
}

@@ -260,34 +260,8 @@
 ';%0A%0A
-  protected char delim_;%0A%0A
   pu
@@ -345,22 +345,26 @@
 ) %7B%0A    
+char 
 delim
-_
  = ps.he
@@ -380,25 +380,24 @@
   if ( delim
-_
  != '%22' && d
@@ -400,17 +400,16 @@
 && delim
-_
  != '%5C''
@@ -410,24 +410,16 @@
 = '%5C'' )
- %7B%0A     
  return 
@@ -423,22 +423,16 @@
 rn null;
-%0A    %7D
 %0A%0A    ps
@@ -471,12 +471,80 @@
 elim
-_
 ;%0A%0A
+    // TODO: use thread-local SB instead to avoid generating garbage%0A
     
@@ -633,24 +633,25 @@
  ps.head();%0A
+%0A
       if ( c
@@ -663,9 +663,8 @@
 elim
-_
  && 
@@ -685,71 +685,13 @@
 E ) 
-%7B%0A        break;%0A      %7D%0A%0A      if ( c != ESCAPE ) sb.append(c)
+break
 ;%0A%0A 
@@ -738,20 +738,22 @@
  ( c == 
-'%5C%5C'
+ESCAPE
  ) %7B%0A   
@@ -762,16 +762,18 @@
    char 
+  
 nextChar
@@ -773,16 +773,23 @@
 extChar 
+       
 = ps.tai
@@ -869,24 +869,59 @@
  == 'u' ) %7B%0A
+          // TODO: make a constant%0A
           es
@@ -993,24 +993,59 @@
  == 'n' ) %7B%0A
+          // TODO: make a constant%0A
           es
@@ -1389,24 +1389,61 @@
    %7D%0A      %7D
+ else %7B%0A        sb.append(c);%0A      %7D
 %0A%0A      ps =

Add TODO's.