示例#1
0
        // Note: This method doesn't support aggregate signatures
        public bool StepOver(Signature sig)
        {
            if (sig == Signature.VariantSig)
            {
                Signature valueSig = ReadSignature();
                return(StepOver(valueSig));
            }

            if (sig == Signature.StringSig)
            {
                uint valueLength = ReadUInt32();
                pos += (int)valueLength;
                pos++;
                return(true);
            }

            if (sig == Signature.SignatureSig)
            {
                byte valueLength = ReadByte();
                pos += valueLength;
                pos++;
                return(true);
            }

            // No need to handle dicts specially. IsArray does the job
            if (sig.IsArray)
            {
                Signature elemSig = sig.GetElementSignature();
                uint      ln      = ReadUInt32();
                pos  = Protocol.Padded(pos, elemSig.Alignment);
                pos += (int)ln;
                return(true);
            }

            int endPos = pos;

            if (sig.GetFixedSize(ref endPos))
            {
                pos = endPos;
                return(true);
            }

            if (sig.IsDictEntry)
            {
                pos = Protocol.Padded(pos, sig.Alignment);
                Signature sigKey, sigValue;
                sig.GetDictEntrySignatures(out sigKey, out sigValue);
                if (!StepOver(sigKey))
                {
                    return(false);
                }
                if (!StepOver(sigValue))
                {
                    return(false);
                }
                return(true);
            }

            if (sig.IsStruct)
            {
                pos = Protocol.Padded(pos, sig.Alignment);
                foreach (Signature fieldSig in sig.GetFieldSignatures())
                {
                    if (!StepOver(fieldSig))
                    {
                        return(false);
                    }
                }
                return(true);
            }

            throw new Exception("Can't step over '" + sig + "'");
            //return false;
        }
示例#2
0
        //this requires a seekable stream for now
        public unsafe void WriteArray <T> (T[] val)
        {
            Type elemType = typeof(T);

            if (elemType == typeof(byte))
            {
                if (val.Length > Protocol.MaxArrayLength)
                {
                    throw new Exception("Array length " + val.Length + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
                }

                Write((uint)val.Length);
                stream.Write((byte[])(object)val, 0, val.Length);
                return;
            }

            if (elemType.IsEnum)
            {
                elemType = Enum.GetUnderlyingType(elemType);
            }

            Signature sigElem   = Signature.GetSig(elemType);
            int       fixedSize = 0;

            if (endianness == Connection.NativeEndianness && elemType.IsValueType && !sigElem.IsStruct && sigElem.GetFixedSize(ref fixedSize))
            {
                int byteLength = fixedSize * val.Length;
                if (byteLength > Protocol.MaxArrayLength)
                {
                    throw new Exception("Array length " + byteLength + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
                }
                Write((uint)byteLength);
                WritePad(sigElem.Alignment);

                GCHandle valHandle = GCHandle.Alloc(val, GCHandleType.Pinned);
                IntPtr   p         = valHandle.AddrOfPinnedObject();
                byte[]   data      = new byte[byteLength];
                byte *   bp        = (byte *)p;
                for (int i = 0; i != byteLength; i++)
                {
                    data[i] = bp[i];
                }
                stream.Write(data, 0, data.Length);
                valHandle.Free();
                return;
            }

            long origPos = stream.Position;

            Write((uint)0);

            //advance to the alignment of the element
            WritePad(sigElem.Alignment);

            long startPos = stream.Position;

            TypeWriter <T> tWriter = TypeImplementer.GetTypeWriter <T> ();

            foreach (T elem in val)
            {
                tWriter(this, elem);
            }

            long endPos = stream.Position;
            uint ln     = (uint)(endPos - startPos);

            stream.Position = origPos;

            if (ln > Protocol.MaxArrayLength)
            {
                throw new Exception("Array length " + ln + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes");
            }

            Write(ln);
            stream.Position = endPos;
        }
        // Note: This method doesn't support aggregate signatures
        public bool StepOver(Signature sig)
        {
            if (sig == Signature.VariantSig) {
                Signature valueSig = ReadSignature ();
                return StepOver (valueSig);
            }

            if (sig == Signature.StringSig) {
                uint valueLength = ReadUInt32 ();
                pos += (int)valueLength;
                pos++;
                return true;
            }

            if (sig == Signature.SignatureSig) {
                byte valueLength = ReadByte ();
                pos += valueLength;
                pos++;
                return true;
            }

            // No need to handle dicts specially. IsArray does the job
            if (sig.IsArray) {
                Signature elemSig = sig.GetElementSignature ();
                uint ln = ReadUInt32 ();
                pos = Protocol.Padded (pos, elemSig.Alignment);
                pos += (int)ln;
                return true;
            }

            int endPos = pos;
            if (sig.GetFixedSize (ref endPos)) {
                pos = endPos;
                return true;
            }

            if (sig.IsDictEntry) {
                pos = Protocol.Padded (pos, sig.Alignment);
                Signature sigKey, sigValue;
                sig.GetDictEntrySignatures (out sigKey, out sigValue);
                if (!StepOver (sigKey))
                    return false;
                if (!StepOver (sigValue))
                    return false;
                return true;
            }

            if (sig.IsStruct) {
                pos = Protocol.Padded (pos, sig.Alignment);
                foreach (Signature fieldSig in sig.GetFieldSignatures ())
                    if (!StepOver (fieldSig))
                        return false;
                return true;
            }

            throw new Exception ("Can't step over '" + sig + "'");
            //return false;
        }