001package org.hl7.fhir.r4.formats;
002
003import java.io.IOException;
004import java.io.Writer;
005import java.math.BigDecimal;
006import java.util.Stack;
007
008import org.hl7.fhir.utilities.Utilities;
009
010/**
011 * A little implementation of a json write to replace Gson .... because Gson screws up decimal values, and *we care*
012 * 
013 * @author Grahame Grieve
014 *
015 */
016public class JsonCreatorDirect implements JsonCreator {
017
018  private Writer writer;
019  private boolean pretty;
020  private boolean named;
021  private boolean valued;
022  private int indent;
023  
024  public JsonCreatorDirect(Writer writer) {
025    super();
026    this.writer = writer;
027  }
028
029  @Override
030  public void setIndent(String indent) {
031    this.pretty = !Utilities.noString(indent);
032  }
033
034  @Override
035  public void beginObject() throws IOException {
036    checkState();
037    writer.write("{");
038    stepIn();
039  }
040
041  public void stepIn() throws IOException {
042    if (pretty) {
043      indent++;
044      writer.write("\r\n");
045      for (int i = 0; i < indent; i++) {
046        writer.write("  ");
047      }
048    }
049  }
050
051  public void stepOut() throws IOException {
052    if (pretty) {
053      indent--;
054      writer.write("\r\n");
055      for (int i = 0; i < indent; i++) {
056        writer.write("  ");
057      }
058    }
059  }
060
061  private void checkState() throws IOException {
062    if (named) {
063      if (pretty)
064        writer.write(" : ");
065      else
066        writer.write(":");
067      named = false;
068    }
069    if (valued) {
070      writer.write(",");
071      if (pretty) {
072        writer.write("\r\n");
073        for (int i = 0; i < indent; i++) {
074          writer.write("  ");
075        }        
076      }
077      valued = false;
078    }
079  }
080
081  @Override
082  public void endObject() throws IOException {
083    stepOut();
084    writer.write("}");    
085  }
086
087  @Override
088  public void nullValue() throws IOException {
089    checkState();
090    writer.write("null");
091    valued = true;
092  }
093
094  @Override
095  public void name(String name) throws IOException {
096    checkState();
097    writer.write("\""+name+"\"");
098    named = true;
099  }
100
101  @Override
102  public void value(String value) throws IOException {
103    checkState();
104    writer.write("\""+Utilities.escapeJson(value)+"\"");    
105    valued = true;
106  }
107
108  @Override
109  public void value(Boolean value) throws IOException {
110    checkState();
111    if (value == null)
112      writer.write("null");
113    else if (value.booleanValue())
114      writer.write("true");
115    else
116      writer.write("false");
117    valued = true;
118  }
119
120  @Override
121  public void value(BigDecimal value) throws IOException {
122    checkState();
123    if (value == null)
124      writer.write("null");
125    else 
126      writer.write(value.toString());    
127    valued = true;
128  }
129
130  @Override
131  public void valueNum(String value) throws IOException {
132    checkState();
133    if (value == null)
134      writer.write("null");
135    else 
136      writer.write(value);    
137    valued = true;
138  }
139
140  @Override
141  public void value(Integer value) throws IOException {
142    checkState();
143    if (value == null)
144      writer.write("null");
145    else 
146      writer.write(value.toString());    
147    valued = true;
148  }
149
150  @Override
151  public void beginArray() throws IOException {
152    checkState();
153    writer.write("[");    
154  }
155
156  @Override
157  public void endArray() throws IOException {
158    writer.write("]");        
159  }
160
161  @Override
162  public void finish() throws IOException {
163    // nothing
164  }
165
166  @Override
167  public void link(String href) {
168    // not used
169    
170  }
171
172}