private int Encode() { EETypeOptionalFieldsElement eLastTag = EETypeOptionalFieldsElement.Count; for (EETypeOptionalFieldsElement eTag = 0; eTag < EETypeOptionalFieldsElement.Count; eTag++) { eLastTag = _rgFields[(int)eTag]._fieldPresent ? eTag : eLastTag; } if (eLastTag == EETypeOptionalFieldsElement.Count) { return(0); } _encoder = new NativePrimitiveEncoder(); _encoder.Init(); for (EETypeOptionalFieldsElement eTag = 0; eTag < EETypeOptionalFieldsElement.Count; eTag++) { if (!_rgFields[(int)eTag]._fieldPresent) { continue; } _encoder.WriteByte((byte)((byte)eTag | (eTag == eLastTag ? 0x80 : 0))); _encoder.WriteUnsigned(_rgFields[(int)eTag]._value); } return(_encoder.Size); }
/// <summary> /// From a string, get a pointer to an allocated memory location that holds a NativeFormat encoded string. /// This is used for the creation of RuntimeFieldHandles from metadata. /// </summary> /// <param name="str"></param> /// <returns></returns> public IntPtr GetNativeFormatStringForString(string str) { using (LockHolder.Hold(_typeLoaderLock)) { IntPtr result; if (_nativeFormatStrings.TryGetValue(str, out result)) { return(result); } NativePrimitiveEncoder stringEncoder = new NativePrimitiveEncoder(); stringEncoder.Init(); byte[] utf8Bytes = Encoding.UTF8.GetBytes(str); stringEncoder.WriteUnsigned(checked ((uint)utf8Bytes.Length)); foreach (byte b in utf8Bytes) { stringEncoder.WriteByte(b); } IntPtr allocatedNativeFormatString = MemoryHelpers.AllocateMemory(stringEncoder.Size); unsafe { stringEncoder.Save((byte *)allocatedNativeFormatString.ToPointer(), stringEncoder.Size); } _nativeFormatStrings.Add(str, allocatedNativeFormatString); return(allocatedNativeFormatString); } }
// Helper method to serialize the data-blob type and flags public static void SerializeDataBlobTypeAndFlags(ref NativePrimitiveEncoder encoder, SerializedDataBlobKind blobType, byte flags) { // make sure that blobType fits in 2 bits and flags fits in 6 bits Debug.Assert(blobType < SerializedDataBlobKind.Limit); Debug.Assert((byte)blobType <= 2 && flags <= 0x3F || (byte)blobType == 3 && flags <= 1 || (byte)blobType > 3 && flags <= 7); byte encodedKindAndFlags; if (blobType <= (SerializedDataBlobKind)3) { encodedKindAndFlags = (byte)((byte)blobType | (flags << 2)); } else { encodedKindAndFlags = (byte)(3 | (((byte)blobType - 3) << 3) | (flags << 5)); } encoder.WriteByte(encodedKindAndFlags); }