Пример #1
0
        internal override void WriteFully(WriteBuffer buf)
        {
            buf.WriteInt32(_length);
            buf.WriteInt32(ProtocolVersion3);

            foreach (var kv in _parameters)
            {
                buf.WriteString(kv.Key);
                buf.WriteByte(0);
                buf.WriteString(kv.Value);
                buf.WriteByte(0);
            }

            buf.WriteByte(0);
        }
Пример #2
0
        private void WriteSprite(Sprite s, ListSet <Timeline> unboundClasses)
        {
            foreach (ICharacterReference cr in s.CharacterRefs)
            {
                this.WriteCharacter(cr.Character, unboundClasses);
            }

            if (s.HasClass && !(s.Class is AdobeClass) && !unboundClasses.Contains(s))
            {
                unboundClasses.Add(s);
            }

            int         id        = this.characterMarshal.GetIDFor(s);
            WriteBuffer tagWriter = this.OpenTag(Tag.DefineSprite, s.ToString() + ";id=" + id.ToString());

            tagWriter.WriteUI16((uint)id);
            tagWriter.WriteUI16(s.FrameCount);
#if DEBUG
            this.LogMessage("char id=" + id);
#endif

            foreach (Frame f in s.Frames)
            {
                if (f.HasLabel)
                {
#if DEBUG
                    this.LogMessage("frame label=" + f.Label);
#endif
                    WriteBuffer labelWriter = this.OpenTag(Tag.FrameLabel);
                    labelWriter.WriteString(f.Label);
                    this.CloseTag();
                }

                foreach (IDisplayListItem dli in f.DisplayList)
                {
                    switch (dli.Type)
                    {
                    case DisplayListItemType.PlaceObjectX:
                        this.WritePlaceObjectTag((PlaceObject)dli);
                        break;

                    case DisplayListItemType.RemoveObjectX:
                        this.WriteRemoveObjectTag((RemoveObject)dli);
                        break;

                    default:
                        /* ISSUE 73 */
                        throw new SWFModellerException(
                                  SWFModellerError.UnimplementedFeature,
                                  "Unsupported tag in SWF sprite writer: " + dli.GetType().ToString());
                    }
                }

                this.WriteBodylessTag(Tag.ShowFrame);
            }

            this.WriteBodylessTag(Tag.End, id.ToString());

            this.CloseTag(); /* DefineSprite */
        }
Пример #3
0
    internal void WriteStartup(Dictionary <string, string> parameters)
    {
        const int protocolVersion3 = 3 << 16; // 196608

        var len = sizeof(int) +               // Length
                  sizeof(int) +               // Protocol version
                  sizeof(byte);               // Trailing zero byte

        foreach (var kvp in parameters)
        {
            len += PGUtil.UTF8Encoding.GetByteCount(kvp.Key) + 1 +
                   PGUtil.UTF8Encoding.GetByteCount(kvp.Value) + 1;
        }

        // Should really never happen, just in case
        if (len > WriteBuffer.Size)
        {
            throw new Exception("Startup message bigger than buffer");
        }

        WriteBuffer.WriteInt32(len);
        WriteBuffer.WriteInt32(protocolVersion3);

        foreach (var kv in parameters)
        {
            WriteBuffer.WriteString(kv.Key);
            WriteBuffer.WriteByte(0);
            WriteBuffer.WriteString(kv.Value);
            WriteBuffer.WriteByte(0);
        }

        WriteBuffer.WriteByte(0);
    }
Пример #4
0
    internal async Task WriteSASLInitialResponse(string mechanism, byte[] initialResponse, bool async, CancellationToken cancellationToken = default)
    {
        var len = sizeof(byte) +                                                // Message code
                  sizeof(int) +                                                 // Length
                  PGUtil.UTF8Encoding.GetByteCount(mechanism) + sizeof(byte) +  // Mechanism plus null terminator
                  sizeof(int) +                                                 // Initial response length
                  (initialResponse?.Length ?? 0);                               // Initial response payload

        if (WriteBuffer.WriteSpaceLeft < len)
        {
            await WriteBuffer.Flush(async, cancellationToken);
        }

        WriteBuffer.WriteByte(FrontendMessageCode.Password);
        WriteBuffer.WriteInt32(len - 1);

        WriteBuffer.WriteString(mechanism);
        WriteBuffer.WriteByte(0);   // null terminator
        if (initialResponse == null)
        {
            WriteBuffer.WriteInt32(-1);
        }
        else
        {
            WriteBuffer.WriteInt32(initialResponse.Length);
            WriteBuffer.WriteBytes(initialResponse);
        }
    }
