/// <summary> /// Initializes a new instance of the <see cref="SharedPool{T}"/> class. /// </summary> /// <param name="allocator">The allocation function for constructing a new object.</param> /// <param name="initialSize">The initial size of the pool. The size will be adjusted up as needed, but never down.</param> /// <param name="knownSerializers">An optional set of known serializers. Only required if the pool holds objects that are deserialized from an older store.</param> public SharedPool(Func <T> allocator, int initialSize = 10, KnownSerializers knownSerializers = null) { this.allocator = allocator; this.available = new Queue <T>(initialSize); this.keepAlive = new List <T>(); this.serializers = knownSerializers; }
public void DictionaryBackCompat() { // Represents a Dictionary<int, string> { { 0, "zero" }, { 1, "one" } } serialized using the previous scheme (auto-generated ClassSerializer) var buf = new byte[] { 0, 0, 0, 128, 0, 0, 0, 128, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 3, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 4, 0, 0, 0, 122, 101, 114, 111, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 128, 3, 0, 0, 0, 111, 110, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, }; // Create the known serializers and register the old version of the Dictionary schema. This simulates what would be read from an older store. var serializers = new KnownSerializers(); var oldSchema = TypeSchema.FromType(typeof(Dictionary <int, string>), new RuntimeInfo(serializationSystemVersion: 2), typeof(ClassSerializer <Dictionary <int, string> >), serializerVersion: 1); serializers.RegisterSchema(oldSchema); // Deserialize the buffer using a SerializationContext initialized with the old schema var br = new BufferReader(buf); var dict = default(Dictionary <int, string>); Serializer.Deserialize(br, ref dict, new SerializationContext(serializers)); Assert.AreEqual(2, dict.Count); Assert.AreEqual("zero", dict[0]); Assert.AreEqual("one", dict[1]); }
public void CloneDelegateClosure() { var v = new int[] { 1, 2, 3 }; Func <int, int[]> fn = (int x) => v.Select(a => a + x).ToArray(); try { var fn2 = default(Func <int, int[]>); Serializer.Clone(fn, ref fn2, new SerializationContext()); Assert.Fail("Should have thrown while attempting to clone Func"); } catch (NotSupportedException ex) { Assert.IsTrue(ex.Message.StartsWith("Cannot clone Func")); } // register to allow IntPtr cloning in Func<int, int> and repeat - should now succeed var serializers = new KnownSerializers(); serializers.Register <Func <int, int[]> >(CloningFlags.CloneIntPtrFields); var fn3 = default(Func <int, int[]>); Serializer.Clone(fn, ref fn3, new SerializationContext(serializers)); var res = fn3(10); Assert.AreEqual(11, res[0]); Assert.AreEqual(12, res[1]); Assert.AreEqual(13, res[2]); }
/// <summary> /// Initializes a new instance of the <see cref="DeserializerComponent{T}"/> class. /// </summary> /// <param name="pipeline">The pipeline to attach to.</param> /// <param name="serializers">A set of known serializers, or KnownSerializers.Default.</param> /// <param name="reusableInstance">An instance of type T to use as a deserialization buffer, or null / default(T) to let the component allocate one.</param> public DeserializerComponent(Pipeline pipeline, KnownSerializers serializers, T reusableInstance) : base(pipeline) { this.serializers = serializers; this.context = new SerializationContext(this.serializers); this.handler = this.serializers.GetHandler <T>(); this.reusableInstance = reusableInstance; }
/// <inheritdoc /> public override void OpenStore(string name, string path, KnownSerializers serializers = null) { if (serializers != null) { throw new ArgumentException("Serializers are not used by JsonStoreReader and must be null.", nameof(serializers)); } this.Reader = new AnnotationStoreReader(name, path); }
/// <inheritdoc /> public virtual void OpenStore(string name, string path, KnownSerializers serializers = null) { if (serializers != null) { throw new ArgumentException("Serializers are not used by JsonStoreReader and must be null.", nameof(serializers)); } this.Reader = new JsonStoreReader(name, path, this.extension); }
private void LoadMetadata(IEnumerable <Metadata> metadata, RuntimeInfo runtimeVersion) { if (this.serializers == null) { this.serializers = new KnownSerializers(runtimeVersion); } this.serializers.RegisterMetadata(metadata); }
/// <summary> /// Sets supplemental stream metadata. /// </summary> /// <typeparam name="T">Type of supplemental metadata.</typeparam> /// <param name="value">Supplemental metadata value.</param> /// <param name="serializers">Known serializers.</param> internal void SetSupplementalMetadata <T>(T value, KnownSerializers serializers) { this.SupplementalMetadataTypeName = typeof(T).AssemblyQualifiedName; var handler = serializers.GetHandler <T>(); var writer = new BufferWriter(this.supplementalMetadataBytes); handler.Serialize(writer, value, new SerializationContext(serializers)); this.supplementalMetadataBytes = writer.Buffer; }
public TypeSchema Initialize(KnownSerializers serializers, TypeSchema targetSchema) { this.handler = serializers.GetHandler <SharedContainer <T> >(); var type = this.GetType(); var name = TypeSchema.GetContractName(type, serializers.RuntimeVersion); var innerMember = new TypeMemberSchema("inner", typeof(SharedContainer <T>).AssemblyQualifiedName, true); var schema = new TypeSchema(name, TypeSchema.GetId(name), type.AssemblyQualifiedName, TypeFlags.IsClass, new TypeMemberSchema[] { innerMember }, Version); return(targetSchema ?? schema); }
public TypeSchema Initialize(KnownSerializers serializers, TypeSchema targetSchema) { serializers.GetHandler <byte>(); // register element type var type = typeof(byte[]); var name = TypeSchema.GetContractName(type, serializers.RuntimeVersion); var elementsMember = new TypeMemberSchema("Elements", typeof(byte).AssemblyQualifiedName, true); var schema = new TypeSchema(name, TypeSchema.GetId(name), type.AssemblyQualifiedName, TypeFlags.IsCollection, new TypeMemberSchema[] { elementsMember }, Version); return(targetSchema ?? schema); }
/// <summary> /// Gets supplemental stream metadata. /// </summary> /// <typeparam name="T">Type of supplemental metadata.</typeparam> /// <param name="serializers">Known serializers.</param> /// <returns>Supplemental metadata.</returns> internal T GetSupplementalMetadata <T>(KnownSerializers serializers) { if (string.IsNullOrEmpty(this.SupplementalMetadataTypeName)) { throw new InvalidOperationException("Stream does not contain supplemental metadata."); } if (typeof(T) != Type.GetType(this.SupplementalMetadataTypeName)) { throw new InvalidCastException($"Supplemental metadata type mismatch ({this.SupplementalMetadataTypeName})."); } var handler = serializers.GetHandler <T>(); var reader = new BufferReader(this.supplementalMetadataBytes); var target = default(T); handler.Deserialize(reader, ref target, new SerializationContext(serializers)); return(target); }
/// <summary> /// Initialize custom serializer. /// </summary> /// <param name="serializers">Known serializers</param> /// <param name="targetSchema">Target type schema</param> /// <returns>Type schema</returns> public TypeSchema Initialize(KnownSerializers serializers, TypeSchema targetSchema) { if (targetSchema == null) { TypeMemberSchema[] schemaMembers = new TypeMemberSchema[6] { new TypeMemberSchema("compression", typeof(CompressionMethod).AssemblyQualifiedName, false), new TypeMemberSchema("image", typeof(UnmanagedBuffer).AssemblyQualifiedName, true), new TypeMemberSchema("width", typeof(int).AssemblyQualifiedName, true), new TypeMemberSchema("height", typeof(int).AssemblyQualifiedName, true), new TypeMemberSchema("stride", typeof(int).AssemblyQualifiedName, true), new TypeMemberSchema("pixelFormat", typeof(Imaging.PixelFormat).AssemblyQualifiedName, true), }; var type = typeof(Imaging.Image); var name = TypeSchema.GetContractName(type, serializers.RuntimeVersion); this.schema = new TypeSchema(name, TypeSchema.GetId(name), type.AssemblyQualifiedName, TypeFlags.IsCollection, schemaMembers, Version); } else { this.schema = targetSchema; } // Check to see if we can retrieve the custom compression serializer try { var assembly = System.Reflection.Assembly.Load(new System.Reflection.AssemblyName("Microsoft.Psi.Imaging.Windows")); if (assembly != null) { var ic = assembly.CreateInstance("Microsoft.Psi.Imaging.ImageCompressor"); if (ic != null) { this.imageCompressor = ic as IImageCompressor; this.imageCompressor.Initialize(compressionMethod); } } } catch (System.IO.FileNotFoundException) { this.imageCompressor = null; } return(this.schema); }
/// <summary> /// Initializes a new instance of the <see cref="Exporter"/> class. /// </summary> /// <param name="pipeline">The pipeline that owns this instance.</param> /// <param name="name">The name of the application that generated the persisted files, or the root name of the files</param> /// <param name="path">The directory in which the main persisted file resides or will reside, or null to create a volatile data store</param> /// <param name="createSubdirectory">If true, a numbered sub-directory is created for this store</param> /// <param name="serializers"> /// A collection of known serializers, or null to infer it from the data being written to the store. /// The known serializer set can be accessed and modified afterwards via the <see cref="Serializers"/> property. /// </param> internal Exporter(Pipeline pipeline, string name, string path, bool createSubdirectory = true, KnownSerializers serializers = null) { this.pipeline = pipeline; this.serializers = serializers ?? new KnownSerializers(); this.writer = new StoreWriter(name, path, createSubdirectory); // write the version info this.writer.WriteToCatalog(this.serializers.RuntimeVersion); // copy the schemas present so far and also make sure the catalog captures schemas added in the future this.serializers.SchemaAdded += (o, e) => this.writer.WriteToCatalog(e); foreach (var schema in this.serializers.Schemas) { this.writer.WriteToCatalog(schema); } this.merger = new Merger <Message <BufferReader>, string>(pipeline); this.writerInput = pipeline.CreateReceiver <Message <BufferReader> >(this, (m, e) => this.writer.Write(m.Data, m.Envelope), nameof(this.writerInput)); this.merger.Select(this.ThrottledMessages).PipeTo(this.writerInput, DeliveryPolicy.Unlimited); }
public void RegisterFlags() { var serializers = new KnownSerializers(); // register different flags for multiple types serializers.Register <ClassWithIntPtr>(CloningFlags.CloneIntPtrFields); serializers.Register <ClassWithPointer>(CloningFlags.ClonePointerFields); serializers.Register <ClassWithNonSerialized>(CloningFlags.SkipNonSerializedFields); serializers.Register <StructWithAll>( CloningFlags.ClonePointerFields | CloningFlags.CloneIntPtrFields | CloningFlags.SkipNonSerializedFields); Assert.AreEqual(CloningFlags.CloneIntPtrFields, serializers.GetCloningFlags(typeof(ClassWithIntPtr))); Assert.AreEqual(CloningFlags.ClonePointerFields, serializers.GetCloningFlags(typeof(ClassWithPointer))); Assert.AreEqual(CloningFlags.SkipNonSerializedFields, serializers.GetCloningFlags(typeof(ClassWithNonSerialized))); Assert.AreEqual( CloningFlags.ClonePointerFields | CloningFlags.CloneIntPtrFields | CloningFlags.SkipNonSerializedFields, serializers.GetCloningFlags(typeof(StructWithAll))); serializers = new KnownSerializers(); // new context // registering with no flags is equivalent to None serializers.Register <ClassWithPointer>(); serializers.Register <ClassWithPointer>(CloningFlags.None); Assert.AreEqual(CloningFlags.None, serializers.GetCloningFlags(typeof(ClassWithPointer))); serializers = new KnownSerializers(); // new context // cannot re-register with different flags serializers.Register <ClassWithPointer>(CloningFlags.ClonePointerFields); Assert.ThrowsException <SerializationException>( () => serializers.Register <ClassWithPointer>(CloningFlags.SkipNonSerializedFields)); Assert.AreEqual(CloningFlags.ClonePointerFields, serializers.GetCloningFlags(typeof(ClassWithPointer))); serializers = new KnownSerializers(); // new context // once a handler has been created, cannot register flags var handler = serializers.GetHandler <ClassWithPointer>(); Assert.ThrowsException <SerializationException>( () => serializers.Register <ClassWithPointer>(CloningFlags.ClonePointerFields)); }
public void CloneNonSerializedField() { var cls = new ClassWithNonSerialized { Value = 1, Secret = 0x12345678 }; var cls2 = default(ClassWithNonSerialized); Serializer.Clone(cls, ref cls2, new SerializationContext()); Assert.AreEqual(1, cls2.Value); Assert.AreEqual(0x12345678, cls2.Secret); // register to disable cloning of NonSerialized fields - field should be skipped var serializers = new KnownSerializers(); serializers.Register <ClassWithNonSerialized>(CloningFlags.SkipNonSerializedFields); var cls3 = default(ClassWithNonSerialized); Serializer.Clone(cls, ref cls3, new SerializationContext(serializers)); Assert.AreEqual(1, cls3.Value); Assert.AreEqual(default, cls3.Secret); // skipped NonSerialized field
public void CustomSerializer() { var c = new TypeWithPolymorphicField(); c.Name = "foo"; c.Enumerable = new List <int>(); BufferWriter bw = new BufferWriter(100); var ks = new KnownSerializers(); ks.Register <TypeWithPolymorphicField, TestCustomSerializer>("some alternate name"); // include an alternate name just to exercise that code path var sc = new SerializationContext(ks); Serializer.Serialize(bw, c, sc); sc.Reset(); TypeWithPolymorphicField c2 = null; var br = new BufferReader(bw.Buffer); Serializer.Deserialize(br, ref c2, sc); Assert.AreEqual(c.Name, c2.Name); }
/// <inheritdoc/> public override TypeSchema Initialize(KnownSerializers serializers, TypeSchema targetSchema) { if (targetSchema == null) { var baseSchema = base.Initialize(serializers, targetSchema); var schemaMembers = new List <TypeMemberSchema>(); schemaMembers.AddRange(baseSchema.Members); schemaMembers.Add(new TypeMemberSchema(nameof(DepthImage.depthValueSemantics), typeof(DepthValueSemantics?).AssemblyQualifiedName, false)); schemaMembers.Add(new TypeMemberSchema(nameof(DepthImage.depthValueToMetersScaleFactor), typeof(double).AssemblyQualifiedName, false)); var type = typeof(DepthImage); var name = TypeSchema.GetContractName(type, serializers.RuntimeVersion); this.Schema = new TypeSchema(name, TypeSchema.GetId(name), type.AssemblyQualifiedName, TypeFlags.IsClass, schemaMembers, Version); } else { this.Schema = targetSchema; } return(this.Schema); }
/// <summary> /// Initializes a new instance of the <see cref="Exporter"/> class. /// </summary> /// <param name="pipeline">The pipeline that owns this instance.</param> /// <param name="name">The name of the application that generated the persisted files, or the root name of the files.</param> /// <param name="path">The directory in which the main persisted file resides or will reside, or null to create a volatile data store.</param> /// <param name="createSubdirectory">If true, a numbered sub-directory is created for this store.</param> /// <param name="serializers"> /// A collection of known serializers, or null to infer it from the data being written to the store. /// The known serializer set can be accessed and modified afterwards via the <see cref="Serializers"/> property. /// </param> internal Exporter(Pipeline pipeline, string name, string path, bool createSubdirectory = true, KnownSerializers serializers = null) : base(pipeline) { this.pipeline = pipeline; this.serializers = serializers ?? new KnownSerializers(); this.writer = new StoreWriter(name, path, createSubdirectory); // write the version info this.writer.WriteToCatalog(this.serializers.RuntimeVersion); // copy the schemas present so far and also make sure the catalog captures schemas added in the future this.serializers.SchemaAdded += (o, e) => this.writer.WriteToCatalog(e); foreach (var schema in this.serializers.Schemas.Values) { this.writer.WriteToCatalog(schema); } this.merger = new Merger <Message <BufferReader>, string>(this, (_, m) => { this.Throttle.WaitOne(); this.writer.Write(m.Data.Data, m.Data.Envelope); }); }
/// <summary> /// Initialize custom serializer. /// </summary> /// <param name="serializers">Known serializers.</param> /// <param name="targetSchema">Target type schema.</param> /// <returns>Type schema.</returns> public TypeSchema Initialize(KnownSerializers serializers, TypeSchema targetSchema) { if (targetSchema == null) { TypeMemberSchema[] schemaMembers = new TypeMemberSchema[6] { new TypeMemberSchema("compression", typeof(CompressionMethod).AssemblyQualifiedName, false), new TypeMemberSchema("image", typeof(UnmanagedBuffer).AssemblyQualifiedName, true), new TypeMemberSchema("width", typeof(int).AssemblyQualifiedName, true), new TypeMemberSchema("height", typeof(int).AssemblyQualifiedName, true), new TypeMemberSchema("stride", typeof(int).AssemblyQualifiedName, true), new TypeMemberSchema("pixelFormat", typeof(Imaging.PixelFormat).AssemblyQualifiedName, true), }; var type = typeof(Imaging.Image); var name = TypeSchema.GetContractName(type, serializers.RuntimeVersion); this.schema = new TypeSchema(name, TypeSchema.GetId(name), type.AssemblyQualifiedName, TypeFlags.IsCollection, schemaMembers, Version); } else { this.schema = targetSchema; } return(this.schema); }
/// <inheritdoc /> public void OpenStore(string name, string path, KnownSerializers serializers = null) { this.reader = new StoreReader(name, path, this.LoadMetadata); this.context = new SerializationContext(this.serializers); }
/// <summary> /// Initializes a new instance of the <see cref="SerializerComponent{T}"/> class. /// </summary> /// <param name="pipeline">Pipeline to which this component belongs.</param> /// <param name="serializers">Known serializers.</param> internal SerializerComponent(Pipeline pipeline, KnownSerializers serializers) : base(pipeline) { this.context = new SerializationContext(serializers); this.handler = serializers.GetHandler <T>(); }
public static Exporter Create(Pipeline pipeline, string name, string rootPath, bool createSubdirectory = true, KnownSerializers serializers = null) { throw new NotImplementedException("Store APIs have moved to PsiStore."); }
/// <summary> /// Initializes a new instance of the <see cref="SimpleReader"/> class without re-loading the metadata and index files. /// The new reader maintains its own cursor into the data file and can be used in parallel with the one it was created from. /// </summary> /// <param name="other">An existing reader.</param> public SimpleReader(SimpleReader other) { this.serializers = other.serializers; this.reader = new StoreReader(other.reader); // copy constructor this.context = new SerializationContext(this.serializers); }
public TypeSchema Initialize(KnownSerializers serializers, TypeSchema targetSchema) { return(null); }
/// <summary> /// Initializes a new instance of the <see cref="SharedPool{T}"/> class. /// </summary> /// <param name="initialSize">The initial size of the pool. The size will be adjusted up as needed, but never down.</param> /// <param name="knownSerializers">An optional set of known serializers. Only required if the pool holds objects that are deserialized from an older store</param> public SharedPool(int initialSize, KnownSerializers knownSerializers = null) { this.available = new Queue <T>(initialSize); this.keepAlive = new List <T>(); this.serializers = knownSerializers; }
/// <summary> /// Initializes a new instance of the <see cref="PsiExporter"/> class. /// </summary> /// <param name="pipeline">The pipeline to add the component to.</param> /// <param name="name">The name of the application that generated the persisted files, or the root name of the files.</param> /// <param name="path">The directory in which the main persisted file resides or will reside, or null to create a volatile data store.</param> /// <param name="createSubdirectory">If true, a numbered sub-directory is created for this store.</param> /// <param name="serializers"> /// A collection of known serializers, or null to infer it from the data being written to the store. /// The known serializer set can be accessed and modified afterwards via the <see cref="Exporter.Serializers"/> property. /// </param> internal PsiExporter(Pipeline pipeline, string name, string path, bool createSubdirectory = true, KnownSerializers serializers = null) : base(pipeline, name, path, createSubdirectory, serializers) { }
/// <summary> /// Creates a new multi-stream \psi store and returns an <see cref="Exporter"/> instance /// which can be used to write streams to this store. /// </summary> /// <param name="pipeline">The pipeline to add the component to.</param> /// <param name="name">The name of the store to create.</param> /// <param name="rootPath">The path to use. If null, an in-memory store is created.</param> /// <param name="createSubdirectory">Indicates whether to create a numbered subdirectory for each execution of the pipeline.</param> /// <param name="serializers">An optional collection of custom serializers to use instead of the default ones.</param> /// <returns>An <see cref="Exporter"/> instance that can be used to write streams.</returns> /// <remarks> /// The Exporter maintains a collection of serializers it knows about, which it uses to serialize /// the data it writes to the store. By default, the Exporter derives the correct serializers /// from the TMessage type argument passed to <see cref="Exporter.Write"/>. In other words, /// for the most part simply knowing the stream type is sufficient to determine all the types needed to /// serialize the messages in the stream. /// Use the <see cref="KnownSerializers"/> parameter to override the default behavior and provide a custom set of serializers. /// </remarks> public static PsiExporter Create(Pipeline pipeline, string name, string rootPath, bool createSubdirectory = true, KnownSerializers serializers = null) { return(new PsiExporter(pipeline, name, rootPath, createSubdirectory, serializers)); }
/// <inheritdoc /> public override void CreateStore(string name, string path, bool createSubdirectory = true, KnownSerializers serializers = null) { if (serializers != null) { throw new ArgumentException("Serializers are not used by JsonSimpleWriter and must be null.", nameof(serializers)); } this.Writer = new AnnotationStoreWriter(name, path, this.definition, createSubdirectory); }
/// <summary> /// Deserializes data from a stream of Message{BufferReader}. /// </summary> /// <typeparam name="T">The type of data expected after deserialization</typeparam> /// <param name="source">The stream containing the serialized data</param> /// <param name="serializers">An optional collection of known types to use</param> /// <param name="reusableInstance">An optional preallocated instance ot use as a buffer. This parameter is required when deserializing <see cref="Shared{T}"/> instances if the deserializer is expected to use a <see cref="SharedPool{T}"/></param> /// <param name="deliveryPolicy">An optional delivery policy.</param> /// <returns>A stream of messages of type T, with their original envelope</returns> public static IProducer <T> Deserialize <T>(this IProducer <Message <BufferReader> > source, KnownSerializers serializers = null, T reusableInstance = default(T), DeliveryPolicy deliveryPolicy = null) { var deserializer = new DeserializerComponent <T>(source.Out.Pipeline, serializers ?? KnownSerializers.Default, reusableInstance); source.PipeTo(deserializer, deliveryPolicy); return(deserializer.Out); }
/// <summary> /// Initializes a new instance of the <see cref="SerializerComponent{T}"/> class. /// </summary> /// <param name="pipeline">The pipeline to add the component to.</param> /// <param name="serializers">Known serializers.</param> /// <param name="name">An optional name for the component.</param> internal SerializerComponent(Pipeline pipeline, KnownSerializers serializers, string name = nameof(SerializerComponent <T>)) : base(pipeline, name) { this.context = new SerializationContext(serializers); this.handler = serializers.GetHandler <T>(); }