001package io.avaje.jsonb.stream;
002
003import io.avaje.jsonb.JsonReader;
004import io.avaje.jsonb.JsonWriter;
005import io.avaje.jsonb.spi.*;
006
007import java.io.*;
008import java.nio.charset.StandardCharsets;
009
010/**
011 * Default implementation of JsonStreamAdapter provided with Jsonb.
012 */
013public final class JsonStream implements JsonStreamAdapter {
014
015  private final boolean serializeNulls;
016  private final boolean serializeEmpty;
017  private final boolean failOnUnknown;
018
019  /**
020   * Create with the given default configuration.
021   */
022  public JsonStream() {
023    this(false, false, false);
024  }
025
026  /**
027   * Create additionally providing the jsonFactory.
028   */
029  public JsonStream(boolean serializeNulls, boolean serializeEmpty, boolean failOnUnknown) {
030    this.serializeNulls = serializeNulls;
031    this.serializeEmpty = serializeEmpty;
032    this.failOnUnknown = failOnUnknown;
033  }
034
035  @Override
036  public PropertyNames properties(String... names) {
037    return JsonNames.of(names);
038  }
039
040  @Override
041  public JsonReader reader(String json) {
042    return reader(json.getBytes(StandardCharsets.UTF_8));
043  }
044
045  @Override
046  public JsonReader reader(byte[] json) {
047    JsonParser parser = Recycle.parser(json);
048    return new JsonReadAdapter(parser, failOnUnknown);
049  }
050
051  @Override
052  public JsonReader reader(Reader reader) {
053    // TODO: Could recycle encoder and buffer
054    return reader(new ReaderInputStream(reader, StandardCharsets.UTF_8));
055  }
056
057  @Override
058  public JsonReader reader(InputStream inputStream) {
059    try {
060      JsonParser parser = Recycle.parser(inputStream);
061      return new JsonReadAdapter(parser, failOnUnknown);
062    } catch (IOException e) {
063      throw new UncheckedIOException(e);
064    }
065  }
066
067  @Override
068  public JsonWriter writer(Writer writer) {
069    // TODO: Could recycle buffer used
070    return writer(new WriterOutputStream(writer, StandardCharsets.UTF_8));
071  }
072
073  @Override
074  public JsonWriter writer(OutputStream outputStream) {
075    return wrap(gen(outputStream));
076  }
077
078  @Override
079  public BufferedJsonWriter bufferedWriter() {
080    JsonGenerator generator = Recycle.generator();
081    return new BufferedWriter(wrap(generator), generator);
082  }
083
084  @Override
085  public BytesJsonWriter bufferedWriterAsBytes() {
086    JsonGenerator generator = Recycle.generator();
087    return new BytesWriter(wrap(generator), generator);
088  }
089
090  private JsonGenerator gen(OutputStream outputStream) {
091    return Recycle.generator(outputStream);
092  }
093
094  private JsonWriteAdapter wrap(JsonGenerator generator) {
095    return new JsonWriteAdapter(generator, serializeNulls, serializeEmpty);
096  }
097
098  private static class BufferedWriter extends DelegateJsonWriter implements BufferedJsonWriter {
099
100    private final JsonGenerator generator;
101
102    BufferedWriter(JsonWriteAdapter delegate, JsonGenerator generator) {
103      super(delegate);
104      this.generator = generator;
105    }
106
107    @Override
108    public String result() {
109      return generator.toString();
110    }
111  }
112
113  private static class BytesWriter extends DelegateJsonWriter implements BytesJsonWriter {
114
115    private final JsonGenerator generator;
116
117    public BytesWriter(JsonWriteAdapter delegate, JsonGenerator generator) {
118      super(delegate);
119      this.generator = generator;
120    }
121
122    @Override
123    public byte[] result() {
124      return generator.toByteArray();
125    }
126  }
127}