Example #1
0
        public static T Read2(TProtocol iprot, T value)
        {
            IProtoColumn <T>[] columns = instance.Value.columns;
            iprot.IncrementRecursionDepth();
            try
            {
                iprot.ReadStructBegin();
                while (true)
                {
                    TField field = iprot.ReadFieldBegin();
                    if (field.Type == TType.Stop)
                    {
                        break;
                    }

                    if (field.ID < columns.Length)
                    {
                        IProtoColumn <T> column = columns[field.ID];
                        column.Read(iprot, value);
                    }
                    else
                    {
                        TProtocolUtil.Skip(iprot, field.Type);
                    }

                    iprot.ReadFieldEnd();
                }
                iprot.ReadStructEnd();
                return(value);
            }
            finally
            {
                iprot.DecrementRecursionDepth();
            }
        }
Example #2
0
 public static void Write(XmlWriter writer, T proto)
 {
     IProtoColumn <T>[] columns = instance.Value.columns;
     for (int index = 0; index < columns.Length; index++)
     {
         IProtoColumn <T> column = columns[index];
         if (column != null)
         {
             column.Write(writer, proto);
         }
     }
 }
Example #3
0
        public static void Write(JsonWriter writer, T proto)
        {
            IProtoColumn <T>[] columns = instance.Value.columns;

            writer.WriteStartObject();
            for (int index = 0; index < columns.Length; index++)
            {
                IProtoColumn <T> column = columns[index];
                if (column != null)
                {
                    column.Write(writer, proto);
                }
            }
            writer.WriteEndObject();
        }
Example #4
0
        /// <summary>
        /// Serialize a tuple into stream.
        ///
        /// The following data are writen into the stream
        /// 1. bitmask bytes length
        /// 2. bitmarks bytes
        /// 3. serialized value for each column in columns masks.
        ///
        /// </summary>
        /// <typeparam name="T">tuple type</typeparam>
        /// <param name="tuple">tuple object</param>
        /// <param name="stream">the stread to write the tuple into</param>
        /// <param name="columnMasks">column masks for serialized columns</param>
        public static void Serialize <T>(this Stream stream, T proto, ProtoSchema schema)
        {
            using (BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8, true))
            {
                int    bitPos   = (int)stream.Position;
                byte[] bitmarks = new byte[schema.ColumnMasks.Length];
                writer.Write((byte)bitmarks.Length);
                writer.Write(bitmarks, 0, bitmarks.Length);

                for (int index = 0; index < schema.Columns.Length; index++)
                {
                    IProtoColumn column = schema.Columns[index];
                    if (column.ID >= schema.ColumnMasks.Length * 8)
                    {
                        break;
                    }

                    if (!schema.ColumnMasks.GetBitmask(column.ID))
                    {
                        bitmarks.SetBitmask(column.ID, false);
                        continue;
                    }

                    object value = proto.GetValue(column);
                    if (CommonUtils.Equals(value, column.DefaultValue))
                    {
                        bitmarks.SetBitmask(column.ID, false);
                    }
                    else
                    {
                        bitmarks.SetBitmask(column.ID, true);
                        column.Write(writer, value);
                    }
                }

                int endPos = (int)stream.Position;
                stream.Position = bitPos;

                writer.Write((byte)bitmarks.Length);
                writer.Write(bitmarks, 0, bitmarks.Length);

                stream.Position = endPos;
            }
        }
Example #5
0
 public static void Write2(TProtocol oprot, T value)
 {
     IProtoColumn <T>[] columns = instance.Value.columns;
     oprot.IncrementRecursionDepth();
     try
     {
         TStruct struc = new TStruct(typeof(T).Name);
         oprot.WriteStructBegin(struc);
         for (int index = 0; index < columns.Length; index++)
         {
             IProtoColumn <T> column = columns[index];
             if (column != null)
             {
                 column.Write(oprot, value);
             }
         }
         oprot.WriteFieldStop();
         oprot.WriteStructEnd();
     }
     finally
     {
         oprot.DecrementRecursionDepth();
     }
 }
Example #6
0
 /// <summary>
 /// Get column value
 /// </summary>
 /// <param name="proto">proto object</param>
 /// <param name="column">proto column</param>
 /// <returns>column value</returns>
 public static object GetValue(T proto, IProtoColumn column)
 {
     return(instance.Value.getters[column.Index](proto));
 }
Example #7
0
        ///// <summary>
        ///// Gets column by column ID
        ///// </summary>
        ///// <param name="id">column ID</param>
        ///// <returns>proto column</returns>
        //public static IProtoColumn GetColumn(int id)
        //{
        //    return Proto<T>.Columns[id - 1];
        //}

        public static bool TryGetColumn(string name, bool ignoreCase, out IProtoColumn column)
        {
            column = Proto <T> .Columns.SingleOrDefault(col => string.Compare(col.Name, name, ignoreCase) == 0);

            return(column != null);
        }
