Beispiel #1
0
        private void XmlFieldValue(byte[] data)
        {
            object        value = null;
            SuggestedType type  = BlobUtil.GetSuggestedType(data);

            switch (type)
            {
            case SuggestedType.StringType:
                value = BlobUtil.TrimNull(Encoding.ASCII.GetString(data));
                break;

            case SuggestedType.Int8Type:
                value = data[0];
                break;

            case SuggestedType.Int16Type:
                value = BitConverter.ToInt16(data, 0);
                break;

            case SuggestedType.Int32Type:
                value = BitConverter.ToInt32(data, 0);
                break;

            case SuggestedType.Int64Type:
                value = BitConverter.ToInt64(data, 0);
                break;

            default:
                value = Convert.ToBase64String(data);
                break;
            }

            xmlOut.WriteAttributeString("type", Convert.ToString(type));
            xmlOut.WriteString(Convert.ToString(value));
        }
Beispiel #2
0
        public void LoadByteKey(byte[] key)
        {
            int index = ByteKeys.FindIndex(x => x.Length == key.Length && BlobUtil.UnsafeCompare(x, key));

            if (index < 0)
            {
                ByteKeys.Add(key);
                index = ByteKeys.Count - 1;
            }

            ilgen.Emit(OpCodes.Ldarg_1);
            ilgen.Emit(index < 256 ? OpCodes.Ldc_I4_S : OpCodes.Ldc_I4, index);
            ilgen.Emit(OpCodes.Ldelem, typeof(byte[]));
        }
Beispiel #3
0
        private void ReadBlobHeader()
        {
            cacheState  = (ECacheState)source.ReadByte();
            processCode = (EAutoPreprocessCode)source.ReadByte();

            bytesAvailable = source.ReadInt32();
            spareAvailable = source.ReadInt32();

            if (!BlobUtil.IsValidCacheState(cacheState) || !BlobUtil.IsValidProcess(processCode))
            {
                throw new InvalidBlobException("Invalid blob header");
            }

            TakeBytes(BlobHeaderLength);
            UnpackBlobIfNeeded();
        }
Beispiel #4
0
        private void XmlStartField(FieldKeyType type, byte[] key, int fieldSize)
        {
            string keyValue;

            if (BlobUtil.IsIntDescriptor(key))
            {
                keyValue = Convert.ToString(BitConverter.ToUInt32(key, 0));
            }
            else
            {
                keyValue = Encoding.UTF8.GetString(key);
            }

            xmlOut.WriteStartElement("field");
            xmlOut.WriteAttributeString("key", keyValue);
        }
        public object Read(Object target, BlobReader reader)
        {
            if (target != null)
            {
                reader = reader.ReadFieldBlob();
            }

            object result = Activator.CreateInstance(targetType);

read_field:
            while (reader.CanTakeBytes(BlobReader.FieldHeaderLength))
            {
                reader.ReadFieldHeader();

                for (int i = 0; i < fields.Length; i++)
                {
                    var field = fields[i];

                    if ((field.PeekIntKey != -1 && field.PeekIntKey == reader.PeekIntKey) ||
                        (field.ByteKey.Length == reader.FieldKeyBytes && BlobUtil.UnsafeCompare(field.ByteKey, reader.ByteKey)))
                    {
                        field.Serializer.Read(result, reader);
                        goto read_field;
                    }
                }

                reader.SkipField();
            }

            reader.SkipSpare();

            if (target != null)
            {
                reader.Dispose();
            }

            return(result);
        }
