//-----------------------------------------------------------------------
// 
//     Copyright (c) Microsoft Corporation.
// 
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
    using System;
    using System.Diagnostics;
    /// 
    /// A byte array column value.
    /// 
    public class BytesColumnValue : ColumnValue
    {
        /// 
        /// Internal value.
        /// 
        private byte[] internalValue;
        /// 
        /// Gets the last set or retrieved value of the column. The
        /// value is returned as a generic object.
        /// 
        public override object ValueAsObject
        {
            [DebuggerStepThrough]
            get { return this.Value; }
        }
        /// 
        /// Gets or sets the value of the column. Use  to update a
        /// record with the column value.
        /// 
        public byte[] Value
        {
            get
            {
                return this.internalValue;
            }
            set
            {
                this.internalValue = value;
                this.Error = value == null ? JET_wrn.ColumnNull : JET_wrn.Success;
            }
        }
        /// 
        /// Gets the byte length of a column value, which is zero if column is null, otherwise
        /// matches the actual length of the byte array.
        /// 
        public override int Length
        {
            get { return this.Value != null ? this.Value.Length : 0; }
        }
        /// 
        /// Gets the size of the value in the column. This returns 0 for
        /// variable sized columns (i.e. binary and string).
        /// 
        protected override int Size
        {
            [DebuggerStepThrough]
            get { return 0; }
        }
        /// 
        /// Returns a  that represents the current .
        /// 
        /// 
        /// A  that represents the current .
        /// 
        public override string ToString()
        {
            if (null == this.Value)
            {
                return string.Empty;
            }
            return BitConverter.ToString(this.Value, 0, Math.Min(this.Value.Length, 16));
        }
        /// 
        /// Recursive SetColumns method for data pinning. This populates the buffer and
        /// calls the inherited SetColumns method.
        /// 
        /// The session to use.
        /// 
        /// The table to set the columns in. An update should be prepared.
        /// 
        /// 
        /// Column values to set.
        /// 
        /// 
        /// Structures to put the pinned data in.
        /// 
        /// Offset of this object in the array.
        /// An error code.
        internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
        {
            if (null != this.Value)
            {
                fixed (void* buffer = this.Value)
                {
                    return this.SetColumns(
                        sesid, tableid, columnValues, nativeColumns, i, buffer, this.Value.Length, true);
                }
            }
            return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, null, 0, false);
        }
        /// 
        /// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
        /// 
        /// An array of bytes.
        /// The starting position within the bytes.
        /// The number of bytes to decode.
        /// The error returned from ESENT.
        protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
        {
            if (JET_wrn.ColumnNull == (JET_wrn)err)
            {
                this.Value = null;
            }
            else
            {
                var copiedValue = new byte[count];
                Buffer.BlockCopy(value, startIndex, copiedValue, 0, count);
                this.Value = copiedValue;
            }
        }
    }
}