public void IsAccessible()
        {
            var id1 = ItemDescription.FromAnalysis <Event <OHLCV> >();
            var id2 = ItemDescription.FromAnalysis <Event <OHLCV> >();

            id1.IsAccessibleWith(id2, ItemDescriptionElements.All);
        }
        static TeaFile <T> OpenRead(Stream stream, bool ownsStream, ItemDescriptionElements elementsToValidate)
        {
            var tf = new TeaFile <T>();

            try
            {
                tf.core   = new TeaFileCore(stream, ownsStream);
                tf.buffer = new SafeBuffer <T>(stream);
                tf.core.ReadHeader();

                //  reflecting the current type incurs some cost, so we do it only if we are asked to consider
                //  current item layout to check it against to layout described in the file
                ItemDescription accessorDescription = null;
                if (elementsToValidate != ItemDescriptionElements.None)
                {
                    accessorDescription = ItemDescription.FromAnalysis <T>();
                }
                tf.core.IsAccessibleWith(accessorDescription, elementsToValidate);
                return(tf);
            }
            catch (Exception)
            {
                tf.Dispose();
                throw;
            }
        }
        /// <summary>
        /// Creates a TeaFile, using the specified stream as the underlying storage media.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="ownsStream">If true, the instance returned owns the stream, such that disposing the returned instance also disposes <paramref name="stream"/>.</param>
        /// <param name="contentDescription">The content description.</param>
        /// <param name="nameValues">The name values.</param>
        /// <param name="includeItemDescription">if set to <c>true</c> [include item description].</param>
        /// <returns></returns>
        /// <remarks>
        /// Instead of creating a new <see cref="FileStream"/>, this method takes the <see cref="Stream"/> passed. This provides
        /// more control over the stream, like setting specific <see cref="FileShare"/> attributes. It also allows usage of
        /// alternative storage medias like <see cref="MemoryStream"/>.
        /// </remarks>
        public static TeaFile <T> Create(Stream stream, bool ownsStream, string contentDescription = null, NameValueCollection nameValues = null, bool includeItemDescription = true)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            var tf = new TeaFile <T>();

            try
            {
                tf.core   = new TeaFileCore(stream, ownsStream);
                tf.buffer = new SafeBuffer <T>(stream);
                if (includeItemDescription)
                {
                    tf.Description.ItemDescription = ItemDescription.FromAnalysis <T>();
                }
                tf.Description.ContentDescription = contentDescription;
                tf.Description.NameValues         = nameValues;
                tf.Description.Timescale          = Time.Scale; // The
                tf.core.WriteHeader();
                tf.Flush();
                return(tf);
            }
            catch (Exception)
            {
                tf.Dispose();
                throw;
            }
        }
        public void IsAccessibleDetectsDifferentSize()
        {
            var ida  = ItemDescription.FromAnalysis <Event <A> >();
            var ida1 = ItemDescription.FromAnalysis <Event <A2> >();

            ida.IsAccessibleWith(ida1, ItemDescriptionElements.None);
            var ex = Executing.This(() => ida.IsAccessibleWith(ida1, ItemDescriptionElements.ItemSize)).Should().Throw <TypeMismatchException>().Exception;

            Console.WriteLine(ex);
        }
        public void EventTimeAttributeTest()
        {
            var id = ItemDescription.FromAnalysis <Timed1>();

            id.Fields[0].IsEventTime.Should().Be.True();

            id = ItemDescription.FromAnalysis <Timed2>();
            id.Fields[0].IsEventTime.Should().Be.True();
            id.Fields[1].IsEventTime.Should().Be.False();

            id = ItemDescription.FromAnalysis <Timed3>();
            id.Fields[0].IsEventTime.Should().Be.False();
            id.Fields[1].IsEventTime.Should().Be.True();
        }
        public void FieldsOffset_might_fail_dependent_on_Jit_TypeLayout_Decision()
        {
            var id = ItemDescription.FromAnalysis <TOHLCV>();

            // the following assertions might fail, since the layout is determined by the Jit compiler and depends on the runtime
            if (Environment.Is64BitProcess)
            {
                id.Fields.Select(f => f.Offset).Should().Have.SameValuesAs(0, 8, 16, 24, 32, 40);
            }
            else
            {
                id.Fields.Select(f => f.Offset).Should().Have.SameValuesAs(0, 8, 16, 24, 32, 40);
            }
        }
        public unsafe void IsAccessibleDetectsFieldTypeDifference()
        {
            sizeof(A2).Should().Be(20);
            sizeof(FieldTypeChange.A2).Should().Be(20);

            var ida  = ItemDescription.FromAnalysis <A2>();
            var ida2 = ItemDescription.FromAnalysis <FieldTypeChange.A2>();

            ida.IsAccessibleWith(ida2, ItemDescriptionElements.None);
            ida.IsAccessibleWith(ida2, ItemDescriptionElements.ItemName);
            ida.IsAccessibleWith(ida2, ItemDescriptionElements.ItemSize);
            Executing.This(() => ida2.IsAccessibleWith(ida, ItemDescriptionElements.FieldTypes))
            .Should().Throw <TypeMismatchException>()
            .Exception.Source.Should().Be("FieldTypes Check");
        }
        public void TimeSeriesFlag()
        {
            var ida = ItemDescription.FromAnalysis <UnTimed>();

            ida.HasEventTime.Should().Be.False();

            var ida2 = ItemDescription.FromAnalysis <Event <UnTimed> >();

            ida2.HasEventTime.Should().Be.True();

            var ida3 = ItemDescription.FromAnalysis <Event <Timed> >();

            ida3.HasEventTime.Should().Be.True();

            Executing.This(() => ItemDescription.FromAnalysis <Event <DateTimed> >()).Should().Throw <InvalidFieldTypeException>();
        }
        public unsafe void Fields()
        {
            var id = ItemDescription.FromAnalysis <TOHLCV>();

            id.ItemTypeName.Should().Be("TOHLCV");
            id.ItemSize.Should().Be.GreaterThanOrEqualTo(sizeof(TOHLCV));
            id.ItemSize.Should().Be.LessThanOrEqualTo(sizeof(TOHLCV) + 8);

            id.Fields.Select(f => f.Name).Should().Have.SameValuesAs("Time", "Open", "High", "Low", "Close", "Volume");
            id.Fields.Select(f => f.Index).Should().Have.SameSequenceAs(0, 1, 2, 3, 4, 5);

            // the following assertions might fail, since the layout is determined by the Jit compiler and depends on the runtime
            if (Environment.Is64BitProcess)
            {
                id.Fields.Select(f => f.Offset).Should().Have.SameValuesAs(0, 8, 16, 24, 32, 40);
            }
            else
            {
                id.Fields.Select(f => f.Offset).Should().Have.SameValuesAs(0, 8, 16, 24, 32, 40);
            }
        }
        static TeaFile <T> OpenWrite(Stream stream, bool ownsStream, ItemDescriptionElements elementsToValidate)
        {
            var tf = new TeaFile <T>();

            try
            {
                tf.buffer = new SafeBuffer <T>(stream);
                tf.core   = new TeaFileCore(stream, ownsStream);
                tf.core.ReadHeader();
                tf.core.IsAccessibleWith(ItemDescription.FromAnalysis <T>(), elementsToValidate);
                // filepointer is at begin of item area. finally, the user might want to read.
                // using filepointer is essential here.
                // check the item api to allow this.
                return(tf);
            }
            catch (Exception)
            {
                tf.Dispose();
                throw;
            }
        }
        public unsafe void IsAccessibleDetectsStructHasNoFieldsException()
        {
            sizeof(A2).Should().Be(20);       // has 2 fields, a, b
            sizeof(Other.A2).Should().Be(20); // an empty struct

            var ida  = ItemDescription.FromAnalysis <A2>();
            var ida2 = new ItemDescription(DescriptionSource.File);

            ida2.ItemSize     = 20;
            ida2.ItemTypeName = "A2";

            ida.IsAccessibleWith(ida2, ItemDescriptionElements.None);
            ida.IsAccessibleWith(ida2, ItemDescriptionElements.ItemName);
            ida.IsAccessibleWith(ida2, ItemDescriptionElements.ItemSize);
            Executing.This(() => ida2.IsAccessibleWith(ida, ItemDescriptionElements.FieldOffsets))
            .Should().Throw <TypeMismatchException>()
            .Exception.Source.Should().Be("No ItemFields");
            Executing.This(() => ida.IsAccessibleWith(ida2, ItemDescriptionElements.FieldOffsets))
            .Should().Throw <TypeMismatchException>()
            .Exception.Source.Should().Be("No ItemFields Accessor");

            // FieldNames checking includes FieldOffset checking, so the exception remains its Source
            Executing.This(() => ida2.IsAccessibleWith(ida, ItemDescriptionElements.FieldNames))
            .Should().Throw <TypeMismatchException>()
            .Exception.Source.Should().Be("No ItemFields");
            Executing.This(() => ida.IsAccessibleWith(ida2, ItemDescriptionElements.FieldNames))
            .Should().Throw <TypeMismatchException>()
            .Exception.Source.Should().Be("No ItemFields Accessor");

            // FieldTypes checking includes FieldOffset checking, so the exception remains its Source
            Executing.This(() => ida2.IsAccessibleWith(ida, ItemDescriptionElements.FieldTypes))
            .Should().Throw <TypeMismatchException>()
            .Exception.Source.Should().Be("No ItemFields");
            Executing.This(() => ida.IsAccessibleWith(ida2, ItemDescriptionElements.FieldTypes))
            .Should().Throw <TypeMismatchException>()
            .Exception.Source.Should().Be("No ItemFields Accessor");
        }
        public void EventTimeIsSetWithoutEventTimeAttribute()
        {
            ItemDescription id = ItemDescription.FromAnalysis <TOHLCV>();

            id.Fields.Count(f => f.IsEventTime).Should().Be(1);
        }
        public void TheFirstTimeFieldIsUsedAsEventTime()
        {
            var ida = ItemDescription.FromAnalysis <PrivateTimed>();

            ida.HasEventTime.Should().Be.True();
        }
 public void EmptyStructIsNotSupported()
 {
     Executing.This(() => ItemDescription.FromAnalysis <EmptyStruct>()).Should().Throw <ItemException>();
 }