Beispiel #6
0
        private void ProcessFields(int serializedSize)
        {
            while (serializedSize > FieldHeaderLength && CanRead(FieldHeaderLength))
            {
                Int16 descriptorLength;
                Int32 dataLength;

                byte[] descriptor;

                Mark(FieldHeaderLength);

                try
                {
                    descriptorLength = input.ReadInt16();
                    dataLength       = input.ReadInt32();

                    if (descriptorLength <= 0 || !CanRead(descriptorLength + dataLength))
                    {
                        Reset();
                        throw new Exception("Corrupted field lengths");
                    }

                    serializedSize -= FieldHeaderLength;

                    descriptor = new byte[descriptorLength];
                    input.Read(descriptor, 0, descriptorLength);

                    serializedSize -= descriptorLength;
                }
                catch (Exception)
                {
                    Reset();
                    throw new Exception("Corrupted field");
                }

                if (Field != null)
                {
                    Field((BlobUtil.IsIntDescriptor(descriptor) ? FieldKeyType.IntType : FieldKeyType.StringType),
                          descriptor, dataLength);
                }

                if (!TryReadBlob((uint)dataLength))
                {
                    byte[] data = new byte[dataLength];
                    input.Read(data, 0, dataLength);

                    if (FieldValue != null)
                    {
                        FieldValue(data);
                    }
                }

                if (EndField != null)
                {
                    EndField();
                }

                serializedSize -= dataLength;
            }

            if (serializedSize != 0)
            {
                throw new Exception("Data left untouched in Field");
            }
        }
Beispiel #7
0
        private bool TryReadBlob(UInt32 lengthHint)
        {
            if (!CanRead(BlobHeaderLength) || lengthHint < BlobHeaderLength)
            {
                return(false);
            }

            ECacheState         cachestate;
            EAutoPreprocessCode process;
            Int32 serialized, spare;

            Mark(BlobHeaderLength);

            try
            {
                cachestate = (ECacheState)input.ReadByte();
                process    = (EAutoPreprocessCode)input.ReadByte();

                serialized = input.ReadInt32();
                spare      = input.ReadInt32();
            }
            catch (Exception)
            {
                Reset();
                throw new InvalidDataException("Corrupted blob");
            }

            if (!BlobUtil.IsValidCacheState(cachestate) || !BlobUtil.IsValidProcess(process) ||
                serialized < 0 || spare < 0 ||
                !CanReadMarked(serialized))
            {
                Reset();
                return(false);
            }

            serialized -= BlobHeaderLength;


            if (process != EAutoPreprocessCode.eAutoPreprocessCodePlaintext)
            {
                PeekableStream originalStream = input;
                object         extendedData   = null;

                input = HandleProcessCode(process, ref serialized, out extendedData);

                bool result = TryReadBlob((uint)serialized);

                input.ReadBytes(40);   // read and dispose HMACs
                // todo: validate them?

                input.Close();
                input = originalStream;

                return(result);
            }

            if (Blob != null)
            {
                Blob(process, cachestate);
            }

            ProcessFields(serialized);

            if (spare > 0)
            {
                byte[] spareData = new byte[spare];
                input.Read(spareData, 0, spare);

                if (Spare != null)
                {
                    Spare(spareData);
                }
            }

            if (EndBlob != null)
            {
                EndBlob();
            }

            return(true);
        }
Beispiel #8
0
        private static object GetDataForProp(byte[] buffer, Type propType)
        {
            object data        = null;
            object integerData = null;

            Type enumType = null;

            // pull out integer data before parsing it, not always the # of bytes we want
            switch (buffer.Length)
            {
            case 1:
                integerData = buffer[0];
                break;

            case 2:
                integerData = BitConverter.ToInt16(buffer, 0);
                break;

            case 4:
                integerData = BitConverter.ToInt32(buffer, 0);
                break;

            case 8:
                integerData = BitConverter.ToInt64(buffer, 0);
                break;
            }

            if (propType.IsEnum)
            {
                enumType = propType;
                propType = Enum.GetUnderlyingType(propType);
            }

            if (propType == typeof(uint))
            {
                data = Convert.ToUInt32(integerData);
            }
            else if (propType == typeof(int))
            {
                data = Convert.ToInt32(integerData);
            }
            else if (propType == typeof(ushort))
            {
                data = Convert.ToUInt16(integerData);
            }
            else if (propType == typeof(short))
            {
                data = Convert.ToInt16(integerData);
            }
            else if (propType == typeof(string))
            {
                data = BlobUtil.TrimNull(Encoding.ASCII.GetString(buffer));
            }
            else if (propType == typeof(bool))
            {
                data = Convert.ToBoolean(integerData);
            }
            else if (propType == typeof(byte))
            {
                data = Convert.ToByte(integerData);
            }
            else if (propType == typeof(byte[]))
            {
                data = buffer;
            }
            else if (propType == typeof(ulong))
            {
                data = Convert.ToUInt64(integerData);
            }
            else if (propType == typeof(long))
            {
                data = Convert.ToInt64(integerData);
            }
            else if (propType == typeof(MicroTime))
            {
                data = new MicroTime(Convert.ToUInt64(integerData));
            }
            else
            {
                throw new NotImplementedException("Missing handler in GetDataForProp of type " + propType.ToString());
            }

            if (enumType != null)
            {
                data = Enum.ToObject(enumType, data);
            }

            return(data);
        }
