protected void WriteValue(StoreContext context, string valueName, Type valueType, object value) { var writer = context.Writer; ++_nValues; if (_nValues > _valueQuota) { throw new InvalidOperationException("Value count is over quota"); } if (valueType.IsPrimitive) { if (valueType == typeof(int)) { writer.WriteStartElement(IntElementName); writer.WriteValue((int)value); writer.WriteEndElement(); } else if (valueType == typeof(bool)) { writer.WriteStartElement(BoolElementName); writer.WriteValue((bool)value); writer.WriteEndElement(); } else if (valueType == typeof(long)) { writer.WriteStartElement(LongElementName); writer.WriteValue((long)value); writer.WriteEndElement(); } else if (valueType == typeof(float)) { writer.WriteStartElement(FloatElementName); writer.WriteValue((float)value); writer.WriteEndElement(); } else if (valueType == typeof(double)) { writer.WriteStartElement(DoubleElementName); writer.WriteValue((double)value); writer.WriteEndElement(); } else if (valueType == typeof(byte)) { writer.WriteStartElement(ByteElementName); writer.WriteValue((byte)value); writer.WriteEndElement(); } else if (valueType == typeof(char)) { writer.WriteStartElement(CharElementName); writer.WriteValue((char)value); writer.WriteEndElement(); } } else { if (valueType == typeof(decimal)) { writer.WriteStartElement(DecimalElementName); writer.WriteValue((decimal)value); writer.WriteEndElement(); } else if (valueType == typeof(DateTime)) { writer.WriteStartElement(DatetimeElementName); writer.WriteValue((DateTime)value); writer.WriteEndElement(); } else if (valueType == typeof(string)) { if (value != null) { writer.WriteStartElement(StringElementName); writer.WriteValue((string)value); writer.WriteEndElement(); } } else if (valueType.IsEnum) { /// Enum SaveEnumProperty(context, valueType, value); } else { var entity = _container.AsEntity(value); if (entity == null) { if (TypePersisters.ContainsKey(valueType)) { /// TypePersister SaveTypeByTypePersister(context, valueName, valueType, value); } else if (TypeService.Instance.HasStringInterconvertibility(valueType)) { /// TypeConverter SaveTypeConverterProperty(context, valueType, value); } else if (IsSerializableDefined(valueType)) { /// Serializable SaveSerializableProperty(context, valueName, value, valueType); } else { /// normal SaveType(context, value, valueType); } } else { /// Entity if (entity.State == PersistentState.Removed || entity.State == PersistentState.Discarded ) { /// do nothing /// nullと同じ扱いにする } else { SaveEntityProperty(context, entity); } } } } }
/// pre: Value (prop type start element or Proxy empty element or primitive value) must be fetched /// post: next of Value node must be fetched protected object ReadValue(StoreContext context, Type valueType) { var reader = context.Reader; object ret = null; // todo: 要素名で判別すべきかvalueTypeで判別すべきか // valueTypeで判別するのなら型を要素名として保存する必要はない switch (reader.Name) { case IntElementName: { ret = reader.ReadElementContentAsInt(); break; } case BoolElementName: { ret = reader.ReadElementContentAsBoolean(); break; } case LongElementName: { ret = reader.ReadElementContentAsLong(); break; } case FloatElementName: { ret = reader.ReadElementContentAsFloat(); break; } case DoubleElementName: { ret = reader.ReadElementContentAsDouble(); break; } case ByteElementName: { ret = (byte)reader.ReadElementContentAsInt(); break; } case CharElementName: { ret = (char)reader.ReadElementContentAsInt(); break; } case DecimalElementName: { ret = reader.ReadElementContentAsDecimal(); break; } case DatetimeElementName: { ret = reader.ReadElementContentAsDateTime(); break; } case StringElementName: { ret = reader.ReadElementContentAsString(); break; } default: { if (reader.IsStartElement(EnumElementName)) { /// Enum型 ret = ReadEnumProperty(context, valueType); } else if (reader.IsStartElement(EntityElementName)) { /// Entity var typeStr = reader.GetAttribute(0); var assemStr = reader.GetAttribute(1); var id = reader.GetAttribute(2); var type = GetTypeObject(typeStr, assemStr); try { ret = _container.Find(type, id); } catch (Exception e) { ret = null; Logger.Warn( "Failed to load entity: assembly=" + assemStr + ", type=" + typeStr + ", id=" + id, e ); } reader.Read(); /// consume IEntity Empty Element and fetch Property end element } else if (reader.IsStartElement(SerializableElementName)) { /// Serializable ret = ReadSerializableProperty(context); } else { if (reader.IsStartElement()) /// start of type of prop { var typeStr = reader.GetAttribute(0); var assemStr = reader.GetAttribute(1); var type = GetTypeObject(typeStr, assemStr); if (TypePersisters.ContainsKey(type)) { /// TypePersister var values = new Dictionary <string, string>(); LoadDictionaryProperty( context, values, new Type[] { typeof(string), typeof(string) } ); ret = TypePersisters[type].Load(values); reader.ReadEndElement(); } else { var service = TypeService.Instance; if (service.HasStringInterconvertibility(type)) { /// TypeConverter ret = ReadTypeConverterProperty(context, valueType); } else { /// normal //ret = Activator.CreateInstance(type); var act = service.GetDefaultActivator(type); ret = act(); if (!reader.IsEmptyElement) { LoadType(context, ret, valueType); } else { reader.Read(); /// consume Empty Element and fetch next } } } } else { throw new InvalidOperationException(); } } break; } } ; return(ret); }