Ejemplo n.º 1
0
        /// <summary>
        /// Reads the <see cref="StackInt"/> value from the given <see cref="FastStreamReader"/>.
        /// Return value indicates success.
        /// </summary>
        /// <param name="stream">Stream containing the <see cref="StackInt"/></param>
        /// <param name="bytes">
        /// If the <see cref="StackInt"/> is not strictly encoded it will contain the wrong encoding, otherwise will be null.
        /// </param>
        /// <param name="result">The result</param>
        /// <param name="error">Error message (null if sucessful, otherwise will contain information about the failure).</param>
        /// <returns>True if reading was successful, false if otherwise.</returns>
        public static bool TryRead(FastStreamReader stream, out byte[] bytes, out StackInt result, out string error)
        {
            error = null;
            bytes = null;
            if (stream is null)
            {
                result = 0;
                error  = "Stream can not be null.";
                return(false);
            }
            if (!stream.TryReadByte(out byte firstByte))
            {
                result = 0;
                error  = Err.EndOfStream;
                return(false);
            }

            if (firstByte < (byte)OP.PushData1)
            {
                result = new StackInt((uint)firstByte);
            }
            else if (firstByte == (byte)OP.PushData1)
            {
                if (!stream.TryReadByte(out byte val))
                {
                    error  = $"OP_{OP.PushData1} needs to be followed by at least one byte.";
                    result = 0;
                    return(false);
                }

                if (val < (byte)OP.PushData1)
                {
                    bytes = new byte[2] {
                        firstByte, val
                    };
                    error = $"For OP_{OP.PushData1} the data value must be bigger than {(byte)OP.PushData1 - 1}.";
                }

                result = new StackInt((uint)val);
            }
            else if (firstByte == (byte)OP.PushData2)
            {
                if (!stream.TryReadByteArray(sizeof(ushort), out byte[] temp))
        /// <summary>
        /// Reads the <see cref="LockTime"/> value from the given <see cref="FastStreamReader"/>.
        /// Return value indicates success.
        /// </summary>
        /// <param name="stream">Stream containing the <see cref="LockTime"/></param>
        /// <param name="result">The result</param>
        /// <param name="error">Error message (null if sucessful, otherwise will contain information about the failure).</param>
        /// <returns>True if reading was successful, false if otherwise.</returns>
        public static bool TryRead(FastStreamReader stream, out LockTime result, out string error)
        {
            if (stream is null)
            {
                result = 0;
                error  = "Stream can not be null.";
                return(false);
            }

            if (!stream.TryReadUInt32(out uint val))
            {
                result = 0;
                error  = Err.EndOfStream;
                return(false);
            }

            result = new LockTime(val);
            error  = null;
            return(true);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Reads the <see cref="CompactInt"/> value from the given<see cref="FastStreamReader"/>.
        /// The return value indicates success.
        /// </summary>
        /// <param name="stream">Stream containing the <see cref="CompactInt"/></param>
        /// <param name="result">The result</param>
        /// <param name="error">Error message (null if sucessful, otherwise will contain information about the failure).</param>
        /// <returns>True if reading was successful, false if otherwise.</returns>
        public static bool TryRead(FastStreamReader stream, out CompactInt result, out string error)
        {
            result = 0;
            if (stream is null)
            {
                error = "Stream can not be null.";
                return(false);
            }
            if (!stream.TryReadByte(out byte firstByte))
            {
                error = Err.EndOfStream;
                return(false);
            }

            if (firstByte <= 252)
            {
                result = new CompactInt((ulong)firstByte);
            }
            else if (firstByte == 253) // 0xfd-XX-XX
            {
                if (!stream.TryReadUInt16(out ushort val))
                {
                    error  = "First byte 253 needs to be followed by at least 2 byte.";
                    result = 0;
                    return(false);
                }

                if (val <= 252)
                {
                    error  = $"For values less than 253, one byte format of {nameof(CompactInt)} should be used.";
                    result = 0;
                    return(false);
                }
                result = new CompactInt((ulong)val);
            }
            else if (firstByte == 254) // 0xfe-XX-XX-XX-XX
            {
                if (!stream.TryReadUInt32(out uint val))
                {
                    error  = "First byte 254 needs to be followed by at least 4 byte.";
                    result = 0;
                    return(false);
                }

                if (val <= ushort.MaxValue)
                {
                    error  = "For values less than 2 bytes, the [253, ushort] format should be used.";
                    result = 0;
                    return(false);
                }
                result = new CompactInt((ulong)val);
            }
            else if (firstByte == 255) //0xff-XX-XX-XX-XX-XX-XX-XX-XX
            {
                if (!stream.TryReadUInt64(out ulong val))
                {
                    error  = "First byte 255 needs to be followed by at least 8 byte.";
                    result = 0;
                    return(false);
                }

                if (val <= uint.MaxValue)
                {
                    error  = "For values less than 4 bytes, the [254, uint] format should be used.";
                    result = 0;
                    return(false);
                }
                result = new CompactInt(val);
            }

            error = null;
            return(true);
        }
        /// <summary>
        /// Reads the <see cref="StackInt"/> value from the given <see cref="FastStreamReader"/>.
        /// Return value indicates success.
        /// </summary>
        /// <param name="stream">Stream containing the <see cref="StackInt"/></param>
        /// <param name="isStrict">Determines if strict rules (shortest encoding possible) should be enforced</param>
        /// <param name="result">The result</param>
        /// <param name="error">Error message (null if sucessful, otherwise will contain information about the failure).</param>
        /// <returns>True if reading was successful, false if otherwise.</returns>
        public static bool TryRead(FastStreamReader stream, bool isStrict, out StackInt result, out string error)
        {
            if (stream is null)
            {
                result = 0;
                error  = "Stream can not be null.";
                return(false);
            }
            if (!stream.TryReadByte(out byte firstByte))
            {
                result = 0;
                error  = Err.EndOfStream;
                return(false);
            }

            if (firstByte < (byte)OP.PushData1)
            {
                result = new StackInt((uint)firstByte);
            }
            else if (firstByte == (byte)OP.PushData1)
            {
                if (!stream.TryReadByte(out byte val))
                {
                    error  = $"OP_{OP.PushData1} needs to be followed by at least one byte.";
                    result = 0;
                    return(false);
                }

                if (isStrict && val < (byte)OP.PushData1)
                {
                    error  = $"For OP_{OP.PushData1} the data value must be bigger than {(byte)OP.PushData1 - 1}.";
                    result = 0;
                    return(false);
                }
                result = new StackInt((uint)val);
            }
            else if (firstByte == (byte)OP.PushData2)
            {
                if (!stream.TryReadUInt16(out ushort val))
                {
                    error  = $"OP_{OP.PushData2} needs to be followed by at least two byte.";
                    result = 0;
                    return(false);
                }

                if (isStrict && val <= byte.MaxValue)
                {
                    error  = $"For OP_{OP.PushData2} the data value must be bigger than {byte.MaxValue}.";
                    result = 0;
                    return(false);
                }
                result = new StackInt((uint)val);
            }
            else if (firstByte == (byte)OP.PushData4)
            {
                if (!stream.TryReadUInt32(out uint val))
                {
                    error  = $"OP_{OP.PushData4} needs to be followed by at least 4 byte.";
                    result = 0;
                    return(false);
                }

                if (isStrict && val <= ushort.MaxValue)
                {
                    error  = $"For OP_{OP.PushData4} the data value must be bigger than {ushort.MaxValue}.";
                    result = 0;
                    return(false);
                }
                result = new StackInt(val);
            }
            else
            {
                error  = "Unknown OP_Push value.";
                result = 0;
                return(false);
            }

            error = null;
            return(true);
        }