Пример #1
0
		//-------------------------------------------------------------------------------------
		#region << Methods >>
		/// <summary>
		/// Возвращает true, если объект заглушен, false - если зарегистрирован
		/// </summary>
		/// <param name="obj"></param>
		/// <param name="cox"></param>
		/// <param name="typeid"></param>
		/// <param name="objid"></param>
		/// <returns></returns>
		private static bool StubGOLObject(GlobalObject obj, SerContext cox, ushort typeid, uint objid)
		{
			if(cox.asEmptyTypes.Contains(obj.GetType()) || cox.asEmptyObjects.Contains(obj))
			{
				#region
				SerObjectInfo si = new SerObjectInfo();
				si.typeID = (ushort)InfraTypes.PulsarEmptyStub;
				si.objID = objid;
				si.fields = new List<SerFieldInfo>(1);

				SerFieldInfo fsi = new SerFieldInfo();
				fsi.typeID = typeid;
				si.fields.Add(fsi);

				if(obj is GlobalObject)
				{
					fsi = new SerFieldInfo();
					fsi.typeID = (ushort)PrimitiveTypes.OID;
					fsi.name = "oid";
					fsi.value = ToBytes(((GlobalObject)obj).OID);
					si.fields.Add(fsi);
				}

				si.Save(cox.stream);
				#endregion 
				return true;
			}

			bool noStub = cox.noStubObjects.Contains(obj);
			if(noStub == false && cox.noStubTypes.Count > 0)
			{
			 Type t = obj.GetType();
				while(t != null)
				 if((noStub = cox.noStubTypes.Contains(t)) == true)
					 break;
					else
					 t = t.BaseType;
			}


			if(typeid == 0)
				typeid = cox.types.GetTypeID(obj.GetType());
			if(objid == 0)
				objid = cox.objs.GetObjID(typeid, obj);

			if(noStub)
			{
				cox.stream.WriteUInt16((ushort)InfraTypes.GOLObjectRegistrator);
				if(Pulsar.Server.ServerParamsBase.IsServer == false && GOL.Contains(obj) == false)
				 GOL.Add(obj);
			}
			else
				cox.stream.WriteUInt16((ushort)InfraTypes.GOLObjectStub);

			cox.stream.WriteUInt16(typeid);
			cox.stream.WriteUInt32(objid);
			cox.stream.WriteBytes(ToBytes(obj.OID));
			if(noStub)
			{
			 if(((IReadWriteLockObject)obj).IsLocked == false)
			  ((IReadWriteLockObject)obj).BeginRead();
				cox.stack.Push(obj);
			}
			return !noStub;
		}