Пример #5
0
        public override bool Write(ref DirectBuffer directBuf)
        {
            if (_lexemePos == -1)
            {
                if (_writeBuf.WriteSpaceLeft < 4)
                {
                    return(false);
                }
                _writeBuf.WriteInt32(_value.Count);
                _lexemePos = 0;
            }

            for (; _lexemePos < _value.Count; _lexemePos++)
            {
                if (_writeBuf.WriteSpaceLeft < MaxSingleLexemeBytes)
                {
                    return(false);
                }

                _writeBuf.WriteString(_value[_lexemePos].Text);
                _writeBuf.WriteByte(0);
                _writeBuf.WriteInt16(_value[_lexemePos].Count);
                for (var i = 0; i < _value[_lexemePos].Count; i++)
                {
                    _writeBuf.WriteInt16(_value[_lexemePos][i]._val);
                }
            }

            return(true);
        }
Пример #6
0
        protected override async Task Write(object value, WriteBuffer buf, LengthCache lengthCache, NpgsqlParameter parameter,
                                            bool async, CancellationToken cancellationToken)
        {
            var vector = (NpgsqlTsVector)value;

            if (buf.WriteSpaceLeft < 4)
            {
                await buf.Flush(async, cancellationToken);
            }
            buf.WriteInt32(vector.Count);

            foreach (var lexeme in vector)
            {
                if (buf.WriteSpaceLeft < MaxSingleLexemeBytes)
                {
                    await buf.Flush(async, cancellationToken);
                }

                buf.WriteString(lexeme.Text);
                buf.WriteByte(0);
                buf.WriteInt16(lexeme.Count);
                for (var i = 0; i < lexeme.Count; i++)
                {
                    buf.WriteInt16(lexeme[i].Value);
                }
            }
        }
Пример #7
0
        protected override async Task Write(object value, WriteBuffer buf, LengthCache lengthCache, NpgsqlParameter parameter,
                                            bool async, CancellationToken cancellationToken)
        {
            var query     = (NpgsqlTsQuery)value;
            var numTokens = GetTokenCount(query);

            if (buf.WriteSpaceLeft < 4)
            {
                await buf.Flush(async, cancellationToken);
            }
            buf.WriteInt32(numTokens);

            if (numTokens == 0)
            {
                return;
            }

            _stack.Push(query);

            while (_stack.Count > 0)
            {
                if (buf.WriteSpaceLeft < 2)
                {
                    await buf.Flush(async, cancellationToken);
                }

                if (_stack.Peek().Kind == NpgsqlTsQuery.NodeKind.Lexeme && buf.WriteSpaceLeft < MaxSingleTokenBytes)
                {
                    await buf.Flush(async, cancellationToken);
                }

                var node = _stack.Pop();
                buf.WriteByte(node.Kind == NpgsqlTsQuery.NodeKind.Lexeme ? (byte)1 : (byte)2);
                if (node.Kind != NpgsqlTsQuery.NodeKind.Lexeme)
                {
                    buf.WriteByte((byte)node.Kind);
                    if (node.Kind == NpgsqlTsQuery.NodeKind.Not)
                    {
                        _stack.Push(((NpgsqlTsQueryNot)node).Child);
                    }
                    else
                    {
                        _stack.Push(((NpgsqlTsQueryBinOp)node).Right);
                        _stack.Push(((NpgsqlTsQueryBinOp)node).Left);
                    }
                }
                else
                {
                    var lexemeNode = (NpgsqlTsQueryLexeme)node;
                    buf.WriteByte((byte)lexemeNode.Weights);
                    buf.WriteByte(lexemeNode.IsPrefixSearch ? (byte)1 : (byte)0);
                    buf.WriteString(lexemeNode.Text);
                    buf.WriteByte(0);
                }
            }

            _stack.Clear();
        }
Пример #8
0
        public override void Write(object value, WriteBuffer buf, NpgsqlParameter parameter)
        {
            string str;
            var    asEnum = (TEnum)value;

            if (!_enumToLabel.TryGetValue(asEnum, out str))
            {
                throw new InvalidCastException($"Can't write value {asEnum} as enum {typeof (TEnum)}");
            }

            buf.WriteString(str);
        }
Пример #9
0
    internal async Task WriteParse(string sql, string statementName, List <NpgsqlParameter> inputParameters, bool async, CancellationToken cancellationToken = default)
    {
        Debug.Assert(statementName.All(c => c < 128));

        int queryByteLen;

        try
        {
            queryByteLen = TextEncoding.GetByteCount(sql);
        }
        catch (Exception e)
        {
            Break(e);
            throw;
        }

        if (WriteBuffer.WriteSpaceLeft < 1 + 4 + statementName.Length + 1)
        {
            await Flush(async, cancellationToken);
        }

        var messageLength =
            sizeof(byte) +                        // Message code
            sizeof(int) +                         // Length
            statementName.Length +                // Statement name
            sizeof(byte) +                        // Null terminator for the statement name
            queryByteLen + sizeof(byte) +         // SQL query length plus null terminator
            sizeof(ushort) +                      // Number of parameters
            inputParameters.Count * sizeof(int);  // Parameter OIDs

        WriteBuffer.WriteByte(FrontendMessageCode.Parse);
        WriteBuffer.WriteInt32(messageLength - 1);
        WriteBuffer.WriteNullTerminatedString(statementName);

        await WriteBuffer.WriteString(sql, queryByteLen, async, cancellationToken);

        if (WriteBuffer.WriteSpaceLeft < 1 + 2)
        {
            await Flush(async, cancellationToken);
        }
        WriteBuffer.WriteByte(0); // Null terminator for the query
        WriteBuffer.WriteUInt16((ushort)inputParameters.Count);

        foreach (var p in inputParameters)
        {
            if (WriteBuffer.WriteSpaceLeft < 4)
            {
                await Flush(async, cancellationToken);
            }

            WriteBuffer.WriteInt32((int)p.Handler !.PostgresType.OID);
        }
    }
