private void WriteBytes(MemoryHolder address, int offset, Bytes bytes) { SimpleType st = (SimpleType)_type; Debug.Assert(st._type == SimpleTypeKind.Char && bytes.Count <= _length); address.WriteSpan(offset, bytes.AsSpan()); if (bytes.Count < _length) { address.WriteByte(checked (offset + bytes.Count), 0); } }
object INativeType.SetValue(MemoryHolder/*!*/ owner, int offset, object value) { SimpleCData data = value as SimpleCData; if (data != null && data.NativeType == this) { data._memHolder.CopyTo(owner, offset, ((INativeType)this).Size); return null; } switch (_type) { case SimpleTypeKind.Boolean: owner.WriteByte(offset, ModuleOps.GetBoolean(value, this)); break; case SimpleTypeKind.Char: owner.WriteByte(offset, ModuleOps.GetChar(value, this)); break; case SimpleTypeKind.SignedByte: owner.WriteByte(offset, ModuleOps.GetSignedByte(value, this)); break; case SimpleTypeKind.UnsignedByte: owner.WriteByte(offset, ModuleOps.GetUnsignedByte(value, this)); break; case SimpleTypeKind.WChar: owner.WriteInt16(offset, (short)ModuleOps.GetWChar(value, this)); break; case SimpleTypeKind.SignedShort: owner.WriteInt16(offset, ModuleOps.GetSignedShort(value, this)); break; case SimpleTypeKind.UnsignedShort: owner.WriteInt16(offset, ModuleOps.GetUnsignedShort(value, this)); break; case SimpleTypeKind.VariantBool: owner.WriteInt16(offset, (short)ModuleOps.GetVariantBool(value, this)); break; case SimpleTypeKind.SignedInt: owner.WriteInt32(offset, ModuleOps.GetSignedInt(value, this)); break; case SimpleTypeKind.UnsignedInt: owner.WriteInt32(offset, ModuleOps.GetUnsignedInt(value, this)); break; case SimpleTypeKind.UnsignedLong: owner.WriteInt32(offset, ModuleOps.GetUnsignedLong(value, this)); break; case SimpleTypeKind.SignedLong: owner.WriteInt32(offset, ModuleOps.GetSignedLong(value, this)); break; case SimpleTypeKind.Single: owner.WriteInt32(offset, ModuleOps.GetSingleBits(value)); break; case SimpleTypeKind.Double: owner.WriteInt64(offset, ModuleOps.GetDoubleBits(value)); break; case SimpleTypeKind.UnsignedLongLong: owner.WriteInt64(offset, ModuleOps.GetUnsignedLongLong(value, this)); break; case SimpleTypeKind.SignedLongLong: owner.WriteInt64(offset, ModuleOps.GetSignedLongLong(value, this)); break; case SimpleTypeKind.Object: owner.WriteIntPtr(offset, ModuleOps.GetObject(value)); break; case SimpleTypeKind.Pointer: owner.WriteIntPtr(offset, ModuleOps.GetPointer(value)); break; case SimpleTypeKind.CharPointer: owner.WriteIntPtr(offset, ModuleOps.GetCharPointer(value)); return value; case SimpleTypeKind.WCharPointer: owner.WriteIntPtr(offset, ModuleOps.GetWCharPointer(value)); return value; default: throw new InvalidOperationException(); } return null; }
object INativeType.SetValue(MemoryHolder /*!*/ owner, int offset, object value) { SimpleCData data = value as SimpleCData; if (data != null && data.NativeType == this) { data._memHolder.CopyTo(owner, offset, ((INativeType)this).Size); return(null); } switch (_type) { case SimpleTypeKind.Boolean: owner.WriteByte(offset, ModuleOps.GetBoolean(value, this)); break; case SimpleTypeKind.Char: owner.WriteByte(offset, ModuleOps.GetChar(value, this)); break; case SimpleTypeKind.SignedByte: owner.WriteByte(offset, ModuleOps.GetSignedByte(value, this)); break; case SimpleTypeKind.UnsignedByte: owner.WriteByte(offset, ModuleOps.GetUnsignedByte(value, this)); break; case SimpleTypeKind.WChar: owner.WriteInt16(offset, (short)ModuleOps.GetWChar(value, this)); break; case SimpleTypeKind.SignedShort: owner.WriteInt16(offset, ModuleOps.GetSignedShort(value, this)); break; case SimpleTypeKind.UnsignedShort: owner.WriteInt16(offset, ModuleOps.GetUnsignedShort(value, this)); break; case SimpleTypeKind.VariantBool: owner.WriteInt16(offset, (short)ModuleOps.GetVariantBool(value, this)); break; case SimpleTypeKind.SignedInt: owner.WriteInt32(offset, ModuleOps.GetSignedInt(value, this)); break; case SimpleTypeKind.UnsignedInt: owner.WriteInt32(offset, ModuleOps.GetUnsignedInt(value, this)); break; case SimpleTypeKind.UnsignedLong: owner.WriteInt32(offset, ModuleOps.GetUnsignedLong(value, this)); break; case SimpleTypeKind.SignedLong: owner.WriteInt32(offset, ModuleOps.GetSignedLong(value, this)); break; case SimpleTypeKind.Single: owner.WriteInt32(offset, ModuleOps.GetSingleBits(value)); break; case SimpleTypeKind.Double: owner.WriteInt64(offset, ModuleOps.GetDoubleBits(value)); break; case SimpleTypeKind.UnsignedLongLong: owner.WriteInt64(offset, ModuleOps.GetUnsignedLongLong(value, this)); break; case SimpleTypeKind.SignedLongLong: owner.WriteInt64(offset, ModuleOps.GetSignedLongLong(value, this)); break; case SimpleTypeKind.Object: owner.WriteIntPtr(offset, ModuleOps.GetObject(value)); break; case SimpleTypeKind.Pointer: owner.WriteIntPtr(offset, ModuleOps.GetPointer(value)); break; case SimpleTypeKind.CharPointer: owner.WriteIntPtr(offset, ModuleOps.GetCharPointer(value)); return(value); case SimpleTypeKind.WCharPointer: owner.WriteIntPtr(offset, ModuleOps.GetWCharPointer(value)); return(value); default: throw new InvalidOperationException(); } return(null); }
/// <summary> /// Called for fields which have been limited to a range of bits. Sets the /// specified value into the bits for the field. /// </summary> private void SetBitsValue(MemoryHolder address, int baseOffset, object value) { // get the value in the form of a ulong which can contain the biggest bitfield ulong newBits; if (IsBoolType) { newBits = PythonOps.IsTrue(value) ? 1ul : 0ul; } else { value = PythonOps.Index(value); // since 3.8 if (value is int iVal) { newBits = (ulong)iVal; } else if (value is BigInteger biVal) { if (biVal.Sign >= 0) { if (biVal <= ulong.MaxValue) { newBits = (ulong)biVal; } else { newBits = (ulong)(biVal & ulong.MaxValue); } } else { if (biVal >= long.MinValue) { newBits = (ulong)(long)biVal; } else { newBits = (ulong)(biVal & ulong.MaxValue); } } } else { throw new InvalidOperationException("unreachable"); } } // do the same for the existing value int offset = checked (_offset + baseOffset); ulong valueBits; if (IsBoolType) { valueBits = address.ReadByte(offset); } else { object curValue = _fieldType.GetValue(address, null, offset, false); if (curValue is int iCurVal) { valueBits = (ulong)iCurVal; } else { valueBits = (ulong)(long)(BigInteger)curValue; } } // get a mask for the bits this field owns ulong targetBits = ((1UL << _bits) - 1) << _bitsOffset; // clear the existing bits valueBits &= ~targetBits; // or in the new bits provided by the user valueBits |= (newBits << _bitsOffset) & targetBits; // and set the value if (IsBoolType) { address.WriteByte(offset, (byte)valueBits); } else if (IsSignedType) { if (_fieldType.Size <= 4) { _fieldType.SetValue(address, offset, (int)(long)valueBits); } else { _fieldType.SetValue(address, offset, (BigInteger)(long)valueBits); } } else { if (_fieldType.Size < 4) { _fieldType.SetValue(address, offset, (int)valueBits); } else { _fieldType.SetValue(address, offset, (BigInteger)valueBits); } } }