Example #8
0
        /// <summary>
        /// Create a ProtoColumn for a specific type.
        /// </summary>
        /// <param name="type">Column type</param>
        /// <param name="name">Column name</param>
        /// <param name="id">Column ID</param>
        /// <returns>protocolumn object</returns>
        private static IProtoColumn CreateColumn(Type type, string name, short id = 0, short colIndex = 0, bool nullable = false, bool ignored = false)
        {
            if (type == typeof(string))
            {
                return(new StringColumn
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    Ignored = ignored,
                });
            }
            else if (type == typeof(bool))
            {
                return(new BooleanColumn
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    IsNullable = nullable,
                    Ignored = ignored,
                });
            }
            else if (type == typeof(byte))
            {
                return(new ByteColumn
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    IsNullable = nullable,
                    Ignored = ignored,
                });
            }
            else if (type == typeof(short))
            {
                return(new Int16Column
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    IsNullable = nullable,
                    Ignored = ignored,
                });
            }
            else if (type == typeof(ushort))
            {
                return(new UInt16Column
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    IsNullable = nullable,
                    Ignored = ignored,
                });
            }
            else if (type == typeof(int))
            {
                return(new Int32Column
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    IsNullable = nullable,
                    Ignored = ignored,
                });
            }
            else if (type == typeof(uint))
            {
                return(new UInt32Column
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    IsNullable = nullable,
                    Ignored = ignored,
                });
            }
            else if (type == typeof(long))
            {
                return(new Int64Column
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    IsNullable = nullable,
                    Ignored = ignored,
                });
            }
            else if (type == typeof(ulong))
            {
                return(new UInt64Column
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    IsNullable = nullable,
                    Ignored = ignored,
                });
            }
            else if (type == typeof(double))
            {
                return(new DoubleColumn
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    IsNullable = nullable,
                    Ignored = ignored,
                });
            }
            else if (type == typeof(DateTime))
            {
                return(new DateTimeColumn
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    IsNullable = nullable,
                    Ignored = ignored,
                });
            }
            else if (type == typeof(Guid))
            {
                return(new GuidColumn
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    IsNullable = nullable,
                    Ignored = ignored,
                });
            }
            else if (type == typeof(byte[]))
            {
                return(new ImageColumn
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    Ignored = ignored,
                });
            }
            else if (type.IsArray)
            {
                IProtoColumn element = CreateColumn(type.GetElementType(), null);
                return(new ArrayColumn
                {
                    Name = name,
                    ID = id,
                    Index = colIndex,
                    Element = element
                });
            }
            else if (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == typeof(int?).GetGenericTypeDefinition())
            {
                IProtoColumn protoColumn = CreateColumn(type.GetGenericArguments()[0], name, id, colIndex, nullable: true, ignored: ignored);
                if (type.GetGenericTypeDefinition().MakeGenericType(protoColumn.ColumnType) != type)
                {
                    throw new ArgumentException(string.Format("ColumnType of {0} do not match ProtoColumn definition", name));
                }

                return(protoColumn);
            }
            else if (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == typeof(List <int>).GetGenericTypeDefinition())
            {
                IProtoColumn element = CreateColumn(type.GetGenericArguments()[0], null);

                Type listColumnType = typeof(ListColumn <int>).GetGenericTypeDefinition().MakeGenericType(element.ColumnType);

                IProtoColumn protoColumn = (IProtoColumn)System.Activator.CreateInstance(listColumnType);
                TypeUtils.SetProperty(protoColumn, "Name", name);
                TypeUtils.SetProperty(protoColumn, "ID", id);
                TypeUtils.SetProperty(protoColumn, "Index", colIndex);
                TypeUtils.SetProperty(protoColumn, "Ignored", ignored);
                TypeUtils.SetProperty(protoColumn, "Element", element);

                return(protoColumn);
            }
            else if (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == typeof(HashSet <int>).GetGenericTypeDefinition())
            {
                IProtoColumn element = CreateColumn(type.GetGenericArguments()[0], null);

                Type listColumnType = typeof(SetColumn <int>).GetGenericTypeDefinition().MakeGenericType(element.ColumnType);

                IProtoColumn protoColumn = (IProtoColumn)System.Activator.CreateInstance(listColumnType);
                TypeUtils.SetProperty(protoColumn, "Name", name);
                TypeUtils.SetProperty(protoColumn, "ID", id);
                TypeUtils.SetProperty(protoColumn, "Index", colIndex);
                TypeUtils.SetProperty(protoColumn, "Ignored", ignored);
                TypeUtils.SetProperty(protoColumn, "Element", element);

                return(protoColumn);
            }
            else if (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == typeof(Dictionary <int, int>).GetGenericTypeDefinition())
            {
                IProtoColumn keyElement   = CreateColumn(type.GetGenericArguments()[0], null);
                IProtoColumn valueElement = CreateColumn(type.GetGenericArguments()[1], null);

                Type mapColumnType = typeof(MapColumn <int, int>).GetGenericTypeDefinition().MakeGenericType(keyElement.ColumnType, valueElement.ColumnType);

                IProtoColumn protoColumn = (IProtoColumn)System.Activator.CreateInstance(mapColumnType);
                TypeUtils.SetProperty(protoColumn, "Name", name);
                TypeUtils.SetProperty(protoColumn, "ID", id);
                TypeUtils.SetProperty(protoColumn, "Index", colIndex);
                TypeUtils.SetProperty(protoColumn, "Ignored", ignored);
                TypeUtils.SetProperty(protoColumn, "KeyElement", keyElement);
                TypeUtils.SetProperty(protoColumn, "ValueElement", valueElement);

                return(protoColumn);
            }
            else if (type.GetCustomAttribute <ProtoAttribute>() != null)
            {
                return(ProtoTypeColumn.CreateColumn(name, id, colIndex, type, ignored, nullable));
            }
            else
            {
                throw new ArgumentException(string.Format("failed to create proto column for type {0}", type));
            }
        }
