public static void WriteValue(this IntPtr baseAddr, ref int offset, ItemType type, object value) { switch (type) { case ItemType.Int8: case ItemType.UInt8: Marshal.WriteByte(baseAddr, offset, Convert.ToByte(value, CultureInfo.InvariantCulture)); // (byte)value); break; case ItemType.Bool: case ItemType.Int16: case ItemType.UInt16: Marshal.WriteInt16(baseAddr, offset, Convert.ToInt16(value, CultureInfo.InvariantCulture)); //(short)value); break; case ItemType.UInt32: case ItemType.Int32: Marshal.WriteInt32(baseAddr, offset, Convert.ToInt32(value, CultureInfo.InvariantCulture)); //(int)value); break; case ItemType.Fix32: TW_FIX32 f32 = (TW_FIX32)value; WriteFix32(baseAddr, ref offset, f32); return; // no need to update offset for this case ItemType.Frame: TW_FRAME frame = (TW_FRAME)value; WriteFix32(baseAddr, ref offset, frame._left); WriteFix32(baseAddr, ref offset, frame._top); WriteFix32(baseAddr, ref offset, frame._right); WriteFix32(baseAddr, ref offset, frame._bottom); return; // no need to update offset for this //case ItemType.String1024: // WriteString(baseAddr, offset, value as string, 1024); // break; case ItemType.String128: WriteString(baseAddr, offset, (string)value, 128); break; case ItemType.String255: WriteString(baseAddr, offset, (string)value, 255); break; case ItemType.String32: WriteString(baseAddr, offset, (string)value, 32); break; case ItemType.String64: WriteString(baseAddr, offset, (string)value, 64); break; //case ItemType.Unicode512: // WriteUString(baseAddr, offset, value as string, 512); // break; } offset += type.GetSize(); }
/// <summary> /// Generates a <see cref="TW_CAPABILITY"/> using single value (aka TW_ONEVALUE). /// </summary> /// <typeparam name="T"></typeparam> /// <param name="cap"></param> /// <param name="type"></param> /// <param name="value"></param> /// <returns></returns> public TW_CAPABILITY Generate <T>(CapabilityId cap, ItemType type, T value) { // size of data + uint16 item type var valueSz = type.GetSize(); if (valueSz < 4) { valueSz = 4; // onevalue container value minimum is 32bit } var memSz = valueSz + 2; // + item type field var twCap = new TW_CAPABILITY { Capability = cap, ContainerType = ContainerType.OneValue, hContainer = config.MemoryManager.Allocate((uint)memSz) }; if (twCap.hContainer != IntPtr.Zero) { IntPtr baseAddr = config.MemoryManager.Lock(twCap.hContainer); try { int offset = 0; // TODO: type size may be different on mac baseAddr.WriteValue(ref offset, ItemType.UInt16, value); // ONEVALUE is special in value can be uint32 or string // if less than uint32 put it in lower word // (string value seems undocumented but internet says put it as-is and not a pointer) if (valueSz < 4) { Marshal.WriteInt16(baseAddr, offset, 0); offset += 2; } baseAddr.WriteValue(ref offset, type, value); } finally { config.MemoryManager.Unlock(twCap.hContainer); } } return(twCap); }