/// <summary>
        /// This is basically the same algorithm as in the t4 template to create the methods
        /// It's necessary to update both
        /// </summary>
        private static ConstantExpression[] GetIntegersForMemberName(string formattedName)
        {
            var result = new List <ConstantExpression>();
            var length = Encoding.UTF8.GetByteCount(formattedName);

            if (length > 23)
            {
                return(null); // fallback
            }
            var bytes = new byte[length + 1];

            bytes[0] = CborWriter.EncodeType(CborType.TextString, (byte)length);
            var opStatus = Utf8.FromUtf16(formattedName, bytes.AsSpan(1), out _, out _);

            Debug.Assert(opStatus == OperationStatus.Done);
            var remaining  = bytes.Length;
            var ulongCount = Math.DivRem(remaining, 8, out remaining);
            var offset     = 0;

            for (var j = 0; j < ulongCount; j++)
            {
                result.Add(Expression.Constant(BitConverter.ToUInt64(bytes, offset)));
                offset += sizeof(ulong);
            }

            var uintCount = Math.DivRem(remaining, 4, out remaining);

            for (var j = 0; j < uintCount; j++)
            {
                result.Add(Expression.Constant(BitConverter.ToUInt32(bytes, offset)));
                offset += sizeof(uint);
            }

            var ushortCount = Math.DivRem(remaining, 2, out remaining);

            for (var j = 0; j < ushortCount; j++)
            {
                result.Add(Expression.Constant(BitConverter.ToUInt16(bytes, offset)));
                offset += sizeof(ushort);
            }

            var byteCount = Math.DivRem(remaining, 1, out remaining);

            for (var j = 0; j < byteCount; j++)
            {
                result.Add(Expression.Constant(bytes[offset]));
                offset++;
            }

            Debug.Assert(remaining == 0);
            Debug.Assert(offset == bytes.Length);
            return(result.ToArray());
        }
        public ValueTask SerializePipe()
        {
            var        pipe       = PipeWriter.Create(Stream.Null);
            CborWriter cborWriter = new CborWriter(pipe);
            var        t          = ComplexClassFormatter <Document> .Default.SerializeAsync(cborWriter, document);

            if (t.IsCompletedSuccessfully)
            {
                return(cborWriter.CompleteAsync());
            }

            return(AwaitComplete(t, cborWriter));
        }
Example #3
0
        private static async Task FillPipeAsync(PipeWriter writer)
        {
            CborWriter cborWriter = new CborWriter(writer);
            var        document   = new Document {
                Key = "Hello", Value = "World"
            };
            var formatter = new ComplexClassFormatter <Document>();
            await formatter.SerializeAsync(cborWriter, document).ConfigureAwait(false);

            //await cborWriter.WriteMap(input).ConfigureAwait(false);
            await cborWriter.FlushAsync().ConfigureAwait(false);

            await writer.CompleteAsync().ConfigureAwait(false);
        }
        public ValueTask SerializeAsync(CborWriter writer, T value, CancellationToken cancellationToken = default)
        {
            if (value is null)
            {
                writer.WriteNull();
                return(writer.FlushAsync(cancellationToken));
            }

            var step = 0;
            var task = Serializer(writer, value, ref step, cancellationToken);

            if (task.IsCompletedSuccessfully && step == MaxSteps) // if everything is synchronous, we should not hit any async path at all
            {
                return(writer.FlushAsync(cancellationToken));
            }

            return(AwaitSerializeAsync(task, writer, value, step, cancellationToken));
        }
        private async ValueTask AwaitComplete(ValueTask valueTask, CborWriter writer)
        {
            await valueTask.ConfigureAwait(false);

            await writer.CompleteAsync();
        }