The ContentRestriction structure describes a content restriction, which is used to limit a table view to only those rows that include a column with contents matching a search string.
Inheritance: Restrictions
        /// <summary>
        /// Read a value from buffer for special Type.
        /// </summary>
        /// <param name="type">The Type of value.</param>
        /// <param name="buffer">Buffer contains value.</param>
        /// <returns>Byte array of the value.</returns>
        public static byte[] ReadValueByType(ushort type, byte[] buffer)
        {
            byte[] value = null;
            BufferReader bufferReader = new BufferReader(buffer);

            uint length = 0;
            byte[] tmpArray = null;
            uint startIndex = 0;
            uint endIndex = 0;
            switch (type)
            {
                // 2-byte
                // PtypInteger16
                case 0x0002:
                    value = bufferReader.ReadBytes(2);
                    break;

                // 4-byte
                // PtypInteger32
                case 0x0003:

                // PtypFloating32
                case 0x0004:

                // PtypErrorCode 
                case 0x000A:
                    value = bufferReader.ReadBytes(4);
                    break;

                // 8-byte
                // PtypFloating64
                case 0x0005:

                // PtypCurrency 
                case 0x0006:

                // PtypFloatingTime
                case 0x0007:

                // PtypInteger64
                case 0x0014:

                // PtypTime 
                case 0x0040:
                    value = bufferReader.ReadBytes(8);
                    break;

                // 1 byte
                // PtypBoolean 
                case 0x000B:
                    value = new byte[1] { bufferReader.ReadByte() };
                    break;

                // PtypString PT_UNICODE
                case 0x001F:
                    value = Encoding.Unicode.GetBytes(bufferReader.ReadUnicodeString());
                    break;

                // PtypString8
                case 0x001E:
                    value = Encoding.ASCII.GetBytes(bufferReader.ReadASCIIString());
                    break;

                // 16-byte
                // PtypGuid  16bytes
                case 0x0048:

                // PtypServerId 
                case 0x00FB:
                    value = bufferReader.ReadBytes(16);
                    break;

                // PtypRestriction  
                case 0x00FD:
                    tmpArray = bufferReader.ReadToEnd();
                    IRestriction restriction = null;
                    RestrictionType restrictionType = (RestrictionType)tmpArray[0];
                    switch (restrictionType)
                    {
                        case RestrictionType.AndRestriction:
                            restriction = new AndRestriction();
                            break;
                        case RestrictionType.BitMaskRestriction:
                            restriction = new BitMaskRestriction();
                            break;
                        case RestrictionType.CommentRestriction:
                            restriction = new CommentRestriction();
                            break;
                        case RestrictionType.ComparePropertiesRestriction:
                            restriction = new ComparePropertiesRestriction();
                            break;
                        case RestrictionType.ContentRestriction:
                            restriction = new ContentRestriction();
                            break;
                        case RestrictionType.CountRestriction:
                            restriction = new CountRestriction();
                            break;
                        case RestrictionType.ExistRestriction:
                            restriction = new ExistRestriction();
                            break;
                        case RestrictionType.NotRestriction:
                            restriction = new NotRestriction();
                            break;
                        case RestrictionType.OrRestriction:
                            restriction = new OrRestriction();
                            break;
                        case RestrictionType.PropertyRestriction:
                            restriction = new PropertyRestriction();
                            break;
                        case RestrictionType.SizeRestriction:
                            restriction = new SizeRestriction();
                            break;
                        case RestrictionType.SubObjectRestriction:
                            restriction = new SubObjectRestriction();
                            break;
                    }

                    length += restriction.Deserialize(tmpArray);
                    value = bufferReader.ReadBytes(0, length);
                    break;

                // PtypRuleAction  
                case 0x00FE:
                    tmpArray = bufferReader.ReadToEnd();
                    RuleAction ruleAction = new RuleAction();
                    length = ruleAction.Deserialize(tmpArray);
                    bufferReader = new BufferReader(tmpArray);
                    value = bufferReader.ReadBytes(length);
                    break;

                // PtypBinary  
                case 0x0102:
                    length = (uint)(buffer[bufferReader.Position] + (buffer[bufferReader.Position + 1] << 8) + 2);
                    value = bufferReader.ReadBytes(length);
                    break;

                // PtypMultipleInteger16 
                case 0x1002:
                    length = (uint)(buffer[bufferReader.Position] + (buffer[bufferReader.Position + 1] << 8));
                    length = (length * 2) + 2;
                    value = bufferReader.ReadBytes(length);
                    break;

                // PtypMultipleInteger32  
                case 0x1003:

                // PtypMultipleFloating32  
                case 0x1004:
                    length = (uint)(buffer[bufferReader.Position] + (buffer[bufferReader.Position + 1] << 8));
                    length = (length * 4) + 2;
                    value = bufferReader.ReadBytes(length);
                    break;

                // PtypMultipleFloating64 
                case 0x1005:

                // PtypMultipleCurrency
                case 0x1006:

                // PtypMultipleFloatingTime
                case 0x1007:

                // PtypMultipleInteger64
                case 0x1014:

                // PtypMultipleTime 
                case 0x1040:
                    length = (uint)(buffer[bufferReader.Position] + (buffer[bufferReader.Position + 1] << 8));
                    length = (length * 8) + 2;
                    value = bufferReader.ReadBytes(length);
                    break;

                // PtypMultipleString
                case 0x101F:
                    startIndex = bufferReader.Position;
                    ushort strCount = bufferReader.ReadUInt16();
                    for (int istr = 0; istr < strCount; istr++)
                    {
                        bufferReader.ReadUnicodeString();
                    }

                    endIndex = bufferReader.Position;
                    length = endIndex - startIndex;
                    value = bufferReader.ReadBytes(startIndex, length);
                    break;

                // PtypMultipleString8
                case 0x101E:
                    startIndex = bufferReader.Position;
                    ushort str8Count = bufferReader.ReadUInt16();
                    for (int istr8 = 0; istr8 < str8Count; istr8++)
                    {
                        bufferReader.ReadASCIIString();
                    }

                    endIndex = bufferReader.Position;
                    length = endIndex - startIndex;
                    value = bufferReader.ReadBytes(startIndex, length);
                    break;

                // PtypMultipleGuid
                case 0x1048:
                    length = (uint)(buffer[bufferReader.Position] + (buffer[bufferReader.Position + 1] << 8));
                    length = (length * 16) + 2;
                    value = bufferReader.ReadBytes(length);
                    break;

                // PtypMultipleBinary 
                case 0x1102:
                    startIndex = bufferReader.Position;
                    ushort binCount = bufferReader.ReadUInt16();
                    for (int ibin = 0; ibin < binCount; ibin++)
                    {
                        uint binLength = bufferReader.ReadUInt16();
                        bufferReader.ReadBytes(binLength);
                    }

                    endIndex = bufferReader.Position;
                    length = endIndex - startIndex;
                    value = bufferReader.ReadBytes(startIndex, length);
                    break;

                // PtypUnspecified 
                case 0x0000:
                    throw new NotImplementedException();

                // PtypNull
                case 0x0001:
                    value = null;
                    break;

                // PtypObject or PtypEmbeddedTable 
                case 0x000D:
                    throw new NotImplementedException();
            }

            return value;
        }
        /// <summary>
        /// Build a RestrictionData as single ContentRestriction.
        /// </summary>
        /// <param name="taggedPValue">A TaggedPropertyValue of this restriction.</param>
        /// <returns>Restriction Data.</returns>
        public static byte[] GenerateContentRestriction(TaggedPropertyValue taggedPValue)
        {
            ContentRestriction result = new ContentRestriction
            {
                FuzzyLevelLow = ContentRestriction.FuzzyLevelLowValue.FL_SUBSTRING,
                FuzzyLevelHigh = ContentRestriction.FuzzyLevelHighValue.FL_IGNORECASE,
                PropertyTag = taggedPValue.PropertyTag,
                TaggedValue = taggedPValue
            };

            return result.Serialize();
        }
        /// <summary>
        /// Generate test data for creating extended rule.
        /// </summary>
        /// <param name="rulename">The rule name.</param>
        /// <param name="ruleSequence">The rule sequence.</param>
        /// <param name="ruleState">The rule state.</param>
        /// <param name="provider">The rule provider.</param>
        /// <param name="actionType">The rule action Type.</param>
        /// <param name="actionData">The rule action data.</param>
        /// <param name="contentRestrictSubjectName">The subject name of the rule content restriction.</param>
        /// <param name="namedPropertyInfo">The namedPropertyInfo that needed for construct the rule data.</param>
        /// <returns>An array of TaggedPropertyValue of an extended rule.</returns>
        public static TaggedPropertyValue[] GenerateExtendedRuleTestData(string rulename, int ruleSequence, uint ruleState, string provider, ActionType actionType, IActionData actionData, string contentRestrictSubjectName, NamedPropertyInfo namedPropertyInfo)
        {
            List<TaggedPropertyValue> propList = new List<TaggedPropertyValue>();
            TaggedPropertyValue pidTagRuleMessageName = new TaggedPropertyValue();
            PropertyTag pidTagRuleMessageNameTag = new PropertyTag
            {
                PropertyId = (ushort)PropertyId.PidTagRuleMessageName,
                PropertyType = (ushort)PropertyType.PtypString
            };
            pidTagRuleMessageName.PropertyTag = pidTagRuleMessageNameTag;
            pidTagRuleMessageName.Value = Encoding.Unicode.GetBytes(rulename + "\0");
            propList.Add(pidTagRuleMessageName);

            TaggedPropertyValue pidTagMessageClass = new TaggedPropertyValue();
            PropertyTag pidTagMessageClassTag = new PropertyTag
            {
                PropertyId = (ushort)PropertyId.PidTagMessageClass,
                PropertyType = (ushort)PropertyType.PtypString
            };
            pidTagMessageClass.PropertyTag = pidTagMessageClassTag;
            pidTagMessageClass.Value = Encoding.Unicode.GetBytes(Constants.ExtendedRuleMessageClass + "\0");
            propList.Add(pidTagMessageClass);

            TaggedPropertyValue pidTagRuleMessageSequence = new TaggedPropertyValue();
            PropertyTag pidTagRuleMessageSequencePropertyTag = new PropertyTag
            {
                PropertyId = (ushort)PropertyId.PidTagRuleMessageSequence,
                PropertyType = (ushort)PropertyType.PtypInteger32
            };
            pidTagRuleMessageSequence.PropertyTag = pidTagRuleMessageSequencePropertyTag;
            pidTagRuleMessageSequence.Value = BitConverter.GetBytes(ruleSequence);
            propList.Add(pidTagRuleMessageSequence);

            TaggedPropertyValue pidTagRuleMessageState = new TaggedPropertyValue();
            PropertyTag pidTagRuleMessageStatePropertyTag = new PropertyTag
            {
                PropertyId = (ushort)PropertyId.PidTagRuleMessageState,
                PropertyType = (ushort)PropertyType.PtypInteger32
            };
            pidTagRuleMessageState.PropertyTag = pidTagRuleMessageStatePropertyTag;
            pidTagRuleMessageState.Value = BitConverter.GetBytes(ruleState);
            propList.Add(pidTagRuleMessageState);

            TaggedPropertyValue pidTagRuleMessageLevel = new TaggedPropertyValue();
            PropertyTag pidTagRuleMessageLevelPropertyTag = new PropertyTag
            {
                PropertyId = (ushort)PropertyId.PidTagRuleMessageLevel,
                PropertyType = (ushort)PropertyType.PtypInteger32
            };
            pidTagRuleMessageLevel.PropertyTag = pidTagRuleMessageLevelPropertyTag;
            pidTagRuleMessageLevel.Value = BitConverter.GetBytes(Constants.ExtendedRuleMessageLevel);
            propList.Add(pidTagRuleMessageLevel);

            TaggedPropertyValue pidTagRuleMessageProvider = new TaggedPropertyValue();
            PropertyTag pidTagRuleMessageProviderPropertyTag = new PropertyTag
            {
                PropertyId = (ushort)PropertyId.PidTagRuleMessageProvider,
                PropertyType = (ushort)PropertyType.PtypString
            };
            pidTagRuleMessageProvider.PropertyTag = pidTagRuleMessageProviderPropertyTag;
            pidTagRuleMessageProvider.Value = Encoding.Unicode.GetBytes(provider + "\0");
            propList.Add(pidTagRuleMessageProvider);

            ExtendedRuleActions extendedRuleActions = new ExtendedRuleActions
            {
                NamedPropertyInformation = namedPropertyInfo
            };

            extendedRuleActions.RuleVersion = Constants.ExtendedRuleVersion;
            extendedRuleActions.RuleActionBuffer = GetRuleAction(actionType, CountByte.FourBytesCount, actionData, Constants.CommonActionFlavor, Constants.RuleActionFlags);

            TaggedPropertyValue pidTagExtendedRuleMessageActions = new TaggedPropertyValue();
            PropertyTag pidTagExtendedRuleMessageActionsPropertyTag = new PropertyTag
            {
                PropertyId = (ushort)PropertyId.PidTagExtendedRuleMessageActions,
                PropertyType = (ushort)PropertyType.PtypBinary
            };
            pidTagExtendedRuleMessageActions.PropertyTag = pidTagExtendedRuleMessageActionsPropertyTag;
            pidTagExtendedRuleMessageActions.Value = Common.AddInt16LengthBeforeBinaryArray(extendedRuleActions.Serialize());
            propList.Add(pidTagExtendedRuleMessageActions);

            TaggedPropertyValue pidTagExtendedRuleMessageCondition = new TaggedPropertyValue();
            PropertyTag pidTagExtendedRuleMessageConditionPropertyTag = new PropertyTag
            {
                PropertyId = (ushort)PropertyId.PidTagExtendedRuleMessageCondition,
                PropertyType = (ushort)PropertyType.PtypBinary
            };
            pidTagExtendedRuleMessageCondition.PropertyTag = pidTagExtendedRuleMessageConditionPropertyTag;

            TaggedPropertyValue taggedProperty = new TaggedPropertyValue();
            PropertyTag taggedPropertyPropertyTag = new PropertyTag
            {
                PropertyId = (ushort)PropertyId.PidTagSubject,
                PropertyType = (ushort)PropertyType.PtypString
            };
            taggedProperty.PropertyTag = taggedPropertyPropertyTag;
            taggedProperty.Value = Encoding.Unicode.GetBytes(contentRestrictSubjectName + "\0");
            ContentRestriction contentRestriction = new ContentRestriction
            {
                FuzzyLevelLow = ContentRestriction.FuzzyLevelLowValue.FL_SUBSTRING,
                FuzzyLevelHigh = ContentRestriction.FuzzyLevelHighValue.FL_IGNORECASE,
                PropertyTag = taggedProperty.PropertyTag,
                TaggedValue = taggedProperty
            };

            ExtendedRuleCondition extendedRuleCondition = new ExtendedRuleCondition
            {
                NamedPropertyInformation = namedPropertyInfo,
                RuleRestriction = contentRestriction
            };
            pidTagExtendedRuleMessageCondition.Value = Common.AddInt16LengthBeforeBinaryArray(extendedRuleCondition.Serialize());
            propList.Add(pidTagExtendedRuleMessageCondition);
            return propList.ToArray();
        }