[ 
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)

Reply via email to