Пример #10
0
        internal override void WriteFully(WriteBuffer buf)
        {
            buf.WriteByte(Code);
            buf.WriteInt32(Length - 1);

            buf.WriteString(_mechanism);
            buf.WriteByte(0);   // null terminator
            if (_initialResponse == null)
            {
                buf.WriteInt32(-1);
            }
            else
            {
                buf.WriteInt32(_initialResponse.Length);
                buf.WriteBytes(_initialResponse);
            }
        }
Пример #11
0
        internal override async Task Write(WriteBuffer buf, bool async, CancellationToken cancellationToken)
        {
            Debug.Assert(Statement != null && Statement.All(c => c < 128));

            var queryByteLen = _encoding.GetByteCount(Query);

            if (buf.WriteSpaceLeft < 1 + 4 + Statement.Length + 1)
            {
                await buf.Flush(async, cancellationToken);
            }

            var messageLength =
                1 +                         // Message code
                4 +                         // Length
                Statement.Length +
                1 +                         // Null terminator
                queryByteLen +
                1 +                         // Null terminator
                2 +                         // Number of parameters
                ParameterTypeOIDs.Count * 4;

            buf.WriteByte(Code);
            buf.WriteInt32(messageLength - 1);
            buf.WriteNullTerminatedString(Statement);

            await buf.WriteString(Query, queryByteLen, async, cancellationToken);

            if (buf.WriteSpaceLeft < 1 + 2)
            {
                await buf.Flush(async, cancellationToken);
            }
            buf.WriteByte(0); // Null terminator for the query
            buf.WriteInt16((short)ParameterTypeOIDs.Count);

            foreach (var t in ParameterTypeOIDs)
            {
                if (buf.WriteSpaceLeft < 4)
                {
                    await buf.Flush(async, cancellationToken);
                }
                buf.WriteInt32((int)t);
            }
        }
Пример #12
0
        internal override async Task Write(WriteBuffer buf, bool async, CancellationToken cancellationToken)
        {
            if (buf.WriteSpaceLeft < 1 + 4)
            {
                await buf.Flush(async, cancellationToken);
            }
            var queryByteLen = _encoding.GetByteCount(_query);

            buf.WriteByte(Code);
            buf.WriteInt32(4 +            // Message length (including self excluding code)
                           queryByteLen + // Query byte length
                           1);            // Null terminator

            await buf.WriteString(_query, queryByteLen, async, cancellationToken);

            if (buf.WriteSpaceLeft < 1)
            {
                await buf.Flush(async, cancellationToken);
            }
            buf.WriteByte(0);
        }
Пример #13
0
        private void BindClasses(ListSet <Timeline> unboundClasses)
        {
            if (unboundClasses.Count > 0)
            {
                WriteBuffer symbolBuf = this.OpenTag(Tag.SymbolClass);

                symbolBuf.WriteUI16((uint)unboundClasses.Count);

                foreach (Timeline t in unboundClasses)
                {
                    symbolBuf.WriteUI16((uint)this.characterMarshal.GetIDFor((ICharacter)t));
                    symbolBuf.WriteString(t.Class.QualifiedName);
                    this.LogMessage(
                        "ID:" +
                        (uint)this.characterMarshal.GetIDFor((ICharacter)t) +
                        " => " +
                        t.Class.QualifiedName);
                }
                this.CloseTag();

                unboundClasses.Clear();
            }
        }
Пример #14
0
    internal async Task WriteQuery(string sql, bool async, CancellationToken cancellationToken = default)
    {
        var queryByteLen = TextEncoding.GetByteCount(sql);

        if (WriteBuffer.WriteSpaceLeft < 1 + 4)
        {
            await Flush(async, cancellationToken);
        }

        WriteBuffer.WriteByte(FrontendMessageCode.Query);
        WriteBuffer.WriteInt32(
            sizeof(int) +         // Message length (including self excluding code)
            queryByteLen +        // Query byte length
            sizeof(byte));        // Null terminator

        await WriteBuffer.WriteString(sql, queryByteLen, async, cancellationToken);

        if (WriteBuffer.WriteSpaceLeft < 1)
        {
            await Flush(async, cancellationToken);
        }
        WriteBuffer.WriteByte(0);  // Null terminator
    }
