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); }
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 */ }
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); }
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); } }
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); }
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); } } }
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(); }
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); }
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); } }
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); } }
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); } }
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); }
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(); } }
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 }
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(); }
internal override void WriteFully(WriteBuffer buf) { buf.WriteByte(Code); buf.WriteInt32(Length - 1); buf.WriteString(_messageStr); }
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); }
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(); } }
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(); } }
/// <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); }
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); }
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(); } }
/// <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(); }