示例#1
0
        protected override void LoadInternal(ref ObjectModel objectModel)
        {
            FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);

            if (fsom == null)
            {
                throw new ObjectModelNotSupportedException();
            }

            Reader reader    = Accessor.Reader;
            string signature = reader.ReadFixedLengthString(8);

            if (!signature.Equals("slick!\0\0"))
            {
                Console.Error.WriteLine("expected 'slick!\\0\\0', got '{0}'", signature);
                throw new InvalidDataFormatException();
            }

            float version = reader.ReadSingle();

            if (version != 1.0f)
            {
                throw new InvalidDataFormatException();
            }

            FileNameSize = reader.ReadInt32();

            int fileCount = reader.ReadInt32();

            for (int i = 0; i < fileCount; i++)
            {
                string fileName = reader.ReadFixedLengthString(FileNameSize).TrimNull();
                int    offset   = reader.ReadInt32();
                int    length   = reader.ReadInt32();

                File file = fsom.AddFile(fileName);
                file.Properties["reader"] = reader;
                file.Properties["offset"] = offset;
                file.Properties["length"] = length;
                file.DataRequest         += File_DataRequest;
            }
        }
示例#2
0
        protected override void BeforeSaveInternal(Stack <ObjectModel> objectModels)
        {
            base.BeforeSaveInternal(objectModels);

            FileNameSize = 32;

            ObjectModel om = objectModels.Pop();
            MochaClassLibraryObjectModel mcl = (om as MochaClassLibraryObjectModel);
            MochaSnapshotObjectModel     mcx = (om as MochaSnapshotObjectModel);

            if (mcl == null && mcx == null)
            {
                throw new ObjectModelNotSupportedException();
            }

            FileSystemObjectModel fsom = new FileSystemObjectModel();

            List <Guid>   _instanceIndices = new List <Guid>();
            List <string> _stringTable     = new List <string>();

            if (mcl != null)
            {
                #region Libraries
                {
                    File           f  = fsom.AddFile("Libraries");
                    MemoryAccessor ma = new MemoryAccessor();
                    ma.Writer.WriteInt32(mcl.Libraries.Count);
                    for (int i = 0; i < mcl.Libraries.Count; i++)
                    {
                        ma.Writer.WriteGuid(mcl.Libraries[i].ID);
                        ma.Writer.WriteInt32(mcl.Libraries[i].Instances.Count);
                        ma.Writer.WriteInt32(mcl.Libraries[i].Relationships.Count);
                    }
                    ma.Close();
                    f.SetData(ma.ToArray());
                }
                #endregion
                #region Instances
                {
                    File           f  = fsom.AddFile("Instances");
                    MemoryAccessor ma = new MemoryAccessor();
                    for (int i = 0; i < mcl.Libraries.Count; i++)
                    {
                        ma.Writer.WriteInt32(mcl.Libraries[i].Instances.Count);
                        for (int j = 0; j < mcl.Libraries[i].Instances.Count; j++)
                        {
                            ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Instances[j].ID));
                            ma.Writer.WriteInt32(mcl.Libraries[i].Instances[j].AttributeValues.Count);

                            MochaInstanceFlags flags = MochaInstanceFlags.None;
                            if (mcl.Libraries[i].Instances[j].Index != null)
                            {
                                flags |= MochaInstanceFlags.HasIndex;
                            }
                            ma.Writer.WriteInt32((int)flags);

                            if ((flags & MochaInstanceFlags.HasIndex) == MochaInstanceFlags.HasIndex)
                            {
                                ma.Writer.WriteInt32(mcl.Libraries[i].Instances[j].Index.Value);
                            }
                        }
                    }
                    ma.Close();
                    f.SetData(ma.ToArray());
                }
                #endregion
                #region Attributes
                {
                    File           f  = fsom.AddFile("Attributes");
                    MemoryAccessor ma = new MemoryAccessor();

                    for (int i = 0; i < mcl.Libraries.Count; i++)
                    {
                        /*
                         * writer.WriteInt32(mcl.Libraries[i].Metadata.Count);
                         * for (int j = 0; j < mcl.Libraries[i].Metadata.Count; j++)
                         * {
                         *      writer.WriteNullTerminatedString(mcl.Libraries[i].Metadata[j].Name);
                         *      writer.WriteNullTerminatedString(mcl.Libraries[i].Metadata[j].Value);
                         * }
                         */
                        for (int j = 0; j < mcl.Libraries[i].Instances.Count; j++)
                        {
                            for (int k = 0; k < mcl.Libraries[i].Instances[j].AttributeValues.Count; k++)
                            {
                                ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Instances[j].AttributeValues[k].AttributeInstanceID));

                                if (mcl.Libraries[i].Instances[j].AttributeValues[k].Value == null)
                                {
                                    ma.Writer.WriteInt32((int)MochaAttributeType.None);
                                }
                                else if (mcl.Libraries[i].Instances[j].AttributeValues[k].Value is string)
                                {
                                    ma.Writer.WriteInt32((int)MochaAttributeType.Text);
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <string>(_stringTable, mcl.Libraries[i].Instances[j].AttributeValues[k].Value as string));
                                }
                                else
                                {
                                    ma.Writer.WriteInt32((int)MochaAttributeType.Unknown);
                                    ma.Writer.WriteObject(mcl.Libraries[i].Instances[j].AttributeValues[k].Value);
                                }
                            }
                        }
                    }

                    ma.Close();
                    f.SetData(ma.ToArray());
                }
                #endregion
                #region Relationships
                {
                    File           f  = fsom.AddFile("Relationships");
                    MemoryAccessor ma = new MemoryAccessor();
                    for (int i = 0; i < mcl.Libraries.Count; i++)
                    {
                        for (int j = 0; j < mcl.Libraries[i].Relationships.Count; j++)
                        {
                            ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Relationships[j].RelationshipInstanceID));
                            ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Relationships[j].SourceInstanceID));

                            ma.Writer.WriteInt32(mcl.Libraries[i].Relationships[j].DestinationInstanceIDs.Count);
                            for (int k = 0; k < mcl.Libraries[i].Relationships[j].DestinationInstanceIDs.Count; k++)
                            {
                                ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Relationships[j].DestinationInstanceIDs[k]));
                            }
                        }
                    }
                    ma.Close();
                    f.SetData(ma.ToArray());
                }
                #endregion

                #region Tenants
                {
                    if (mcl.Tenants.Count > 0)
                    {
                        File           f  = fsom.AddFile("Tenants");
                        MemoryAccessor ma = new MemoryAccessor();
                        ma.Writer.WriteInt32(mcl.Tenants.Count);
                        foreach (MochaTenant tenant in mcl.Tenants)
                        {
                            ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.ID));
                            ma.Writer.WriteInt32(AddOrUpdateLookupTable <string>(_stringTable, tenant.Name));

                            ma.Writer.WriteInt32(tenant.LibraryReferences.Count);
                            for (int i = 0; i < tenant.LibraryReferences.Count; i++)
                            {
                                ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.LibraryReferences[i].LibraryID));
                            }

                            ma.Writer.WriteInt32(tenant.Instances.Count);
                            for (int i = 0; i < tenant.Instances.Count; i++)
                            {
                                ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.Instances[i].ID));
                            }
                            ma.Writer.WriteInt32(tenant.Relationships.Count);
                            for (int i = 0; i < tenant.Relationships.Count; i++)
                            {
                                ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.Relationships[i].SourceInstanceID));
                                ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.Relationships[i].RelationshipInstanceID));
                                ma.Writer.WriteInt32(tenant.Relationships[i].DestinationInstanceIDs.Count);
                                for (int j = 0; j < tenant.Relationships[i].DestinationInstanceIDs.Count; j++)
                                {
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.Relationships[i].DestinationInstanceIDs[j]));
                                }
                            }
                        }
                        ma.Close();
                        f.SetData(ma.ToArray());
                    }
                }
                #endregion
            }
            else if (mcx != null)
            {
                #region Journal
                {
                    if (mcx.Transactions.Count > 0)
                    {
                        File           f  = fsom.AddFile("Journal");
                        MemoryAccessor ma = new MemoryAccessor();
                        foreach (MochaSnapshotTransaction t in mcx.Transactions)
                        {
                            ma.Writer.WriteByte((byte)MochaOpcode.BeginTransaction);
                            ma.Writer.WriteInt32(AddOrUpdateLookupTable <string>(_stringTable, t.TenantName));
                            foreach (MochaSnapshotTransactionOperation op in t.Operations)
                            {
                                if (op is MochaSnapshotCreateInstanceTransactionOperation ci)
                                {
                                    ma.Writer.WriteByte((byte)MochaOpcode.CreateInstance);
                                    ma.Writer.WriteDateTime(ci.EffectiveDate);
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, ci.GlobalIdentifier));
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, ci.ClassGlobalIdentifier));
                                }
                                else if (op is MochaSnapshotAssignAttributeTransactionOperation aa)
                                {
                                    ma.Writer.WriteByte((byte)MochaOpcode.AssignAttribute);
                                    ma.Writer.WriteDateTime(aa.EffectiveDate);
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, aa.SourceInstanceID));
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, aa.AttributeInstanceID));
                                    WriteMochaValue(ma.Writer, aa.Value, _stringTable);
                                }
                                else if (op is MochaSnapshotAssociateRelationshipTransactionOperation ar)
                                {
                                    ma.Writer.WriteByte((byte)MochaOpcode.CreateRelationship);
                                    ma.Writer.WriteDateTime(ar.EffectiveDate);
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, ar.SourceInstanceID));
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, ar.RelationshipInstanceID));
                                    ma.Writer.WriteInt32(ar.TargetInstanceIDs.Count);
                                    foreach (Guid id in ar.TargetInstanceIDs)
                                    {
                                        ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, id));
                                    }
                                }
                            }
                            ma.Writer.WriteByte((byte)MochaOpcode.EndTransaction);
                        }
                        ma.Close();
                        f.SetData(ma.ToArray());
                    }
                }
                #endregion
            }
            #region Guid Table
            {
                File           f  = fsom.AddFile("GlobalIdentifiers");
                MemoryAccessor ma = new MemoryAccessor();
                ma.Writer.WriteInt32(_instanceIndices.Count);
                foreach (Guid id in _instanceIndices)
                {
                    ma.Writer.WriteGuid(id);
                }
                ma.Close();
                f.SetData(ma.ToArray());
            }
            #endregion
            #region String Table
            {
                File           f  = fsom.AddFile("StringTable");
                MemoryAccessor ma = new MemoryAccessor();
                ma.Writer.WriteInt32(_stringTable.Count);
                foreach (string id in _stringTable)
                {
                    ma.Writer.WriteNullTerminatedString(id);
                }
                ma.Close();
                f.SetData(ma.ToArray());
            }
            #endregion

            objectModels.Push(fsom);
        }