Пример #15
0
        private void WritePlaceObjectTag(PlaceObject po)
        {
            Tag         placeTag  = this.TagForPlaceObject(po);
            WriteBuffer tagWriter = this.OpenTag(placeTag);
            int         cid;

            switch (placeTag)
            {
            case Tag.PlaceObject:
                if (!po.HasCharacter)
                {
                    throw new SWFModellerException(
                              SWFModellerError.Internal,
                              "A PlaceObject display list item must have a character unless it is a move instruction.");
                }
#if DEBUG
                if (!this.characterMarshal.HasMarshalled(po.Character))
                {
                    throw new SWFModellerException(
                              SWFModellerError.Internal,
                              "Can't place object that hasn't been written to stream yet.");
                }
#endif
                cid = this.characterMarshal.GetIDFor(po.Character);
                tagWriter.WriteUI16((uint)cid);
#if DEBUG
                this.LogMessage("po cid =" + cid);
#endif
                tagWriter.WriteUI16((uint)po.LayerIndex);
                if (!po.HasMatrix)
                {
                    throw new SWFModellerException(
                              SWFModellerError.Internal,
                              "A PlaceObject display list item must have a Matrix, unless it's a PlaceObject2 tag. See spec for info, I can't work it out.");
                }
                tagWriter.WriteMatrix(po.Matrix);
                if (po.HasColorTransform)
                {
                    tagWriter.WriteColorTransform(po.CXForm, false);
                }
                break;


            case Tag.PlaceObject2:
                tagWriter.WriteBit(po.HasClipActions);
                tagWriter.WriteBit(po.HasClipDepth);
                tagWriter.WriteBit(po.HasName);
                tagWriter.WriteBit(po.HasRatio);
                tagWriter.WriteBit(po.HasColorTransform);
                tagWriter.WriteBit(po.HasMatrix);
                tagWriter.WriteBit(po.HasCharacter);
                tagWriter.WriteBit(po.IsMove);
                tagWriter.WriteUI16((uint)po.LayerIndex);

                if (po.HasCharacter)
                {
#if DEBUG
                    if (!this.characterMarshal.HasMarshalled(po.Character))
                    {
                        throw new SWFModellerException(
                                  SWFModellerError.Internal,
                                  "Can't place object that hasn't been written to stream yet.");
                    }
#endif
                    cid = this.characterMarshal.GetIDFor(po.Character);
                    tagWriter.WriteUI16((uint)cid);
#if DEBUG
                    this.LogMessage("po cid =" + cid);
#endif
                }

                if (po.HasMatrix)
                {
                    tagWriter.WriteMatrix(po.Matrix);
                }

                if (po.HasColorTransform)
                {
                    tagWriter.WriteColorTransform(po.CXForm, true);
                }

                if (po.HasRatio)
                {
                    tagWriter.WriteUI16((uint)po.Ratio);
                }

                if (po.HasName)
                {
#if DEBUG
                    this.LogMessage("name=" + po.Name);
#endif
                    tagWriter.WriteString(po.Name);
                }

                if (po.HasClipDepth)
                {
                    tagWriter.WriteUI16((uint)po.ClipDepth);
                }

                if (po.HasClipActions)
                {
                    throw new SWFModellerException(
                              SWFModellerError.Internal,
                              "Clips cannot have actions in the target SWF version.");
                }
                break;

            default:
                /* ISSUE 73 */
                throw new SWFModellerException(
                          SWFModellerError.UnimplementedFeature,
                          "Unsupported PlaceObject tag: " + placeTag.ToString());
            }

#if DEBUG
            this.LogMessage("po char =" + po.Character);
#endif

            this.CloseTag();
        }
Пример #16
0
 internal override void WriteFully(WriteBuffer buf)
 {
     buf.WriteByte(Code);
     buf.WriteInt32(Length - 1);
     buf.WriteString(_messageStr);
 }
Пример #17
0
        public override bool Write(ref DirectBuffer directBuf)
        {
            if (_stack == null)
            {
                if (_writeBuf.WriteSpaceLeft < 4)
                {
                    return(false);
                }
                _writeBuf.WriteInt32(_numTokens);

                if (_numTokens == 0)
                {
                    _writeBuf = null;
                    _value    = null;
                    return(true);
                }
                _stack = new Stack <NpgsqlTsQuery>();
                _stack.Push(_value);
            }

            while (_stack.Count > 0)
            {
                if (_writeBuf.WriteSpaceLeft < 2)
                {
                    return(false);
                }

                if (_stack.Peek().Kind == NpgsqlTsQuery.NodeKind.Lexeme && _writeBuf.WriteSpaceLeft < MaxSingleTokenBytes)
                {
                    return(false);
                }

                var node = _stack.Pop();
                _writeBuf.WriteByte(node.Kind == NpgsqlTsQuery.NodeKind.Lexeme ? (byte)1 : (byte)2);
                if (node.Kind != NpgsqlTsQuery.NodeKind.Lexeme)
                {
                    _writeBuf.WriteByte((byte)node.Kind);
                    if (node.Kind == NpgsqlTsQuery.NodeKind.Not)
                    {
                        _stack.Push(((NpgsqlTsQueryNot)node).Child);
                    }
                    else
                    {
                        _stack.Push(((NpgsqlTsQueryBinOp)node).Right);
                        _stack.Push(((NpgsqlTsQueryBinOp)node).Left);
                    }
                }
                else
                {
                    var lexemeNode = (NpgsqlTsQueryLexeme)node;
                    _writeBuf.WriteByte((byte)lexemeNode.Weights);
                    _writeBuf.WriteByte(lexemeNode.IsPrefixSearch ? (byte)1 : (byte)0);
                    _writeBuf.WriteString(lexemeNode.Text);
                    _writeBuf.WriteByte(0);
                }
            }

            _writeBuf = null;
            _value    = null;
            _stack    = null;
            return(true);
        }
