Exemple #1
0
        private object ReadType(CtfStruct strct, object[] result, CtfMetadataType type)
        {
            Align(type.Align);

            switch (type.CtfType)
            {
            case CtfTypes.Array:
                CtfArray array = (CtfArray)type;
                int      len   = array.GetLength(strct, result);

                object[] ret = new object[len];

                for (int j = 0; j < len; j++)
                {
                    ret[j] = ReadType(null, null, array.Type);
                }

                return(ret);

            case CtfTypes.Enum:
                return(ReadType(strct, result, ((CtfEnum)type).Type));

            case CtfTypes.Float:
                CtfFloat flt = (CtfFloat)type;
                ReadBits(flt.Exp + flt.Mant);
                return(0f);     // TODO:  Not implemented.

            case CtfTypes.Integer:
                CtfInteger ctfInt = (CtfInteger)type;
                return(ReadInteger(ctfInt));

            case CtfTypes.String:
                bool ascii = ((CtfString)type).IsAscii;
                return(ReadString(ascii));

            case CtfTypes.Struct:
                return(ReadStruct((CtfStruct)type));

            case CtfTypes.Variant:
                CtfVariant var = (CtfVariant)type;

                int      i        = strct.GetFieldIndex(var.Switch);
                CtfField field    = strct.Fields[i];
                CtfEnum  enumType = (CtfEnum)field.Type;

                int    value = strct.GetFieldValue <int>(result, i);
                string name  = enumType.GetName(value);

                field = var.Union.Where(f => f.Name == name).Single();
                return(ReadType(strct, result, field.Type));

            default:
                throw new InvalidOperationException();
            }
        }
Exemple #2
0
        public void ReadTypeIntoBuffer(CtfStruct context, CtfMetadataType type)
        {
            Align(type.Align);

            type.BitOffset = _bitOffset;

            if (type.CtfType == CtfTypes.Enum)
            {
                type           = ((CtfEnum)type).Type;
                type.BitOffset = _bitOffset;
            }
            else if (type.CtfType != CtfTypes.Struct && type.CtfType != CtfTypes.Variant)
            {
                int size = type.GetSize();
                if (size != CtfEvent.SizeIndeterminate)
                {
                    ReadBits(size);
                    return;
                }
            }

            switch (type.CtfType)
            {
            case CtfTypes.Array:
                CtfArray array = (CtfArray)type;

                var indexType = context.GetField(array.Index).Type;
                int len       = CtfInteger.ReadInt <int>(indexType, _buffer, indexType.BitOffset);

                int elemSize = array.Type.GetSize();
                if (elemSize == CtfEvent.SizeIndeterminate)
                {
                    for (int j = 0; j < len; j++)
                    {
                        ReadTypeIntoBuffer(null, array.Type);
                    }
                }
                else
                {
                    for (int j = 0; j < len; j++)
                    {
                        Align(type.Align);
                        ReadBits(elemSize);
                    }
                }
                break;

            case CtfTypes.Float:
                CtfFloat flt = (CtfFloat)type;
                ReadBits(flt.Exp + flt.Mant);
                break;

            case CtfTypes.Integer:
                CtfInteger ctfInt = (CtfInteger)type;
                ReadBits(ctfInt.Size);
                break;

            case CtfTypes.String:
                Debug.Assert((_bitOffset % 8) == 0);
                int startOffset = _bitOffset >> 3;
                int offset      = startOffset;

                ReadBits(8);
                bool ascii = ((CtfString)type).IsAscii;
                if (ascii)
                {
                    while (_buffer[offset++] != 0)
                    {
                        ReadBits(8);
                    }
                }
                else
                {
                    byte b = _buffer[offset];
                    while (b != 0)
                    {
                        switch (b)
                        {
                        default:
                            break;

                        case 0xc:
                        case 0xd:
                            ReadBits(8);
                            break;

                        case 0xe:
                            ReadBits(16);
                            break;

                        case 0xf:
                            ReadBits(24);
                            break;
                        }

                        offset = ReadBits(8) >> 3;
                        b      = _buffer[offset];
                    }
                }

                int bufferLen = (_bitOffset >> 3) - startOffset;

                Encoding encoding = ascii ? Encoding.ASCII : Encoding.UTF8;

                byte[] newArr = Encoding.Convert(encoding, Encoding.Unicode, _buffer, startOffset, bufferLen);
                ((CtfString)type).Length = bufferLen;

                if (_buffer.Length < _bufferLength + newArr.Length)
                {
                    byte[] buffer = ReallocateBuffer(_bufferLength + newArr.Length);
                    System.Buffer.BlockCopy(buffer, 0, _buffer, 0, _bufferLength);
                }

                System.Buffer.BlockCopy(newArr, 0, _buffer, startOffset, newArr.Length);
                _bufferLength = startOffset + newArr.Length;
                _bitOffset    = _bufferLength * 8;

                break;


            case CtfTypes.Struct:
                ReadStruct((CtfStruct)type);
                break;

            case CtfTypes.Variant:
                CtfVariant var = (CtfVariant)type;

                CtfField field    = context.GetField(var.Switch);
                CtfEnum  enumType = (CtfEnum)field.Type;

                int    value = CtfInteger.ReadInt <int>(enumType, _buffer, enumType.BitOffset);
                string name  = enumType.GetName(value);

                field = var.GetVariant(name);
                ReadTypeIntoBuffer(null, field.Type);
                break;

            default:
                throw new InvalidOperationException();
            }
        }