//------------------------------------------------------------------------------------- /// <summary> /// Инициализирующий конструктор. /// </summary> public TransBox(GlobalObject obj, PulsarSerializationParams pars) { if(obj == null) throw new ArgumentNullException("obj"); if(pars == null) throw new ArgumentNullException("obj"); if(pars.NoStubObjects == null) pars.NoStubObjects = new object[1] { obj }; else if(pars.NoStubObjects.Contains(obj) == false) { pars.NoStubObjects = new List<object>(pars.NoStubObjects); ((List<object>)pars.NoStubObjects).Add(obj); } using(MemoryStream ms = PulsarSerializer.Serialize(obj, pars)) { ms.Position = 0; _data = ms.ToArray(); } }
/// <summary> /// Метод запроса к серверу Пульсара. /// </summary> /// <param name="query">Объект запроса.</param> /// <param name="pars">Параметры сериализации запроса.</param> /// <param name="messageHandler">Делегат метода, вызываемый для обработки сообщений сервера.</param> /// <returns></returns> public static PulsarAnswer Query(PulsarQuery query, PulsarSerializationParams pars, Action<PulsarAnswer> messageHandler = null) { TcpClient cl = null; Stream ns = null; try { OnDataAccessBegin(); if(query == null) throw new ArgumentNullException("query"); cl = new TcpClient(); cl.ReceiveTimeout = ReceiveTimeOut * 1000; cl.ReceiveBufferSize = ReceiveBufSize ; cl.SendTimeout = SendTimeOut * 1000; cl.SendBufferSize = SendBufSize; cl.Connect(Address.ToString(), Port); ns = cl.GetStream(); if(messageHandler != null) query.Params |= PulsarQueryParams.Verbose; if(pars == null) pars = new PulsarSerializationParams() { Mode = PulsarSerializationMode.ForClient }; using(MemoryStream temp = PulsarSerializer.Serialize(query, pars)) { byte[] buf = new byte[cl.SendBufferSize]; int bytes; while((bytes = temp.Read(buf, 0, buf.Length)) != 0) ns.Write(buf, 0, bytes); } Stopwatch sw = null; if(traceLevel >= 3) sw = Stopwatch.StartNew(); if(traceLevel >= 5) { ns = new DebugStream(ns, "c:\\temp"); Debug.WriteLine(((DebugStream)ns).DebugFileName); } PulsarAnswer answer = null; do { answer = (PulsarAnswer)PulsarSerializer.Deserialize(ns, LoadEssences); if(answer.Answer == PulsarAnswerStatus.Error) throw new PulsarServerException((answer.Return ?? "").ToString()); if(answer.Answer == PulsarAnswerStatus.Message || answer.Answer == PulsarAnswerStatus.ErrorMessage) { if(messageHandler != null) messageHandler(answer); continue; } break; } while(true); if(traceLevel >= 3) { sw.Stop(); Debug.WriteLine("{0}: {1}", Thread.CurrentThread.Name, sw.Elapsed); Debug.Flush(); } return answer; } catch { throw; } finally { if(ns != null) ns.Close(); if(cl != null) cl.Close(); OnDataAccessEnd(); } }
//------------------------------------------------------------------------------------- /// <summary> /// Метод запроса к серверу Пульсара. /// </summary> /// <param name="query">Объект запроса.</param> /// <param name="noStub">Типы объектов, которые не должны быть заглушены при отправке запроса.</param> /// <param name="noSer">Типы объектов, которые не должны быть сериализованы при отправке запроса.</param> /// <param name="messageHandler">Делегат метода, вызываемый для обработки сообщений сервера.</param> /// <returns></returns> public static PulsarAnswer Query(PulsarQuery query, IEnumerable<Type> noStub = null, IEnumerable<Type> noSer = null, Action<PulsarAnswer> messageHandler = null) { PulsarSerializationParams pars = new PulsarSerializationParams(); pars.NoStubTypes = noStub; pars.AsEmptyTypes = noSer; pars.Mode = PulsarSerializationMode.ForClient; return Query(query, pars, messageHandler); }
//------------------------------------------------------------------------------------- /// <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; } }
/// <summary> /// Выполняет запрос на Пульсаре (с модицикацией). /// </summary> /// <param name="query">Запрос.</param> /// <param name="pars">Параметры сериализации запроса.</param> /// <param name="messageHandler">Делегат метода, вызываемый для обработки сообщений сервера.</param> /// <returns></returns> public object Modify(PulsarQuery query, PulsarSerializationParams pars, Action<PulsarAnswer> messageHandler = null) { query.Params |= PulsarQueryParams.Modify; pars.Mode = PulsarSerializationMode.ForClient; return Query(query, pars, messageHandler: messageHandler).Return; }
/// <summary> /// Метод запроса к серверу Пульсара. /// </summary> /// <param name="query">Объект запроса.</param> /// <param name="pars">Параметры сериализации запроса.</param> /// <param name="messageHandler">Делегат метода, вызываемый для обработки сообщений сервера.</param> /// <returns></returns> public PulsarAnswer Query(PulsarQuery query, PulsarSerializationParams pars, Action<PulsarAnswer> messageHandler = null) { TcpClient cl = null; Stream ns = null; try { OnDataAccessBegin(); if(query == null) throw new ArgumentNullException("query"); cl = new TcpClient(); cl.ReceiveTimeout = ReceiveTimeOut; cl.ReceiveBufferSize = ReceiveBufferSize; cl.SendTimeout = SendTimeOut; cl.SendBufferSize = SendBufferSize; cl.Connect(Address.ToString(), Port); ns = cl.GetStream(); ns.WriteByte((byte)QueryType.Object); if(messageHandler != null) query.Params |= PulsarQueryParams.Verbose; if(pars == null) pars = new PulsarSerializationParams() { Mode = PulsarSerializationMode.ForClient }; using(MemoryStream temp = PulsarSerializer.Serialize(query, pars)) { byte[] buf = new byte[cl.SendBufferSize]; int bytes; while((bytes = temp.Read(buf, 0, buf.Length)) != 0) ns.Write(buf, 0, bytes); } PulsarAnswer answer = null; do { answer = (PulsarAnswer)PulsarSerializer.Deserialize(ns); if(answer.Answer == PulsarAnswerStatus.Error) throw new PulsarServerException((answer.Return ?? "").ToString()); if(answer.Answer == PulsarAnswerStatus.TestMessage || answer.Answer == PulsarAnswerStatus.ErrorMessage) { if(messageHandler != null) messageHandler(answer); continue; } break; } while(true); return answer; } catch { throw; } finally { if(ns != null) ns.Close(); if(cl != null) cl.Close(); OnDataAccessEnd(); } }
//------------------------------------------------------------------------------------- #region << Controls Handlers>> private void buttonSend_Click(object sender, EventArgs e) { try { ftgvView.Tree = null; List<Object> noStub = new List<Object>(); PulsarQuery q = new PulsarQuery(); q.RootObject = tbObj.Text; q.Query = tbQuery.Text.TrimAll().Length == 0 ? null : tbQuery.Text.TrimAll(); if(tbArgs.Text.TrimAll().Length > 0) { q.Args = ParamsDic.FromString(tbArgs.Text.Replace('|', '¦')); foreach(string p in q.Args.Params.ToArray()) if(q.Args[p] is string && ((string)q.Args[p]).StartsWith("$") && ((string)q.Args[p]).EndsWith("$")) q.Args[p] = store[((string)q.Args[p]).Replace("$", "")].Object; else if(q.Args[p] is string && ((string)q.Args[p]).StartsWith("&") && ((string)q.Args[p]).EndsWith("&")) { q.Args[p] = store[((string)q.Args[p]).Replace("&", "")].Object; noStub.Add(q.Args[p]); } } q.NoStubTypes = noStubList.Count > 0 ? noStubList.ToArray() : null; q.NoSerTypes = noSerList.Count > 0 ? noSerList.ToArray() : null; if(chbModify.Checked) q.Params |= PulsarQueryParams.Modify; if(chbNonPublic.Checked) q.Params |= PulsarQueryParams.NonPublic; if(chbServant.Checked) q.Params |= PulsarQueryParams.Servant; if(chbCode.Checked) q.Params |= PulsarQueryParams.Code; if(chbVerbose.Checked) q.Params |= PulsarQueryParams.Verbose; if(chbNoStubEs.Checked) q.Params |= PulsarQueryParams.NoStubEssences; PulsarSerializationParams pars = new PulsarSerializationParams(); pars.Mode = PulsarSerializationMode.ForClient; pars.NoStubObjects = noStub.ToArray(); ShowProgressWindow(); if(q.Params.HasFlag(PulsarQueryParams.Verbose)) TaskManager.Run("Query", this, () => PulsarConnection.Default.Query(q, pars, messageHandler: (a) => ToLog(null, a.ToString()))); else TaskManager.Run("Query", this, () => PulsarConnection.Default.Query(q, pars)); ToLog(true, q.ToString()); } catch(Exception Err) { ModalErrorBox.Show(Err, PanelBack); } }