Пример #18
0
        internal override bool Write(WriteBuffer buf)
        {
            Contract.Requires(Statement != null);

            switch (_state)
            {
                case State.WroteNothing:
                    _statementNameBytes = Statement.Length == 0 ? PGUtil.EmptyBuffer : _encoding.GetBytes(Statement);
                    _queryLen = _encoding.GetByteCount(Query);
                    if (buf.WriteSpaceLeft < 1 + 4 + _statementNameBytes.Length + 1) {
                        return false;
                    }

                    var messageLength =
                        1 +                         // Message code
                        4 +                         // Length
                        _statementNameBytes.Length +
                        1 +                         // Null terminator
                        _queryLen +
                        1 +                         // Null terminator
                        2 +                         // Number of parameters
                        ParameterTypeOIDs.Count * 4;

                    buf.WriteByte(Code);
                    buf.WriteInt32(messageLength - 1);
                    buf.WriteBytesNullTerminated(_statementNameBytes);
                    goto case State.WroteHeader;

                case State.WroteHeader:
                    _state = State.WroteHeader;

                    if (_queryLen <= buf.WriteSpaceLeft) {
                        buf.WriteString(Query);
                        goto case State.WroteQuery;
                    }

                    if (_queryLen <= buf.Size) {
                        // String can fit entirely in an empty buffer. Flush and retry rather than
                        // going into the partial writing flow below (which requires ToCharArray())
                        return false;
                    }

                    _queryChars = Query.ToCharArray();
                    _charPos = 0;
                    goto case State.WritingQuery;

                case State.WritingQuery:
                    _state = State.WritingQuery;
                    int charsUsed;
                    bool completed;
                    buf.WriteStringChunked(_queryChars, _charPos, _queryChars.Length - _charPos, true,
                                           out charsUsed, out completed);
                    if (!completed)
                    {
                        _charPos += charsUsed;
                        return false;
                    }
                    goto case State.WroteQuery;

                case State.WroteQuery:
                    _state = State.WroteQuery;
                    if (buf.WriteSpaceLeft < 1 + 2) {
                        return false;
                    }
                    buf.WriteByte(0); // Null terminator for the query
                    buf.WriteInt16((short)ParameterTypeOIDs.Count);
                    goto case State.WritingParameterTypes;

                case State.WritingParameterTypes:
                    _state = State.WritingParameterTypes;
                    for (; _parameterTypePos < ParameterTypeOIDs.Count; _parameterTypePos++)
                    {
                        if (buf.WriteSpaceLeft < 4)
                        {
                            return false;
                        }
                        buf.WriteInt32((int)ParameterTypeOIDs[_parameterTypePos]);
                    }

                    _state = State.WroteAll;
                    return true;

                default:
                    throw PGUtil.ThrowIfReached();
            }
        }
Пример #19
0
        internal override bool Write(WriteBuffer buf)
        {
            Contract.Requires(Statement != null);

            switch (_state)
            {
            case State.WroteNothing:
                _statementNameBytes = Statement.Length == 0 ? PGUtil.EmptyBuffer : _encoding.GetBytes(Statement);
                _queryLen           = _encoding.GetByteCount(Query);
                if (buf.WriteSpaceLeft < 1 + 4 + _statementNameBytes.Length + 1)
                {
                    return(false);
                }

                var messageLength =
                    1 +                             // Message code
                    4 +                             // Length
                    _statementNameBytes.Length +
                    1 +                             // Null terminator
                    _queryLen +
                    1 +                             // Null terminator
                    2 +                             // Number of parameters
                    ParameterTypeOIDs.Count * 4;

                buf.WriteByte(Code);
                buf.WriteInt32(messageLength - 1);
                buf.WriteBytesNullTerminated(_statementNameBytes);
                goto case State.WroteHeader;

            case State.WroteHeader:
                _state = State.WroteHeader;

                if (_queryLen <= buf.WriteSpaceLeft)
                {
                    buf.WriteString(Query);
                    goto case State.WroteQuery;
                }

                if (_queryLen <= buf.Size)
                {
                    // String can fit entirely in an empty buffer. Flush and retry rather than
                    // going into the partial writing flow below (which requires ToCharArray())
                    return(false);
                }

                _queryChars = Query.ToCharArray();
                _charPos    = 0;
                goto case State.WritingQuery;

            case State.WritingQuery:
                _state = State.WritingQuery;
                int  charsUsed;
                bool completed;
                buf.WriteStringChunked(_queryChars, _charPos, _queryChars.Length - _charPos, true,
                                       out charsUsed, out completed);
                if (!completed)
                {
                    _charPos += charsUsed;
                    return(false);
                }
                goto case State.WroteQuery;

            case State.WroteQuery:
                _state = State.WroteQuery;
                if (buf.WriteSpaceLeft < 1 + 2)
                {
                    return(false);
                }
                buf.WriteByte(0);     // Null terminator for the query
                buf.WriteInt16((short)ParameterTypeOIDs.Count);
                goto case State.WritingParameterTypes;

            case State.WritingParameterTypes:
                _state = State.WritingParameterTypes;
                for (; _parameterTypePos < ParameterTypeOIDs.Count; _parameterTypePos++)
                {
                    if (buf.WriteSpaceLeft < 4)
                    {
                        return(false);
                    }
                    buf.WriteInt32((int)ParameterTypeOIDs[_parameterTypePos]);
                }

                _state = State.WroteAll;
                return(true);

            default:
                throw PGUtil.ThrowIfReached();
            }
        }
