[
https://issues.apache.org/jira/browse/AVRO-3001?focusedWorklogId=802496&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-802496
]
ASF GitHub Bot logged work on AVRO-3001:
----------------------------------------
Author: ASF GitHub Bot
Created on: 22/Aug/22 14:50
Start Date: 22/Aug/22 14:50
Worklog Time Spent: 10m
Work Description: rayokota commented on code in PR #1833:
URL: https://github.com/apache/avro/pull/1833#discussion_r951537746
##########
lang/csharp/src/apache/main/IO/JsonEncoder.cs:
##########
@@ -0,0 +1,360 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Avro.IO.Parsing;
+using System.Collections;
+using System.IO;
+using System.Text;
+using Newtonsoft.Json;
+
+namespace Avro.IO
+{
+ /// <summary>
+ /// An <seealso cref="Encoder"/> for Avro's JSON data encoding.
+ ///
+ /// JsonEncoder buffers output, and data may not appear on the output until
+ /// <seealso cref="Encoder.Flush()"/> is called.
+ ///
+ /// JsonEncoder is not thread-safe.
+ /// </summary>
+ public class JsonEncoder : ParsingEncoder, Parser.ActionHandler
+ {
+ private readonly Parser parser;
+ private JsonWriter writer;
+ private bool includeNamespace = true;
+
+ // Has anything been written into the collections?
+ private readonly BitArray isEmpty = new BitArray(64);
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="JsonEncoder"/> class.
+ /// </summary>
+ public JsonEncoder(Schema sc, Stream stream) : this(sc,
getJsonWriter(stream, false))
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="JsonEncoder"/> class.
+ /// </summary>
+ public JsonEncoder(Schema sc, Stream stream, bool pretty) : this(sc,
getJsonWriter(stream, pretty))
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="JsonEncoder"/> class.
+ /// </summary>
+ public JsonEncoder(Schema sc, JsonWriter writer)
+ {
+ Configure(writer);
+ this.parser = new Parser((new
JsonGrammarGenerator()).Generate(sc), this);
+ }
+
+ /// <inheritdoc />
+ public override void Flush()
+ {
+ parser.ProcessImplicitActions();
+ if (writer != null)
+ {
+ writer.Flush();
+ }
+ }
+
+ // by default, one object per line.
+ // with pretty option use default pretty printer with root line
separator.
+ private static JsonWriter getJsonWriter(Stream stream, bool pretty)
+ {
+ JsonWriter writer = new JsonTextWriter(new StreamWriter(stream));
+ if (pretty)
+ {
+ writer.Formatting = Formatting.Indented;
+ }
+
+ return writer;
+ }
+
+ /// <summary>
+ /// Whether to include the namespace.
+ /// </summary>
+ public virtual bool IncludeNamespace
+ {
+ get { return includeNamespace; }
+ set { this.includeNamespace = value; }
+ }
+
+
+ /// <summary>
+ /// Reconfigures this JsonEncoder to use the output stream provided.
+ /// <p/>
+ /// Otherwise, this JsonEncoder will flush its current output and then
+ /// reconfigure its output to use a default UTF8 JsonWriter that
writes to the
+ /// provided OutputStream.
+ /// </summary>
+ /// <param name="stream"> The OutputStream to direct output to. Cannot
be null. </param>
+ /// <returns> this JsonEncoder </returns>
+ public JsonEncoder Configure(Stream stream)
+ {
+ this.Configure(getJsonWriter(stream, false));
+ return this;
+ }
+
+ /// <summary>
+ /// Reconfigures this JsonEncoder to output to the JsonWriter provided.
+ /// <p/>
+ /// Otherwise, this JsonEncoder will flush its current output and then
+ /// reconfigure its output to use the provided JsonWriter.
+ /// </summary>
+ /// <param name="jsonWriter"> The JsonWriter to direct output to.
Cannot be null. </param>
+ /// <returns> this JsonEncoder </returns>
+ public JsonEncoder Configure(JsonWriter jsonWriter)
+ {
+ if (null != parser)
+ {
+ Flush();
+ }
+
+ this.writer = jsonWriter;
+ return this;
+ }
+
+ /// <inheritdoc />
+ public override void WriteNull()
+ {
+ parser.Advance(Symbol.Null);
+ writer.WriteNull();
+ }
+
+ /// <inheritdoc />
+ public override void WriteBoolean(bool b)
+ {
+ parser.Advance(Symbol.Boolean);
+ writer.WriteValue(b);
+ }
+
+ /// <inheritdoc />
+ public override void WriteInt(int n)
+ {
+ parser.Advance(Symbol.Int);
+ writer.WriteValue(n);
+ }
+
+ /// <inheritdoc />
+ public override void WriteLong(long n)
+ {
+ parser.Advance(Symbol.Long);
+ writer.WriteValue(n);
+ }
+
+ /// <inheritdoc />
+ public override void WriteFloat(float f)
+ {
+ parser.Advance(Symbol.Float);
+ writer.WriteValue(f);
+ }
+
+ /// <inheritdoc />
+ public override void WriteDouble(double d)
+ {
+ parser.Advance(Symbol.Double);
+ writer.WriteValue(d);
+ }
+
+ /// <inheritdoc />
+ public override void WriteString(string str)
+ {
+ parser.Advance(Symbol.String);
+ if (parser.TopSymbol() == Symbol.MapKeyMarker)
+ {
+ parser.Advance(Symbol.MapKeyMarker);
+ writer.WritePropertyName(str);
+ }
+ else
+ {
+ writer.WriteValue(str);
+ }
+ }
+
+ /// <inheritdoc />
+ public override void WriteBytes(byte[] bytes)
+ {
+ WriteBytes(bytes, 0, bytes.Length);
+ }
+
+ /// <inheritdoc />
+ public override void WriteBytes(byte[] bytes, int start, int len)
+ {
+ parser.Advance(Symbol.Bytes);
+ writeByteArray(bytes, start, len);
+ }
+
+ private void writeByteArray(byte[] bytes, int start, int len)
+ {
+ Encoding iso = Encoding.GetEncoding("ISO-8859-1");
+ writer.WriteValue(iso.GetString(bytes, start, len));
+ }
+
+ /// <inheritdoc />
+ public override void WriteFixed(byte[] bytes)
+ {
+ WriteFixed(bytes, 0, bytes.Length);
+ }
+
+ /// <inheritdoc />
+ public override void WriteFixed(byte[] bytes, int start, int len)
+ {
+ parser.Advance(Symbol.Fixed);
+ Symbol.IntCheckAction top =
(Symbol.IntCheckAction)parser.PopSymbol();
+ if (len != top.Size)
+ {
+ throw new AvroTypeException("Incorrect length for fixed
binary: expected " + top.Size +
+ " but received " + len + "
bytes.");
+ }
+
+ writeByteArray(bytes, start, len);
+ }
+
+ /// <inheritdoc />
+ public override void WriteEnum(int e)
+ {
+ parser.Advance(Symbol.Enum);
+ Symbol.EnumLabelsAction top =
(Symbol.EnumLabelsAction)parser.PopSymbol();
+ if (e < 0 || e >= top.Size)
+ {
+ throw new AvroTypeException("Enumeration out of range: max is
" + top.Size + " but received " + e);
+ }
+
+ writer.WriteValue(top.GetLabel(e));
+ }
+
+ /// <inheritdoc />
+ public override void WriteArrayStart()
+ {
+ parser.Advance(Symbol.ArrayStart);
+ writer.WriteStartArray();
+ Push();
+ if (Depth() >= isEmpty.Length)
+ {
+ isEmpty.Length += isEmpty.Length;
+ }
+
+ isEmpty.Set(Depth(), true);
+ }
+
+ /// <inheritdoc />
+ public override void WriteArrayEnd()
+ {
+ if (!isEmpty.Get(Pos))
+ {
+ parser.Advance(Symbol.ItemEnd);
+ }
+
+ Pop();
+ parser.Advance(Symbol.ArrayEnd);
+ writer.WriteEndArray();
+ }
+
+ /// <inheritdoc />
+ public override void WriteMapStart()
+ {
+ Push();
+ if (Depth() >= isEmpty.Length)
+ {
+ isEmpty.Length += isEmpty.Length;
+ }
+
+ isEmpty.Set(Depth(), true);
+
+ parser.Advance(Symbol.MapStart);
+ writer.WriteStartObject();
+ }
+
+ /// <inheritdoc />
+ public override void WriteMapEnd()
+ {
+ if (!isEmpty.Get(Pos))
+ {
+ parser.Advance(Symbol.ItemEnd);
+ }
+
+ Pop();
+
+ parser.Advance(Symbol.MapEnd);
+ writer.WriteEndObject();
+ }
+
+ /// <summary>
+ /// Start an array item.
+ /// </summary>
+ public new void StartItem()
Review Comment:
Ah, thanks for the detailed explained. I fixed this.
Issue Time Tracking
-------------------
Worklog Id: (was: 802496)
Time Spent: 2.5h (was: 2h 20m)
> JsonEncode Decode support for C#
> --------------------------------
>
> Key: AVRO-3001
> URL: https://issues.apache.org/jira/browse/AVRO-3001
> Project: Apache Avro
> Issue Type: Improvement
> Components: csharp
> Affects Versions: 1.10.0, 1.11.0
> Reporter: Krishnan Unni
> Assignee: Robert Yokota
> Priority: Major
> Labels: pull-request-available
> Time Spent: 2.5h
> Remaining Estimate: 0h
>
> The C# library for avro currently supports only the Binary encoding and also
> with compile time types (Generic support only). As part of a project I am
> doing I need to validate the avro schema against the incoming json data on
> the fly without a predefined type (generated class). So basically comparing
> an avro schema (string/json representation) against a raw json string. It is
> possible with the Java library since it supports both non generic types and
> streams as well as json encoding. With C# currently this is not possible. Is
> there a plan to extend the C# library to provide these features? If yes, is
> there a timeline? If not is there any alternative to achieve this?
--
This message was sent by Atlassian Jira
(v8.20.10#820010)