Beispiel #9
0
        private void TypeStartField(FieldKeyType type, byte[] key, int fieldSize)
        {
            string keyValue;

            if (BlobUtil.IsIntDescriptor(key))
            {
                keyValue = Convert.ToString(BitConverter.ToUInt32(key, 0));
            }
            else
            {
                keyValue = Encoding.UTF8.GetString(key);
            }

            int          fieldIndex;
            ProcessState top = PeekStackTop();

            if (top.State == EProcessingState.TopSearch &&
                TestFieldAttributeState(top, keyValue, out fieldIndex))
            {
                PushTypeAttributesToStack(typeof(T), Target);
            }
            else if (top.State == EProcessingState.FieldSearch &&
                     TestFieldAttributeState(top, keyValue, out fieldIndex))
            {
                PropertyInfo       prop   = top.Properties[fieldIndex];
                BlobFieldAttribute attrib = top.Attributes[fieldIndex];

                Type subType = prop.PropertyType;
                Type genericType;
                int  genericCount;

                if (subType.IsTypeListOrDictionary(out genericType, out genericCount))
                {
                    object subInstance = CacheUtil.FastConstruct(TypedCache, subType); //Activator.CreateInstance(subType);

                    prop.SetValue(top.WorkingType, subInstance, null);

                    PushListTypeAttributesToStack(subInstance, attrib, prop);
                }
                else if (attrib.Complex == true)
                {
                    object subInstance = CacheUtil.FastConstruct(TypedCache, subType); //Activator.CreateInstance(subType);

                    prop.SetValue(top.WorkingType, subInstance, null);

                    PushTypeAttributesToStack(subType, subInstance);
                }
                else if (attrib.SubFieldDepth > 0 ||
                         attrib.SubFieldKey != null)
                {
                    PushSubSearchAttributeToStack(top, attrib, prop, top.WorkingType);
                }
                else
                {
                    expectingIndex = fieldIndex;
                }
            }
            else if (top.State == EProcessingState.SubFieldSearch &&
                     TestSubFieldAttributeState(top, keyValue, out fieldIndex))
            {
                expectingIndex = fieldIndex;
            }
            else if (top.State == EProcessingState.EveryFieldSearch &&
                     depth - top.Depth == 1)
            {
                PropertyInfo prop = top.Properties[0];

                Type subType;
                int  genericCount;

                bool genericType = prop.PropertyType.IsTypeListOrDictionary(out subType, out genericCount);

                if (top.Attributes[0].Complex == true && genericType)
                {
                    object subInstance = CacheUtil.FastConstruct(TypedCache, subType); //Activator.CreateInstance(subType);

                    CacheUtil.HandleAddCall(prop, genericCount, top.WorkingType, keyValue, subInstance);

                    PushTypeAttributesToStack(subType, subInstance);
                }
                else if (fieldSize == 0 && genericType)
                {
                    // key is the actual field.
                    object value = GetDataForProp(key, subType);

                    CacheUtil.HandleAddCall(prop, genericCount, top.WorkingType, expectedKey, value);
                }
                else
                {
                    expectedKey    = keyValue;
                    expectingIndex = 0;
                }
            }
        }