/// <summary>
        /// Gets the index to the provided blob signature. If the signature is not present in the buffer, it will be
        /// appended to the end of the stream.
        /// </summary>
        /// <param name="provider">The object to use for obtaining metadata tokens for members in the tables stream.</param>
        /// <param name="signature">The signature to lookup or add.</param>
        /// <param name="diagnosticBag">The bag used to collect diagnostic information.</param>
        /// <returns>The index of the signature.</returns>
        public uint GetBlobIndex(ITypeCodedIndexProvider provider, BlobSignature signature, DiagnosticBag diagnosticBag)
        {
            if (signature is null)
            {
                return(0u);
            }

            // Serialize blob.
            using var stream = new MemoryStream();
            var writer = new BinaryStreamWriter(stream);

            signature.Write(new BlobSerializationContext(writer, provider, diagnosticBag));

            return(GetBlobIndex(stream.ToArray()));
        }
        /// <summary>
        /// Gets the index to the provided blob signature. If the signature is not present in the buffer, it will be
        /// appended to the end of the stream.
        /// </summary>
        /// <param name="provider">The object to use for obtaining metadata tokens for members in the tables stream.</param>
        /// <param name="signature">The signature to lookup or add.</param>
        /// <returns>The index of the signature.</returns>
        public uint GetBlobIndex(ITypeCodedIndexProvider provider, BlobSignature signature)
        {
            if (signature is null)
            {
                return(0u);
            }

            // Serialize blob.
            using var stream = new MemoryStream();
            var writer = new BinaryStreamWriter(stream);

            signature.Write(writer, provider);

            return(GetBlobIndex(stream.ToArray()));
        }
예제 #3
0
        /// <summary>
        /// Gets or creates a new index for the given blob signature.
        /// </summary>
        /// <param name="signature">The blob signature to get the index from.</param>
        /// <returns>The index.</returns>
        public uint GetBlobOffset(BlobSignature signature)
        {
            if (signature == null)
            {
                return(0);
            }

            if (!_signatureOffsetMapping.TryGetValue(signature, out uint offset))
            {
                _signatureOffsetMapping.Add(signature, offset = _length);
                uint signatureLength = signature.GetPhysicalLength(_parentBuffer);
                _length += signatureLength.GetCompressedSize() + signatureLength;
            }
            return(offset);
        }
예제 #4
0
        public void CustomBlobs()
        {
            var assembly  = NetAssemblyFactory.CreateAssembly("SomeAssembly", false);
            var header    = assembly.NetDirectory.MetadataHeader;
            var image     = header.LockMetadata();
            var importer  = new ReferenceImporter(image);
            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));

            var main = new MethodDefinition("Main", MethodAttributes.Public | MethodAttributes.Static,
                                            new MethodSignature(image.TypeSystem.Void));

            main.CilMethodBody = new CilMethodBody(main);
            main.CilMethodBody.Instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldstr, "Hello, world!"),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Ret)
            });

            image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(main);

            image.ManagedEntrypoint = main;

            var extraBlobs = new BlobSignature[]
            {
                new DataBlobSignature(new byte[] { 1, 2, 3 }),
                new DataBlobSignature(new byte[] { 4, 5, 6 })
            };

            // Commit changes to assembly
            var builder = new CustomBuilder(extraBlobs);

            image.Header.UnlockMetadata(builder);

            var blobStream = header.GetStream <BlobStream>();

            Assert.Equal(new byte[] { 1, 2, 3 }, blobStream.GetBlobByOffset(builder.GetBlobOffset(extraBlobs[0])));
            Assert.Equal(new byte[] { 4, 5, 6 }, blobStream.GetBlobByOffset(builder.GetBlobOffset(extraBlobs[1])));
        }
예제 #5
0
 public uint GetBlobOffset(BlobSignature signature)
 {
     return(_extraBlobs[signature]);
 }
예제 #6
0
 /// <summary>
 /// Wraps a blob signature into a new stand-alone signature.
 /// </summary>
 /// <param name="signature">The signature to assign a metadata token.</param>
 public StandAloneSignature(BlobSignature signature)
     : this(new MetadataToken(TableIndex.StandAloneSig, 0))
 {
     Signature = signature;
 }