Пример #20
0
        /// <summary>
        /// Does the grunt-work of writing all the objects in the SWF file, tagging
        /// each of them with a record header.
        /// </summary>
        private void WriteTags()
        {
            /* Start with a file attributes tag */
            this.WriteFileAttributesTag();
            /* Despite background color being specified in the header, flash always puts this in too. */
            this.WriteBGColorTag();

            if (swf.ProtectHash != null)
            {
                /* ISSUE 45: This should be an option of some kind. */
                WriteBuffer protectTag = this.OpenTag(Tag.Protect);
                protectTag.WriteUI16(0); /* Reserved, always 0 */
                protectTag.WriteString(swf.ProtectHash);
                this.CloseTag();
            }

            if (this.options.EnableDebugger)
            {
                WriteBuffer dbugTag = this.OpenTag(Tag.EnableDebugger2);
                dbugTag.WriteUI16(0);                                /* Reserved, always 0 */
                dbugTag.WriteString("$1$ZH$B14iwyCzzcXcqLaJz0Mif0"); /* MD5-encoded password "abc"; http://devadraco.blogspot.com/2009/06/guide-to-cracking-enabledebugger2.html */
                this.CloseTag();
            }

            /* ISSUE 46: Write DefineSceneAndFrameLabelData tag */
            foreach (DoABC abc in this.swf.Scripts)
            {
                WriteBuffer abcOut = this.OpenTag(Tag.DoABC);

                abcOut.WriteUI32((uint)(abc.IsLazilyInitialized ? ABCValues.AbcFlagLazyInitialize : 0));
                abcOut.WriteString(abc.Name);

                AbcWriter abcWriter = new AbcWriter();
                abcWriter.AssembleIfNecessary(
                    abc,
                    this.options.EnableDebugger,
                    this.swf.Class == null ? null : this.swf.Class.QualifiedName,
                    this.abcWriteLog);

                abcOut.WriteBytes(abc.Bytecode);

                this.CloseTag();
            }

            ListSet <Timeline> writtenSymbolClasses = new ListSet <Timeline>();
            ListSet <Timeline> unboundClasses       = new ListSet <Timeline>();

            foreach (Sprite exported in this.swf.ExportOnFirstFrame)
            {
                this.WriteSprite(exported, unboundClasses);
            }

            this.BindClasses(unboundClasses);

            if (this.swf.FrameCount > 0)
            {
                int writtenFrames = 0;

                if (this.swf.HasClass)
                {
                    WriteBuffer scbuf = this.OpenTag(Tag.SymbolClass);
                    scbuf.WriteUI16(1);                              /* Count */
                    scbuf.WriteUI16(0);                              /* Character ref */
                    scbuf.WriteString(this.swf.Class.QualifiedName); /* Name */
                    this.LogMessage(this.swf.Class.QualifiedName);
                    this.CloseTag();
                }

                foreach (Frame f in this.swf.Frames)
                {
                    if (f.HasLabel)
                    {
#if DEBUG
                        this.LogMessage("frame label=" + f.Label);
#endif
                        WriteBuffer labelWriter = this.OpenTag(Tag.FrameLabel);
                        labelWriter.WriteString(f.Label);
                        this.CloseTag();
                    }

                    foreach (IDisplayListItem dli in f.DisplayList)
                    {
                        switch (dli.Type)
                        {
                        case DisplayListItemType.PlaceObjectX:
                            this.WriteCharacter(((ICharacterReference)dli).Character, unboundClasses);
                            this.WritePlaceObjectTag((PlaceObject)dli);
                            break;

                        case DisplayListItemType.RemoveObjectX:
                        default:
                            this.WriteRemoveObjectTag((RemoveObject)dli);
                            break;
                        }
                    }

                    this.BindClasses(unboundClasses);

                    this.WriteBodylessTag(Tag.ShowFrame);

                    writtenFrames++;

                    List <SymbolClass> symbolClasses = new List <SymbolClass>();
                }
            }
            else
            {
                /* No SWF should be frameless. Awwww. */
                this.WriteBodylessTag(Tag.ShowFrame);
            }

            /* Finish with an end tag */
            this.WriteBodylessTag(Tag.End);
        }