Пример #2
0
		//-------------------------------------------------------------------------------------
		/// <summary>
		/// Сериализует объект в поток.
		/// </summary>
		/// <param name="stream">Поток сериализации/</param>
		/// <param name="obj">Сериализуемый объект.</param>
		/// <param name="pars">Параметры сериализации.</param>
		public static void Serialize(Stream stream, object obj, PulsarSerializationParams pars)
		{
			try
			{
				if(obj == null)
					return;
				if(stream == null)
					throw new ArgumentNullException("stream");
				if(stream.CanWrite == false)
					throw new Exception("Указанный поток сериализации не позволяет запись!");
				
				SerContext cox = new SerContext(stream, pars);

				Type objType = obj.GetType();
				if(IsPrimitive(objType) || objType == typeof(string) || objType == typeof(RefString) || obj is Array || 
								obj is Type || obj is ISelfSerialization)
					obj = new PulsarPrimitiveHolder(obj);
				else if(cox.mode != PulsarSerializationMode.Backup && obj is GlobalObject)
				{
					if(StubGOLObject((GlobalObject)obj, cox, 0, 0))	// cox.noStubObjects.Contains(obj) == false &&
					{
						stream.WriteUInt16(ushort.MaxValue);
						return;
					}
				}
				if(cox.stack.Contains(obj) == false)
					cox.stack.Push(obj);


				ushort objTypeID = 0;
				uint objID = 0;
				SerObjectInfo si = null;
				while(cox.stack.Count > 0)
				{
					obj = cox.stack.Pop();
					objType = obj.GetType();
					objTypeID = cox.types.GetTypeID(objType);
					objID = cox.objs.GetObjID(objTypeID, obj);

					if(si == null)
					{
						si = new SerObjectInfo() { fields = new List<SerFieldInfo>() };
						si.fields.Add(new SerFieldInfo() { name = "$root$" });
						if(obj is GlobalObject)
						{
							SerFieldInfo fsi = new SerFieldInfo();
							fsi.typeID = (ushort)PrimitiveTypes.OID;
							fsi.name = "oid";
							fsi.value = ToBytes(((GlobalObject)obj).OID);
							si.fields.Add(fsi);
						}
					}
					else
						si = new SerObjectInfo();

					if(cox.asEmptyTypes.Contains(objType) || cox.asEmptyObjects.Contains(obj))
					{
						#region
						si.typeID = (ushort)InfraTypes.PulsarEmptyStub;
						si.objID = objID;
						if(si.fields == null)
						 si.fields = new List<SerFieldInfo>(1);

						SerFieldInfo fsi = new SerFieldInfo();
						fsi.typeID = objTypeID;
						si.fields.Add(fsi);

						if(obj is GlobalObject)
						{
							fsi = new SerFieldInfo();
							fsi.typeID = (ushort)PrimitiveTypes.OID;
							fsi.name = "oid";
							fsi.value = ToBytes(((GlobalObject)obj).OID);
							si.fields.Add(fsi);
						}

						si.Save(stream);
						#endregion
						continue;
					}

					si.typeID = objTypeID;
					si.objID = objID;
					CallOnSerializing(obj, cox);

					if(obj is ISerializable)
					{
						#region
						SerializationInfo serInfo = new SerializationInfo(objType, nativeConverter);
						((ISerializable)obj).GetObjectData(serInfo, new StreamingContext());

						FieldWrap m_members = null;
						FieldWrap m_data = null;

						TypeSerializationWrap tw = TypeSerializationWrap.GetTypeSerializationWrap(typeof(SerializationInfo));
						foreach(FieldWrap fw in tw.Fields)
							if(fw.Name == "m_members")
								m_members = fw;
							else if(fw.Name == "m_data")
								m_data = fw;

						if(si.fields == null)
							si.fields = new List<SerFieldInfo>(2);
						SerFieldInfo fsi = new SerFieldInfo();
						fsi.typeID = (ushort)InfraTypes.StringArr;
						fsi.name = "m_members";
						fsi.value = PackArray((Array)m_members.Get(serInfo), cox);
						si.fields.Add(fsi);

						fsi = new SerFieldInfo();
						fsi.typeID = (ushort)InfraTypes.ObjectArr;
						fsi.name = "m_data";
						fsi.value = PackArray((Array)m_data.Get(serInfo), cox);
						si.fields.Add(fsi);

						si.Save(stream);
						CallOnSerialized(obj, cox);
						#endregion
						continue;
					}

					string pref = "";
					while(objType != typeof(object))
					{
						//foreach(FieldInfo fi in objType.GetFields(fieldsDiscovery))
						foreach(FieldWrap fw in TypeSerializationWrap.GetTypeSerializationWrap(objType).Fields)
						{
							if(fw.NoSerMode != null)
								if(fw.NoSerMode.Value == PulsarSerializationMode.Default || 
												cox.mode == PulsarSerializationMode.Default || 
											(fw.NoSerMode & cox.mode) > 0)
												continue;

							object val = fw.Get(obj);

							if(val == null || val is Delegate)
								continue;
							Type valType = val is Type ? typeof(Type) : val.GetType();
							if(valType.IsValueType && valType == fw.Type && val.Equals(Activator.CreateInstance(valType)))
								continue;

							if(fw.ByDemandModes != null)
								if(fw.ByDemandModes.Value == PulsarSerializationMode.Default || 
												cox.mode == PulsarSerializationMode.Default ||
												(fw.ByDemandModes & cox.mode) == 0)
							{
								if(cox.opts.HasFlag(PulsarSerializationOptions.IgnoreAllByDemandSerialization) == false &&
											cox.byDemandTypes.Contains(valType) == false)
									continue;
							}

							SerFieldInfo fsi = new SerFieldInfo();
							fsi.typeID = cox.types.GetTypeID(valType);
							fsi.name = pref + fw.Name;

							// При добавлении, посмотреть PackArray
							if(fsi.typeID <= 25 || valType.IsEnum || fsi.typeID == (uint)InfraTypes.RefString)
								fsi.value = ToBytes(val);
							else if(val is ISelfSerialization)
							{
								CallOnSerializing(val, cox);
								fsi.value = ((ISelfSerialization)val).GetSerializedData();
								CallOnSerialized(val, cox);
							}
							else if(val is Type)
								fsi.value = ToBytes(cox.types.GetTypeID((Type)val));
							else if(val is Array)
								fsi.value = PackArray((Array)val, cox);
							else
							{
								uint id;
								if(cox.objs.AddAsNew(fsi.typeID, val, out id))
									if(val is GlobalObject && pars != null && pars.Options.HasFlag(PulsarSerializationOptions.DeepSerialization) == false)
										StubGOLObject((GlobalObject)val, cox, fsi.typeID, id);
									else
										cox.stack.Push(val);
								fsi.value = ToBytes(id);
							}
							if(si.fields == null)
								si.fields = new List<SerFieldInfo>();
							si.fields.Add(fsi);
						}
						objType = objType.BaseType;
						if(objType == null || objType == typeof(object))
							break;
						pref += '.';
					}
					si.Save(stream);
					CallOnSerialized(obj, cox);
				}
				stream.WriteUInt16(ushort.MaxValue);
			}
			catch
			{
				throw;
			}
		}
Пример #3
0
 //-------------------------------------------------------------------------------------
 public void Load(Stream fs)
 {
  // typeID - уже должен быть прочитан
  try
  {
   objID = fs.ReadUInt32();
   byte count = (byte)fs.ReadByte();
   if(count > 0)
    index = new Dictionary<string, SerFieldInfo>(count);
   for(; count > 0; count--)
   {
    SerFieldInfo sfi = new SerFieldInfo();
    sfi.Load(fs);
    index.Add(sfi.name, sfi);
   }
  }
  catch
  {
   throw;
  }
 }