Example #9
0
        /// <summary>
        /// Initializes proto schema
        /// <remarks>ArgumentException could be thrown if ProtoAttribute and ProtoColumn
        /// attributes are not defined correctly on the type. </remarks>
        /// </summary>
        /// <returns>Proto Schema</returns>
        private static ProtoSchema InitializeSchema(Type type, ref short colIndex)
        {
            BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly;

            List <IProtoColumn> propColumns = new List <IProtoColumn>();

            foreach (PropertyInfo propInfo in type.GetProperties(bindingFlags))
            {
                ProtoColumnAttribute protoColumnAttribute = propInfo.GetCustomAttribute <ProtoColumnAttribute>();
                if (protoColumnAttribute != null)
                {
                    IProtoColumn protoColumn = Proto <T> .CreateColumn(propInfo.PropertyType, propInfo.Name, protoColumnAttribute.ID, colIndex ++, false, protoColumnAttribute.Ignored);

                    propColumns.Add(protoColumn);
                }
            }

            HashSet <string> nameChecks = new HashSet <string>();
            HashSet <short>  idChecks   = new HashSet <short>();

            int maxID = 0;
            int minID = 1;
            int count = 0;

            foreach (IProtoColumn col in propColumns.OfType <IProtoColumn>())
            {
                if (!string.IsNullOrEmpty(col.Name))
                {
                    if (nameChecks.Contains(col.Name))
                    {
                        throw new ProtoException(ProtoErrorCode.InvalidArgument, "Column name {0} is duplicated", col.Name);
                    }
                    else
                    {
                        nameChecks.Add(col.Name);
                    }
                }

                if (idChecks.Contains(col.ID))
                {
                    throw new ProtoException(ProtoErrorCode.InvalidArgument, "Column ID {0} is duplicated", col.ID);
                }
                else
                {
                    idChecks.Add(col.ID);
                }

                count++;
                minID = Math.Min(col.ID, minID);
                maxID = Math.Max(col.ID, maxID);
            }

            if (minID != 1 || maxID != count)
            {
                throw new ProtoException(ProtoErrorCode.InvalidArgument, "Column IDs are not consecutive starting from 1");
            }

            byte[] columnMasks = new byte[CommonUtils.BitmaskSize(count + 1)];

            if (columnMasks.Length > byte.MaxValue)
            {
                throw new ProtoException(ProtoErrorCode.InvalidArgument, "The length of ColumnMasks is greater than {0}", byte.MaxValue);
            }

            for (int index = 0; index < columnMasks.Length; index++)
            {
                columnMasks[index] = 0;
            }

            foreach (IProtoColumn col in propColumns.OfType <IProtoColumn>().Where(c => !c.Ignored))
            {
                CommonUtils.SetBitmask(columnMasks, col.ID, true);
            }

            return(new ProtoSchema
            {
                Name = type.Name,
                ColumnMasks = columnMasks,
                Columns = propColumns.OrderBy(col => col.ID).ToArray(),
            });
        }
Example #10
0
 /// <summary>
 /// Set column value
 /// </summary>
 /// <param name="proto">proto object</param>
 /// <param name="column">proto column</param>
 /// <param name="value">column value</param>
 public static void SetValue(T proto, IProtoColumn column, object value)
 {
     instance.Value.setters[column.Index](proto, value);
 }
