internal void EmitArray(ILGenerator ilgen, ref EntryFieldInfo info, bool lastField) { var count = info.ArraySize; var elemType = info.ElementType; EmitLoadImm(ilgen, count); ilgen.Emit(OpCodes.Newarr, elemType); for (int i = 0; i < count; ++i) { bool last = lastField && i + 1 >= count; ilgen.Emit(OpCodes.Dup); EmitLoadImm(ilgen, i); var id = info.DBCTypeId; switch (id) { case StoredTypeId.Int32: case StoredTypeId.UInt32: EmitLoadOnStackTop(ilgen, id, last); ilgen.Emit(OpCodes.Stelem_I4); break; case StoredTypeId.Int64: case StoredTypeId.UInt64: EmitLoadOnStackTop(ilgen, id, last); ilgen.Emit(OpCodes.Stelem_I8); break; case StoredTypeId.Single: EmitLoadOnStackTop(ilgen, id, last); ilgen.Emit(OpCodes.Stelem_R4); break; case StoredTypeId.String: EmitLoadOnStackTop(ilgen, id, last); ilgen.Emit(OpCodes.Stelem_Ref); break; case StoredTypeId.LazyCString: ilgen.Emit(OpCodes.Ldelema, elemType); EmitLoadOnStackTop(ilgen, id, last); ilgen.Emit(OpCodes.Stobj, elemType); break; default: throw new InvalidOperationException(); } } }
/// <summary> /// Initializes a new instance of <see cref="DBFilesClient.NET.DBCStorage<T>"/> class. /// </summary> public DBCStorage() { m_ctor = m_entryType.GetConstructor(Type.EmptyTypes); if (m_ctor == null) { throw new InvalidOperationException("Cannot find default constructor for " + m_entryTypeName); } var fields = GetFields(); var properties = GetProperties(); var fieldCount = fields.Length; m_fields = new EntryFieldInfo[fieldCount]; for (int i = 0; i < fieldCount; i++) { var attr = fields[i].Value; var field = fields[i].Key; var fieldName = field.Name; Type type; if (attr != null && attr.Option == StoragePresenceOption.UseProperty) { // Property Detected var propertyName = attr.PropertyName; var property = properties.FirstOrDefault(prop => prop.Name == propertyName); if (property == null) { throw new InvalidOperationException("Property " + propertyName + " for field " + fieldName + " of class " + m_entryTypeName + " cannot be found."); } type = property.PropertyType; foreach (var accessor in property.GetAccessors(false)) { if (accessor.ReturnType == field.FieldType) { m_fields[i].Getter = accessor; } else if (accessor.ReturnType == typeof(void)) { m_fields[i].Setter = accessor; } } } else { m_fields[i].FieldInfo = field; type = field.FieldType; } int elementCount = 1; if (type.IsArray) { if (type.GetArrayRank() != 1) { throw new InvalidOperationException( "Field " + fieldName + " of type " + m_entryTypeName + " cannot be a multi-dimensional array."); } if (attr == null || attr.ArraySize < 1) { throw new InvalidOperationException( "Use " + typeof(StoragePresenceAttribute).Name + " to set number of elements of field " + fieldName + " of type " + m_entryTypeName + "."); } m_fields[i].ArraySize = elementCount = attr.ArraySize; m_fields[i].ElementType = type = type.GetElementType(); } if (type.IsEnum) { type = type.GetEnumUnderlyingType(); } if (i == 0 && type != s_intType && type != s_uintType) { throw new InvalidOperationException("First field of type " + m_entryTypeName + " must be Int32 or UInt32."); } if (type == s_intType) { m_fields[i].DBCTypeId = StoredTypeId.Int32; m_entrySize += 4 * elementCount; } else if (type == s_uintType) { m_fields[i].DBCTypeId = StoredTypeId.UInt32; m_entrySize += 4 * elementCount; } else if (type == s_floatType) { m_fields[i].DBCTypeId = StoredTypeId.Single; m_entrySize += 4 * elementCount; } else if (type == s_longType) { m_fields[i].DBCTypeId = StoredTypeId.Int64; m_entrySize += 8 * elementCount; } else if (type == s_ulongType) { m_fields[i].DBCTypeId = StoredTypeId.UInt64; m_entrySize += 8 * elementCount; } else if (type == s_stringType) { m_fields[i].DBCTypeId = StoredTypeId.String; m_entrySize += 4 * elementCount; m_haveString = true; } else if (type == s_lazyCStringType) { m_fields[i].DBCTypeId = StoredTypeId.LazyCString; m_entrySize += 4 * elementCount; m_haveLazyCString = true; } else { throw new InvalidOperationException( "Unknown field type " + type.FullName + " (field " + fieldName + ") of type " + m_entryTypeName + "." ); } } GenerateIdGetter(); }