private void loadInstVarIds(System.IO.Stream stream, SmalltalkArchive archive, SmalltalkPointerObject obj, int size)
        {
            for (int i = 0; i < obj.Class.InstVarNames.Count; i++)
            {
                obj.InstVars[i] = new SmalltalkValueReference(archive, readInteger(stream));
            }

            if (size > 0)
            {
                if (obj.Class.IsVariable)
                {
                    for (int i = 0; i < size; i++)
                    {
                        obj.InstVars.Add(new SmalltalkValueReference(archive, (readInteger(stream))));
                    }
                }
                else
                { // Drop filed indexed values on the floor
                    for (int i = 0; i < size; i++)
                    {
                        readInteger(stream);
                    }
                }
            }
        }
        private XElement ExportClasses(SmalltalkArchive archive)
        {
            var root = new XElement("Classes");

            foreach (SmalltalkClass @class in archive.Classes.Values.Where(c => !c.IsHidden).OrderBy(c => c.ClassId))
            {
                var xmlClass = new XElement("Class");

                if (@class.IsMetaClass)
                {
                    xmlClass.SetAttributeValue("isMetaClass", true);
                }

                xmlClass.SetAttributeValue("cid", @class.ClassId);
                xmlClass.SetAttributeValue("rep", @class.Rep);

                if (!string.IsNullOrEmpty(@class.LibraryName))
                {
                    xmlClass.SetAttributeValue("lib", @class.LibraryName);
                }

                xmlClass.SetAttributeValue("name", @class.ClassName);

                foreach (var varName in @class.InstVarNames)
                {
                    xmlClass.Add(new XElement("Ivar", new XAttribute("name", varName)));
                }
                root.Add(xmlClass);
            }
            return(root);
        }
        /* Write a <behavior descriptor> entry for each behavior
         * <behavior type> <id> <nameString> <NUL><representation><number of named instance vars> [<inst var name>]...<DLL name> <NUL>[version-dependent]
         * for class, store names of all the inst vars in <name> <NUL> form
         */
        private void dumpBehaviorDescriptors(System.IO.Stream stream, SmalltalkArchive archive)
        {
            foreach (SmalltalkClass @class in archive.Classes.Values.Where(c => !c.IsHidden))
            {
                if (@class.IsMetaClass)
                {
                    stream.WriteByte(SmalltalkClass.TagMetaClass);
                }
                else
                {
                    stream.WriteByte(SmalltalkClass.TagClass);
                }

                WriteInteger(stream, @class.ClassId);
                WriteString(stream, @class.ClassName);
                stream.WriteByte(NUL);
                stream.WriteByte(@class.Rep);
                WriteInteger(stream, @class.InstVarNames.Count);

                foreach (var varName in @class.InstVarNames)
                {
                    WriteString(stream, varName);
                    stream.WriteByte(NUL);
                }

                WriteString(stream, @class.LibraryName ?? "");
                stream.WriteByte(NUL);
            }
            stream.WriteByte(NUL);
        }
 public void Serialize(System.IO.Stream stream, SmalltalkArchive archive)
 {
     dumpHeader(stream, archive.Header);
     dumpBehaviorDescriptors(stream, archive);
     dumpObjectDescriptors(stream, archive);
     dumpSoftSlots(stream, archive);
 }
        private void loadObjectDescriptors(System.IO.Stream stream, SmalltalkArchive archive)
        {
            long objectId = 0;
            var  objects  = DefaultObjects;

            while ((objectId = readInteger(stream)) != NUL)
            {
                var classId = readInteger(stream);
                var size    = (int)readInteger(stream);
                var @class  = archive.Classes[classId];
                var hash    = readInteger(stream);

                if (@class.IsBytes)
                {
                    var bytes = new byte[size];
                    stream.Read(bytes, 0, size);
                    var obj = new SmalltalkBytesObject(objectId, size, hash, @class, bytes);
                    objects.Add(objectId, obj);
                }
                else if (@class.IsVariable)
                {
                    var obj = new SmalltalkVariableObject(objectId, size, hash, @class);
                    loadInstVarIds(stream, archive, obj, size);
                    objects.Add(objectId, obj);
                }
                else
                {
                    var obj = new SmalltalkPointerObject(objectId, size, hash, @class);
                    loadInstVarIds(stream, archive, obj, size);
                    objects.Add(objectId, obj);
                }
            }
            archive.Objects = objects;
        }
        public void Serialize(System.IO.Stream stream, SmalltalkArchive archive)
        {
            var writer = System.Xml.XmlWriter.Create(stream);
            var root   = Export(archive);

            root.WriteTo(writer);
            writer.Close();
        }
 private static bool IsCharacterValue(long objectId, SmalltalkArchive archive)
 {
     if (IsObjectValue(objectId, archive))
     {
         return(false);
     }
     return(objectId < archive.IdIntegerZero);
 }
 private static bool IsLongValue(long objectId, SmalltalkArchive archive)
 {
     if (IsObjectValue(objectId, archive))
     {
         return(false);
     }
     return(!IsCharacterValue(objectId, archive));
 }
        public XElement Export(SmalltalkArchive archive)
        {
            var root = new XElement("SmalltalkArchive");

            root.Add(ExportHeader(archive.Header));
            root.Add(ExportClasses(archive));
            root.Add(ExportObjects(archive));
            return(root);
        }
        /* Write an <object descriptor> for each (surrogate) object:
         * <object id> <class id> <number of indexed instance variables><basicHash> <bytesOrPointers>
         */
        private void dumpObjectDescriptors(System.IO.Stream stream, SmalltalkArchive archive)
        {
            var lastBehaviorId = archive.LastBehaviorId;

            foreach (var keyAndValue in archive.Objects)
            {
                if (!(keyAndValue.Value is SmalltalkObject))
                {
                    continue;
                }

                var objectId = keyAndValue.Key;
                var obj      = (SmalltalkObject)keyAndValue.Value;

                long classId    = obj.Class.ClassId;
                int  objectSize = obj.Size;
                long objectHash = obj.Hash;
                bool isBytes    = obj.Class.IsBytes;

                WriteInteger(stream, objectId);
                WriteInteger(stream, classId);
                WriteInteger(stream, objectSize);
                WriteInteger(stream, objectHash);

                if (obj is SmalltalkBytesObject)
                {
                    var bytes = ((SmalltalkBytesObject)obj).Bytes;
                    stream.Write(bytes, 0, bytes.Length);
                }
                else if (obj is SmalltalkVariableObject)
                {
                    var variable = (SmalltalkVariableObject)obj;

                    for (int i = 0; i < variable.InstVars.Count; i++)
                    {
                        var id = variable.InstVars[i].ObjectId;
                        WriteInteger(stream, id);
                    }
                }
                else if (obj is SmalltalkPointerObject)
                {
                    var ptr = (SmalltalkPointerObject)obj;
                    for (int i = 0; i < ptr.Class.InstVarNames.Count; i++)
                    {
                        var id = ptr.InstVars[i].ObjectId;
                        WriteInteger(stream, id);
                    }
                }
                else
                {
                    throw new NotImplementedException($"Unexpected object {obj.GetType().Name}");
                }
            }
            stream.WriteByte(NUL);
        }
 private static object GetObject(long objectId, SmalltalkArchive archive)
 {
     if (archive.Objects.ContainsKey(objectId))
     {
         return(archive.Objects[objectId]);
     }
     else
     {
         return(null);
     }
 }
        private SmalltalkArchive readFrom(System.IO.Stream stream)
        {
            var header = readHeaderFrom(stream);

            var classes = DefaultClasses;

            int tag;

            while ((tag = stream.ReadByte()) != NUL)
            {
                var  classId           = readInteger(stream);
                var  className         = readString(stream, NUL);
                byte rep               = (byte)stream.ReadByte();
                var  numNamedInstVars  = readInteger(stream);
                var  filedInstVarNames = new List <string>();

                for (int i = 0; i < numNamedInstVars; i++)
                {
                    filedInstVarNames.Add(readString(stream, NUL));
                }

                var componentName = readString(stream, NUL);

                classes.Add(classId, new SmalltalkClass(tag, classId, className, rep, filedInstVarNames));
            }

            var archive = new SmalltalkArchive()
            {
                Header  = header,
                Classes = classes
            };

            loadObjectDescriptors(stream, archive);
            //restoreInstanceVariables(archive);

            // Read to end or next ESC
            int nextByte = stream.ReadByte();

            while (nextByte >= 0)
            {
                if (nextByte == ESC)      // Start of next archive
                {
                    stream.Position -= 1; // backup 1
                    break;                // then quick
                }
                nextByte = stream.ReadByte();
            }

            return(archive);
        }
        private XElement ExportObjects(SmalltalkArchive archive)
        {
            var root = new XElement("Objects");

            ExportedObjs = new List <long>();

            var lastBehaviorId = archive.LastBehaviorId;

            foreach (var keyAndValue in archive.Objects.OrderBy(k => k.Key))
            {
                if (!(keyAndValue.Value is SmalltalkObject))
                {
                    continue;
                }

                var objectId = keyAndValue.Key;



                // Some objects are "shortcut exported"
                // e.g. OrderedCollections
                if (ExportedObjs.Contains(objectId))
                {
                    continue;
                }

                var  obj     = (SmalltalkObject)keyAndValue.Value;
                long classId = obj.Class.ClassId;

                var xmlObject = new XElement("Object");

                xmlObject.SetAttributeValue("id", objectId);
                xmlObject.SetAttributeValue("refcid", classId);

                if (obj.Size > 0)
                {
                    xmlObject.SetAttributeValue("size", obj.Size);
                }

                xmlObject.SetAttributeValue("hash", obj.Hash);

                if (obj is SmalltalkBytesObject)
                {
                    Export((SmalltalkBytesObject)obj, xmlObject);
                }
                else if (obj is SmalltalkVariableObject)
                {
                    Export((SmalltalkVariableObject)obj, xmlObject);
                }
                else if (obj is SmalltalkPointerObject)
                {
                    Export((SmalltalkPointerObject)obj, xmlObject);
                }
                else
                {
                    throw new NotImplementedException($"Unexpected object {obj.GetType().Name}");
                }

                root.Add(xmlObject);
            }
            return(root);
        }
 /* The soft slots section format is:
  * <soft slot type count>[ <soft slot values list> ]...NUL
  * where each type of soft slot has an entry containing the set selector
  * for that soft slot and a list of the id pairs containing the id of the
  * object with the soft slot value and the filed id of its value:
  * <set selector> [ <object id> <soft slot value id> ]... NUL
  */
 private void dumpSoftSlots(System.IO.Stream stream, SmalltalkArchive archive)
 {
     // Softslots disabled in Smalltalk
     WriteInteger(stream, 0); // Number of softslots
     stream.WriteByte(NUL);   // Section Terminator
 }
 private static bool IsObjectValue(long objectId, SmalltalkArchive archive)
 {
     return(objectId < archive.IdCharacterZero);
 }
 public SmalltalkValueReference(SmalltalkArchive archive, long objectId)
 {
     Archive  = archive;
     ObjectId = objectId;
 }