Пример #21
0
        public override bool Write(ref DirectBuffer directBuf)
        {
            if (_charPos == -1)
            {
                if (_byteLen <= _writeBuf.WriteSpaceLeft)
                {
                    // Can simply write the string to the buffer
                    if (_str != null)
                    {
                        _writeBuf.WriteString(_str, _charLen);
                        _str = null;
                    }
                    else
                    {
                        Contract.Assert(_chars != null);
                        _writeBuf.WriteChars(_chars, _charLen);
                        _str = null;
                    }
                    _writeBuf = null;
                    return(true);
                }

                if (_byteLen <= _writeBuf.UsableSize)
                {
                    // Buffer is currently too full, but the string can fit. Force a write to fill.
                    return(false);
                }

                // Bad case: the string doesn't fit in our buffer.
                _charPos = 0;

                // For strings, chunked/incremental conversion isn't supported
                // (see https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/6584398-add-system-text-encoder-convert-method-string-in)
                // So for now allocate a temporary byte buffer to hold the entire string and write it directly.
                if (_str != null)
                {
                    directBuf.Buffer = new byte[_byteLen];
                    _writeBuf.TextEncoding.GetBytes(_str, 0, _charLen, directBuf.Buffer, 0);
                    return(false);
                }
                Contract.Assert(_chars != null);

                // For char arrays, fall through to chunked writing below
            }

            if (_str != null)
            {
                // We did a direct buffer write above, and must now clean up
                _str      = null;
                _writeBuf = null;
                return(true);
            }

            int  charsUsed;
            bool completed;

            _writeBuf.WriteStringChunked(_chars, _charPos, _chars.Length - _charPos, false, out charsUsed, out completed);
            if (completed)
            {
                // Flush encoder
                _writeBuf.WriteStringChunked(_chars, _charPos, _chars.Length - _charPos, true, out charsUsed, out completed);
                _chars    = null;
                _writeBuf = null;
                return(true);
            }
            _charPos += charsUsed;
            return(false);
        }
Пример #22
0
        private void WriteFont(SWFFont font, int fid)
        {
            WriteBuffer fontTag = this.OpenTag(Tag.DefineFont3, font.Name + "; id=" + fid);

            char[] codes = font.CodePoints;

            /* Tag.DefineFont3 */
            {
                fontTag.WriteUI16((uint)fid);

                fontTag.WriteBit(font.HasLayout);

                fontTag.WriteBit(false); /* ISSUE 50: ShiftJIS support */
                fontTag.WriteBit(font.IsSmall);
                fontTag.WriteBit(false); /* ISSUE 51: ANSI support, though I think this might never be false. */

                fontTag.WriteBit(true);  /* ISSUE 52: We always write wide offsets. This is because we're too lazy to measure our table. */
                fontTag.WriteBit(true);  /* Spec says must be true. */

                fontTag.WriteBit(font.IsItalic);
                fontTag.WriteBit(font.IsBold);

                fontTag.WriteUI8((uint)font.LanguageCode);

                fontTag.WriteString(font.Name, true);

                fontTag.WriteUI16((uint)font.GlyphCount);

                byte[][] shapeData       = new byte[font.GlyphCount][];
                int      totalShapeBytes = 0;
                for (int i = 0; i < font.GlyphCount; i++)
                {
                    Tag format;
                    shapeData[i] = ShapeWriter.ShapeToBytes(font.GetGlyphShape(codes[i]), out format);

                    if (format != Tag.DefineFont3)
                    {
                        throw new SWFModellerException(SWFModellerError.Internal, "Can't write non-font shapes as glyphs");
                    }

                    totalShapeBytes += shapeData[i].Length;
                }

                int startOffset = font.GlyphCount * 4 + 4; /* 4 bytes per offset (wide offsets) + 4 for the code table offset */
                int nextOffset  = startOffset;
                foreach (byte[] shapeBytes in shapeData)
                {
                    fontTag.WriteUI32((uint)nextOffset);
                    nextOffset += shapeBytes.Length;
                }

                fontTag.WriteUI32((uint)(startOffset + totalShapeBytes));

                foreach (byte[] shapeBytes in shapeData)
                {
                    fontTag.WriteBytes(shapeBytes);
                }

                foreach (char code in codes)
                {
                    fontTag.WriteUI16((uint)code);
                }

                if (font.HasLayout)
                {
                    fontTag.WriteSI16(font.Ascent.Value);
                    fontTag.WriteSI16(font.Descent.Value);
                    fontTag.WriteSI16(font.Leading.Value);

                    Rect[] bounds    = new Rect[font.GlyphCount];
                    int    boundsPos = 0;
                    foreach (char c in codes)
                    {
                        GlyphLayout gl = font.GetLayout(c);
                        fontTag.WriteSI16(gl.Advance);
                        bounds[boundsPos++] = gl.Bounds;
                    }

                    foreach (Rect bound in bounds)
                    {
                        fontTag.WriteRect(bound);
                        fontTag.Align8();
                    }

                    fontTag.WriteUI16((uint)font.KerningTable.Length);
                    foreach (KerningPair kern in font.KerningTable)
                    {
                        fontTag.WriteUI16(kern.LeftChar);
                        fontTag.WriteUI16(kern.RightChar);
                        fontTag.WriteSI16(kern.Adjustment);
                    }
                }
            }

            this.CloseTag();

            if (font.HasPixelAlignment)
            {
                WriteBuffer zonesTag = this.OpenTag(Tag.DefineFontAlignZones, font.Name + "; id=" + fid);

                zonesTag.WriteUI16((uint)fid);

                if (font.ThicknessHint == null)
                {
                    throw new SWFModellerException(SWFModellerError.Internal, "Can't have pixel aligmnent without a font thickness hint.");
                }

                zonesTag.WriteUBits((uint)font.ThicknessHint, 2);
                zonesTag.WriteUBits(0, 6); /* Reserved */

                foreach (char c in codes)
                {
                    PixelAlignment pa = font.GetPixelAligment(c);

                    if (pa.ZoneInfo.Length != 2)
                    {
                        throw new SWFModellerException(SWFModellerError.Internal, "Pixel aligment should always have 2 zones.");
                    }

                    zonesTag.WriteUI8((uint)pa.ZoneInfo.Length);

                    foreach (PixelAlignment.ZoneData zi in pa.ZoneInfo)
                    {
                        /* These int values are just unparsed 16-bit floats. */
                        zonesTag.WriteUI16((uint)zi.AlignmentCoord);
                        zonesTag.WriteUI16((uint)zi.Range);
                    }

                    zonesTag.WriteUBits(0, 6); /* Reserved */
                    zonesTag.WriteBit(pa.HasY);
                    zonesTag.WriteBit(pa.HasX);
                }

                this.CloseTag();
            }

            if (font.HasExtraNameInfo)
            {
                WriteBuffer nameTag = this.OpenTag(Tag.DefineFontName, font.FullName + "; id=" + fid);

                nameTag.WriteUI16((uint)fid);
                nameTag.WriteString(font.FullName);
                nameTag.WriteString(font.Copyright);

                this.CloseTag();
            }
        }
