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)); }
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[])); }
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(); }
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); }
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"); } }
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); }
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); }
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; } } }