/// <exception cref="System.IO.IOException"></exception>
        private IClassDefinition CreateNestedClassDef(IPortable portable, ClassDefinitionBuilder
                                                      nestedBuilder)
        {
            var writer = new ClassDefinitionWriter(_context, nestedBuilder);

            portable.WritePortable(writer);
            return(_context.RegisterClassDefinition(nestedBuilder.Build()));
        }
        /// <exception cref="System.IO.IOException" />
        internal IClassDefinition ReadClassDefinition(ObjectDataInput @in, int factoryId, int classId,
                                                      int version)
        {
            var register = true;
            var builder  = new ClassDefinitionBuilder(factoryId, classId, version);

            // final position after portable is read
            @in.ReadInt();
            // field count
            var fieldCount = @in.ReadInt();
            var offset     = @in.Position;

            for (var i = 0; i < fieldCount; i++)
            {
                var pos = @in.ReadInt(offset + i * BytesExtensions.SizeOfInt);
                @in.Position = pos;
                var len   = @in.ReadShort();
                var chars = new char[len];
                for (var k = 0; k < len; k++)
                {
                    chars[k] = (char)@in.ReadByte();
                }
                var type           = (FieldType)(@in.ReadByte());
                var name           = new string(chars);
                var fieldFactoryId = 0;
                var fieldClassId   = 0;
                int fieldVersion   = version;
                if (type == FieldType.Portable)
                {
                    // is null
                    if (@in.ReadBoolean())
                    {
                        register = false;
                    }
                    fieldFactoryId = @in.ReadInt();
                    fieldClassId   = @in.ReadInt();
                    if (register)
                    {
                        fieldVersion = @in.ReadInt();
                        ReadClassDefinition(@in, fieldFactoryId, fieldClassId, fieldVersion);
                    }
                }
                else
                {
                    if (type == FieldType.PortableArray)
                    {
                        var k1 = @in.ReadInt();
                        fieldFactoryId = @in.ReadInt();
                        fieldClassId   = @in.ReadInt();
                        if (k1 > 0)
                        {
                            var p = @in.ReadInt();
                            @in.Position = p;
                            fieldVersion = @in.ReadInt();
                            ReadClassDefinition(@in, fieldFactoryId, fieldClassId, fieldVersion);
                        }
                        else
                        {
                            register = false;
                        }
                    }
                }
                builder.AddField(new FieldDefinition(i, name, type, fieldFactoryId, fieldClassId, fieldVersion));
            }
            var classDefinition = builder.Build();

            if (register)
            {
                classDefinition = RegisterClassDefinition(classDefinition);
            }
            return(classDefinition);
        }
 internal ClassDefinitionWriter(IPortableContext context, ClassDefinitionBuilder builder)
 {
     _context = context;
     _builder = builder;
 }
 internal ClassDefinitionWriter(IPortableContext context, int factoryId, int classId, int version)
 {
     _context = context;
     _builder = new ClassDefinitionBuilder(factoryId, classId, version);
 }