/* =========================================================================== Copyright (C) 2015-2019 Project Meteor Dev Team This file is part of Project Meteor Server. Project Meteor Server is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Project Meteor Server is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Project Meteor Server. If not, see . =========================================================================== */ using System; namespace Meteor.Common { [global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] public sealed class BitfieldLengthAttribute : Attribute { uint length; public BitfieldLengthAttribute(uint length) { this.length = length; } public uint Length { get { return length; } } } public static class PrimitiveConversion { public static UInt32 ToUInt32(T t) where T : struct { UInt32 r = 0; int offset = 0; // For every field suitably attributed with a BitfieldLength foreach (System.Reflection.FieldInfo f in t.GetType().GetFields()) { object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false); if (attrs.Length == 1) { uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length; // Calculate a bitmask of the desired length uint mask = 0; for (int i = 0; i < fieldLength; i++) mask |= (UInt32)1 << i; r |= ((UInt32)f.GetValue(t) & mask) << offset; offset += (int)fieldLength; } } return r; } public static long ToLong(T t) where T : struct { long r = 0; int offset = 0; // For every field suitably attributed with a BitfieldLength foreach (System.Reflection.FieldInfo f in t.GetType().GetFields()) { object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false); if (attrs.Length == 1) { uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length; // Calculate a bitmask of the desired length long mask = 0; for (int i = 0; i < fieldLength; i++) mask |= 1L << i; r |= ((UInt32)f.GetValue(t) & mask) << offset; offset += (int)fieldLength; } } return r; } } }