Пример #1
0
        public void Serialize(Stream stream, IUnique source, AlertLog log = null)
        {
            log?.RaiseAlert("BEG", "Beginning serialisation...");
            _Format  = new Dictionary <string, TypeFieldsFormat>();
            _Aliases = new Dictionary <Type, string>();
            _Uniques = new UniquesCollection();
            _Writer  = new StreamWriter(stream);

            // Write base item:
            _Writer.WriteLine(SerializeItem(source));

            // Write uniques:
            int i = 0;

            while (i < _Uniques.Count)
            {
                log?.RaiseAlert("PROG", "Writing...", (double)i / (double)_Uniques.Count, AlertLevel.Information);
                IUnique unique = _Uniques[i];
                _Writer.WriteLine(SerializeItem(unique));
                i++;
            }

            //_Writer.WriteLine();
            //_Writer.WriteLine(FORMAT);

            //_Writer.Write(GenerateFormatDescription());

            _Writer.Flush();

            log?.RaiseAlert("BEG", "Serialisation complete.");
        }
Пример #2
0
        public IUnique Deserialize(Stream stream, AlertLog log = null)
        {
            IUnique result = null;

            _Format  = new Dictionary <string, TypeFieldsFormat>();
            _Aliases = new Dictionary <Type, string>();
            _Uniques = new UniquesCollection();
            _Reader  = new StreamReader(stream);

            // First, read through once to end:
            log?.RaiseAlert("FORM", "Reading format data...");

            string line;
            int    lineCount = 0;

            while ((line = _Reader.ReadLine()) != null)
            {
                lineCount++;
                if (line.StartsWith(FORMAT))
                {
                    ReadFormat(line, log);
                }
                else if (line.StartsWith(DATA))
                {
                    // Initial pass: Create object
                    int    i         = DATA.Length;
                    string guid      = line.NextChunk(ref i, KEY_SEPARATOR);
                    string typeAlias = line.NextChunk(ref i, OPEN_DATABLOCK);
                    if (_Format.ContainsKey(typeAlias))
                    {
                        TypeFieldsFormat format = _Format[typeAlias];

                        IUnique unique = format.Type.Instantiate() as IUnique;//FormatterServices.GetUninitializedObject(format.Type) as IUnique;
                        if (unique is IUniqueWithModifiableGUID)
                        {
                            var uniqueMG = (IUniqueWithModifiableGUID)unique;
                            uniqueMG.SetGUID(new Guid(guid));
                        }
                        else
                        {
                            FieldInfo fI = format.Type.GetBaseField("_GUID"); // Will not work if backing field is named differently!
                            fI.SetValue(unique, new Guid(guid));
                        }
                        _Uniques.Add(unique);
                        if (result == null)
                        {
                            result = unique;                 // Set primary output object
                        }
                    }
                    else
                    {
                        log?.RaiseAlert("FNF" + typeAlias, "Formatting data for type alias '" + typeAlias + "' not found.", AlertLevel.Warning);
                    }
                }
            }

            log?.RaiseAlert("FORM", "Format data read.");

            // Next: Second pass - populate fields with data

            // Rewind:
            stream.Seek(0, SeekOrigin.Begin);
            _Reader = new StreamReader(stream);
            int lineNum = 0;

            while ((line = _Reader.ReadLine()) != null)
            {
                log?.RaiseAlert("DAT", "Reading data...", (double)lineNum / (double)lineCount);
                if (line.StartsWith(DATA))
                {
                    // Initial pass: Create object
                    int    i         = DATA.Length;
                    string guid      = line.NextChunk(ref i, KEY_SEPARATOR);
                    string typeAlias = line.NextChunk(ref i, OPEN_DATABLOCK);
                    if (_Format.ContainsKey(typeAlias))
                    {
                        TypeFieldsFormat format = _Format[typeAlias];
                        object           unique = _Uniques[new Guid(guid)];
                        PopulateFields(ref unique, format, ref i, line, log);
                    }
                }
                lineNum++;
            }

            log?.RaiseAlert("DAT", "Reading data complete.", 1.0);

            log?.RaiseAlert("FIN", "Finalising...");

            // Finally: Call OnDeserialized function on each object
            foreach (var unique in _Uniques)
            {
                MethodInfo mInfo = unique.GetType().GetOnDeserializedMethod();
                if (mInfo != null)
                {
                    mInfo.Invoke(unique, new object[] { new StreamingContext() });
                }
                // TODO: Pass in populated streamingcontext arguments?
            }

            log?.RaiseAlert("FIN", "Finalised");

            return(result);
        }