public void Encode(RubyToken token, string file, RubyEncoderOptions options) { using (var stream = File.Open(file, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) { Encode(token, stream, options); } }
public void Encode(RubyToken token, Stream stream, RubyEncoderOptions options) { using (var writer = new BinaryWriter(stream)) { writer.Write((short)0x0804); WriteEntry(token, new WriteContext { Writer = writer }, options ?? new RubyEncoderOptions()); } }
private static LazyList <Token> ParseRubyText(IEnumerator <UChar> inputStream, UString rubyParent) { var text = new UStringBuilder(32); while (inputStream.MoveNext()) { var c = inputStream.Current; if (c == SpecialCharacters.RubyClose) { var token = new RubyToken(rubyParent, text.ToUString()); return(LazyList <Token> .New(token, () => ParseNormal(inputStream))); } else { text.Append(c); } } //WARNING: syntax-error // dispose incomplete ruby return(LazyList <Token> .New(new NormalToken(rubyParent))); }
internal static void WriteEntry(RubyToken token, WriteContext context, RubyEncoderOptions options) { switch (token.Type) { case RubyTokenType.Array: var rubyArray = (RubyArray)token; context.Data.Add(rubyArray); context.Writer.Write((byte)RubyType.Array); WriteNumber(rubyArray.Count, context); foreach (var item in rubyArray) { WriteEntry(item, context, options); } break; case RubyTokenType.Object: var rubyObject = (RubyObject)token; context.Data.Add(rubyObject); if (rubyObject.RubyClass.Name == "encoder:Hash") { context.Writer.Write((byte)RubyType.Hash); WriteNumber(rubyObject.Properties.Count, context); foreach (var property in rubyObject.Properties) { var rubyKey = long.TryParse(property.Key, out var numberKey) ? new RubyValue(numberKey) : new RubyValue(property.Key); WriteEntry(rubyKey, context, options); WriteEntry(property.Value, context, options); } } else if (options.UserEncoders.TryGetValue(rubyObject.RubyClass.Name, out var encoder)) { context.Writer.Write((byte)RubyType.UserDefined); WriteSymbolDefinition(rubyObject.RubyClass.Name, context); var bytes = encoder(rubyObject); WriteNumber(bytes.Length, context); context.Writer.Write(bytes, 0, bytes.Length); } else { context.Writer.Write((byte)RubyType.Object); WriteSymbolDefinition(rubyObject.RubyClass.Name, context); WriteNumber(rubyObject.Properties.Count, context); foreach (var property in rubyObject.Properties) { WriteSymbolDefinition("@" + property.Key, context); WriteEntry(property.Value, context, options); } } break; case RubyTokenType.Boolean: context.Writer.Write((byte)(token.GetValue <bool>() ? RubyType.True : RubyType.False)); break; case RubyTokenType.String: context.Writer.Write((byte)RubyType.String); WriteString(token.GetValue <string>(), context); break; case RubyTokenType.Bytes: context.Writer.Write((byte)RubyType.String); WriteBytes(token.GetValue <byte[]>(), context); break; case RubyTokenType.Number: context.Writer.Write((byte)RubyType.Number); WriteNumber(token.GetValue <long>(), context); break; case RubyTokenType.Float: context.Writer.Write((byte)RubyType.Decimal); context.Data.Add(token); WriteFloat(token.GetValue <double>(), context); break; case RubyTokenType.Null: context.Writer.Write((byte)RubyType.Nil); break; default: throw new InvalidOperationException($"Cannot write type of {token.Type}."); } }
public void Encode(RubyToken token, Stream stream) { Encode(token, stream, null); }
public void Encode(RubyToken token, string file) { Encode(token, file, null); }
private static LazyList<Token> ParseRubyText(IEnumerator<UChar> inputStream, UString rubyParent) { var text = new UStringBuilder(32); while (inputStream.MoveNext()) { var c = inputStream.Current; if (c == SpecialCharacters.RubyClose) { var token = new RubyToken(rubyParent, text.ToUString()); return LazyList<Token>.New(token, () => ParseNormal(inputStream)); } else { text.Append(c); } } //WARNING: syntax-error // dispose incomplete ruby return LazyList<Token>.New(new NormalToken(rubyParent)); }