Example #11
0
 /// <summary>
 /// Set column value
 /// </summary>
 /// <param name="column">proto column</param>
 /// <param name="value">column value</param>
 public static void SetValue <T>(this T tuple, IProtoColumn column, object value)
 {
     Proto <T> .SetValue(tuple, column, value);
 }
Example #12
0
        // /// <summary>
        // /// Changes context working directory and return a new context
        // /// </summary>
        // /// <param name="context">current context</param>
        // /// <param name="dir">directory to go</param>
        // /// <returns>new context</returns>
        // public static IProtoContext ChangeDirectory(this IProtoContext context, string dir)
        // {
        //     return new ProtoContext(context, dir);
        // }

        // /// <summary>
        // /// Log a trace
        // /// </summary>
        // /// <param name="context">component context</param>
        // /// <param name="component">component name</param>
        // /// <param name="traceLevel">trace level</param>
        // /// <param name="category">trace category</param>
        // /// <param name="msg">message format</param>
        // /// <param name="args">message arguments</param>
        // public static void Log(this IProtoContext context, IProtoComponent component, TraceLevel traceLevel, string category, string msg, params object[] args)
        // {
        //     context.Log(component.Name, traceLevel, category, msg, args);
        // }

        /// <summary>
        /// Get column value
        /// </summary>
        /// <param name="column">proto column</param>
        /// <returns>column value</returns>
        public static object GetValue <T>(this T tuple, IProtoColumn column)
        {
            return(Proto <T> .GetValue(tuple, column));
        }
Example #13
0
        /// <summary>
        /// Initialize proto metadata
        /// </summary>
        /// <returns></returns>
        private static Proto <T> Initialize()
        {
            Type type = typeof(T);

            if (!type.HasCustomAttribute <ProtoAttribute>())
            {
                throw new ProtoException(ProtoErrorCode.InvalidArgument, "ProtoAttribute is not defined for type {0}", type.FullName);
            }

            BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly;

            List <IProtoColumn <T> > propColumns = new List <IProtoColumn <T> >();

            foreach (PropertyInfo propInfo in type.GetProperties(bindingFlags))
            {
                if (propInfo.HasCustomAttribute <ProtoColumnAttribute>())
                {
                    IProtoColumn <T> protoColumn = Proto <T> .CreateProtoColumn(propInfo);

                    propColumns.Add(protoColumn);
                }
            }

            HashSet <string> nameChecks = new HashSet <string>();
            HashSet <short>  idChecks   = new HashSet <short>();

            int maxID = 0;
            int minID = 1;
            int count = 0;

            foreach (IProtoColumn <T> col in propColumns)
            {
                if (!string.IsNullOrEmpty(col.Name))
                {
                    if (nameChecks.Contains(col.Name))
                    {
                        throw new ProtoException(ProtoErrorCode.InvalidArgument, "Duplicated column name {0}", col.Name);
                    }
                    else
                    {
                        nameChecks.Add(col.Name);
                    }
                }

                if (idChecks.Contains(col.ID))
                {
                    throw new ProtoException(ProtoErrorCode.InvalidArgument, "Duplicated column ID {0}", col.ID);
                }
                else
                {
                    idChecks.Add(col.ID);
                }

                count++;
                minID = Math.Min(col.ID, minID);
                maxID = Math.Max(col.ID, maxID);
            }

            // if (minID != 1 || maxID != count)
            // {
            //   throw new ProtoException(ProtoErrorCode.InvalidArgument, "Column IDs are not consecutive starting from 1");
            // }

            if (minID <= 0 && maxID > short.MaxValue)
            {
                throw new ProtoException(ProtoErrorCode.InvalidArgument, "Column IDs must be unique and between 1 to 65535");
            }

            IProtoColumn <T>[] columns = new IProtoColumn <T> [maxID + 1];
            foreach (IProtoColumn <T> column in propColumns)
            {
                columns[column.ID] = column;
            }

            Proto <T> proto = new Proto <T>(columns);

            ParameterExpression iprot    = Expression.Parameter(protType);
            ParameterExpression ivalue   = Expression.Parameter(typeof(T));
            Expression          readExpr = Read(iprot, ivalue, columns);

            proto.reader = Expression.Lambda <Action <TProtocol, T> >(readExpr, iprot, ivalue).Compile();

            ParameterExpression oprot     = Expression.Parameter(protType);
            ParameterExpression ovalue    = Expression.Parameter(typeof(T));
            Expression          writeExpr = Write(oprot, ovalue, columns);

            proto.writer = Expression.Lambda <Action <TProtocol, T> >(writeExpr, oprot, ovalue).Compile();

            return(proto);
        }