Пример #23
0
        /// <param name="fontID">Pass -1 if this has no font.</param>
        private void WriteEditText(EditText text, int fontID)
        {
            int cid = characterMarshal.GetIDFor(text);

            WriteBuffer textTag = this.OpenTag(Tag.DefineEditText, "; id=" + cid);

            /* Tag.DefineEditText */
            {
                textTag.WriteUI16((uint)cid);

                textTag.WriteRect(text.Bounds);
                textTag.Align8();

                textTag.WriteBit(text.HasText);
                textTag.WriteBit(text.WordWrapEnabled);
                textTag.WriteBit(text.IsMultiline);
                textTag.WriteBit(text.IsPassword);
                textTag.WriteBit(text.IsReadOnly);
                textTag.WriteBit(text.HasTextColor);
                textTag.WriteBit(text.HasMaxLength);
                textTag.WriteBit(text.HasFont);
                textTag.WriteBit(text.HasFontClass);
                textTag.WriteBit(text.IsAutoSized);
                textTag.WriteBit(text.HasLayout);
                textTag.WriteBit(text.IsNonSelectable);
                textTag.WriteBit(text.HasBorder);
                textTag.WriteBit(text.IsStatic);
                textTag.WriteBit(text.IsHTML);
                textTag.WriteBit(text.UseOutlines);

                if (text.HasFont)
                {
                    textTag.WriteUI16((uint)fontID);
                }

                if (text.HasFontClass)
                {
                    /* ISSUE 14 */
                    throw new SWFModellerException(SWFModellerError.UnimplementedFeature, "Font classes can't be written.");
                }

                if (text.HasFont)
                {
                    textTag.WriteUI16((uint)text.FontHeight);
                }

                if (text.HasTextColor)
                {
                    textTag.WriteRGBA(text.Color.ToArgb());
                }

                if (text.HasMaxLength)
                {
                    textTag.WriteUI16((uint)text.MaxLength.Value);
                }

                if (text.HasLayout)
                {
                    EditText.Layout layout = text.LayoutInfo;

                    textTag.WriteUI8((uint)layout.Align);
                    textTag.WriteUI16((uint)layout.LeftMargin);
                    textTag.WriteUI16((uint)layout.RightMargin);
                    textTag.WriteUI16((uint)layout.Indent);
                    textTag.WriteSI16(layout.Leading);
                }

                textTag.WriteString(text.VarName);

                if (text.HasText)
                {
                    textTag.WriteString(text.Text);
                }
            }

            CloseTag();
        }