private void AnchorNode(Node node) { while (node is LinkNode) { node = ((LinkNode)node).Linked; } if (!IgnoreAnchor(node)) { string anchor; if (_anchors.TryGetValue(node, out anchor)) { if (null == anchor) { _anchors[node] = GenerateAnchor(node); } } else { _anchors.Add(node, null); SequenceNode seq; MappingNode map; if ((seq = node as SequenceNode) != null) { foreach (Node n in seq.Nodes) { AnchorNode(n); } } else if ((map = node as MappingNode) != null) { foreach (KeyValuePair<Node, Node> e in map.Nodes) { AnchorNode(e.Key); AnchorNode(e.Value); } } } } }
private void AddAnchor(string anchor, Node node) { if (_anchors.ContainsKey(anchor)) { _anchors[anchor] = node; } else { _anchors.Add(anchor, node); } }
public static object ConstructYamlBool(IConstructor ctor, Node node) { bool result; if (TryConstructYamlBool(ctor, node, out result)) { return result; } return null; }
public void Serialize(Node node) { if (_closed) { throw new SerializerException("serializer is closed"); } _emitter.Emit(new DocumentStartEvent(_useExplicitStart, _useVersion, null)); AnchorNode(node); SerializeNode(node, null, null); _emitter.Emit(_useExplicitEnd ? DocumentEndEvent.ExplicitInstance : DocumentEndEvent.ImplicitInstance); _serializedNodes.Clear(); _anchors.Clear(); _lastAnchorId = 0; }
public object Construct(BaseConstructor ctor, string tag, Node node) { object result; _block.Yield(MutableString.Create(tag, RubyEncoding.UTF8), ctor.ConstructPrimitive(node), out result); return result; }
public object Construct(BaseConstructor ctor, Node node) { return Construct(ctor, node.Tag, node); }
public static object ConstructYamlTimestamp(IConstructor ctor, Node node) { ScalarNode scalar = node as ScalarNode; if (scalar == null) { throw new ConstructorException("can only contruct timestamp from scalar node"); } Match match = TIMESTAMP_REGEXP.Match(scalar.Value); if (!match.Success) { return ctor.ConstructPrivateType(node); } string year_s = match.Groups[1].Value; string month_s = match.Groups[2].Value; string day_s = match.Groups[3].Value; string hour_s = match.Groups[4].Value; string min_s = match.Groups[5].Value; string sec_s = match.Groups[6].Value; string fract_s = match.Groups[7].Value; string utc = match.Groups[8].Value; string timezoneh_s = match.Groups[9].Value; string timezonem_s = match.Groups[10].Value; bool isUtc = utc == "Z" || utc == "z"; DateTime dt = new DateTime( year_s != "" ? int.Parse(year_s) : 0, month_s != "" ? int.Parse(month_s) : 1, day_s != "" ? int.Parse(day_s) : 1, hour_s != "" ? int.Parse(hour_s) : 0, min_s != "" ? int.Parse(min_s) : 0, sec_s != "" ? int.Parse(sec_s) : 0, isUtc? DateTimeKind.Utc : DateTimeKind.Local ); if (!string.IsNullOrEmpty(fract_s)) { long fract = int.Parse(fract_s); if (fract > 0) { while (fract < 1000000) { fract *= 10; } dt = dt.AddTicks(fract); } } if (!isUtc) { if (timezoneh_s != "" || timezonem_s != "") { int zone = 0; int sign = +1; if (timezoneh_s != "") { if (timezoneh_s.StartsWith("-")) { sign = -1; } zone += int.Parse(timezoneh_s.Substring(1)) * 3600000; } if (timezonem_s != "") { zone += int.Parse(timezonem_s) * 60000; } double utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(dt).TotalMilliseconds; dt = dt.AddMilliseconds(utcOffset - sign * zone); } } return dt; }
private static object ConstructRubyStruct(RubyConstructor/*!*/ ctor, string/*!*/ structName, Node/*!*/ node) { MappingNode mapping = node as MappingNode; if (mapping == null) { throw new ConstructorException("can only construct struct from mapping node"); } if (structName.Length == 0) { // TODO: throw new NotSupportedException("anonymous structs not supported"); } RubyContext context = ctor.GlobalScope.Context; RubyModule module; // TODO: MRI calls "members" on an arbitrary object // MRI checks Struct first, then falls back to Object if (!context.TryGetModule(ctor.GlobalScope, "Struct::" + structName, out module) && !context.TryGetModule(ctor.GlobalScope, structName, out module)) { throw RubyExceptions.CreateTypeError("Undefined struct `{0}'", structName); } RubyClass cls = module as RubyClass; if (cls == null) { throw RubyExceptions.CreateTypeError("`{0}' is not a class", structName); } RubyStruct newStruct = RubyStruct.Create(cls); foreach (var pair in ctor.ConstructMapping(mapping)) { var attributeName = pair.Key as MutableString; int index; // TODO: encoding if (attributeName != null && newStruct.TryGetIndex(attributeName.ToString(), out index)) { newStruct[index] = pair.Value; } } return newStruct; }
public static object ConstructYamlFloat(IConstructor ctor, Node node) { string value = ctor.ConstructScalar(node).ToString().Replace("_", "").Replace(",", ""); int sign = +1; char first = value[0]; if (first == '-') { sign = -1; value = value.Substring(1); } else if (first == '+') { value = value.Substring(1); } string valLower = value.ToLower(); if (valLower == ".inf") { return sign == -1 ? double.NegativeInfinity : double.PositiveInfinity; } else if (valLower == ".nan") { return double.NaN; } else if (value.IndexOf(':') != -1) { string[] digits = value.Split(':'); int bes = 1; double val = 0.0; for (int i = 0, j = digits.Length; i < j; i++) { val += (double.Parse(digits[(j - i) - 1]) * bes); bes *= 60; } return sign * val; } else { return sign * double.Parse(value); } }
protected virtual bool IgnoreAnchor(Node node) { // This is possibly Ruby specific. // but it didn't seem worth subclassing Serializer for this one method return !(node is CollectionNode); //return false; }
private static object ConstructRubyStruct(RubyConstructor/*!*/ ctor, string className, Node node) { MappingNode mapping = node as MappingNode; if (mapping == null) { throw new ConstructorException("can only construct struct from mapping node"); } RubyContext context = ctor.GlobalScope.Context; RubyModule module; RubyClass cls; if (context.TryGetModule(ctor.GlobalScope, className, out module)) { cls = module as RubyClass; if (cls == null) { throw new ConstructorException("Struct type name must be Ruby class"); } } else { RubyModule structModule = context.GetModule(typeof(RubyStruct)); cls = RubyUtils.GetConstant(ctor.GlobalScope, structModule, className, false) as RubyClass; if (cls == null) { throw new ConstructorException(String.Format("Cannot find struct class \"{0}\"", className)); } } RubyStruct newStruct = RubyStruct.Create(cls); foreach (var pair in ctor.ConstructMapping(mapping)) { RubyStructOps.SetValue(newStruct, SymbolTable.StringToId(pair.Key.ToString()), pair.Value); } return newStruct; }
private static RubyRegex ConstructRubyRegexp(RubyConstructor/*!*/ ctor, Node node) { ScalarNode scalar = node as ScalarNode; if (node == null) { throw RubyExceptions.CreateTypeError("Can only create regex from scalar node"); } Match match = _regexPattern.Match(scalar.Value); if (!match.Success) { throw new ConstructorException("Invalid Regular expression: \"" + scalar.Value + "\""); } RubyRegexOptions options = new RubyRegexOptions(); foreach (char c in match.Groups["opts"].Value) { switch (c) { case 'i': options |= RubyRegexOptions.IgnoreCase; break; case 'x': options |= RubyRegexOptions.Extended; break; case 'm': options |= RubyRegexOptions.Multiline; break; case 'o': break; case 'n': options |= RubyRegexOptions.FIXED; break; case 'e': options |= RubyRegexOptions.EUC; break; case 's': options |= RubyRegexOptions.SJIS; break; case 'u': options |= RubyRegexOptions.UTF8; break; default: throw new ConstructorException("Unknown regular expression option: '" + c + "'"); } } // TODO: encoding (ignore kcode on 1.9, string enc?): return new RubyRegex(MutableString.CreateMutable(match.Groups["expr"].Value, RubyEncoding.UTF8), options); }
public static object ConstructCliObject(IConstructor ctor, string pref, Node node) { // TODO: should this use serialization or some more standard CLR mechanism? // (it is very ad-hoc) // TODO: use DLR APIs instead of reflection try { Type type = Type.GetType(pref); object result = type.GetConstructor(Type.EmptyTypes).Invoke(null); foreach (KeyValuePair<object, object> e in ctor.ConstructMapping(node)) { string name = e.Key.ToString(); name = "" + char.ToUpper(name[0]) + name.Substring(1); PropertyInfo prop = type.GetProperty(name); prop.SetValue(result, Convert.ChangeType(e.Value, prop.PropertyType), null); } return result; } catch (Exception e) { throw new ConstructorException("Can't construct a CLI object from class: " + pref, e); } }
public static object ConstructYamlNull(IConstructor ctor, Node node) { return null; }
public static object ConstructSpecializedMap(IConstructor ctor, string pref, Node node) { Hash result = null; try { result = (Hash)Type.GetType(pref).GetConstructor(Type.EmptyTypes).Invoke(null); } catch (Exception e) { throw new ConstructorException("Can't construct a mapping from class: " + pref, e); } foreach (KeyValuePair<object, object> e in ctor.ConstructMapping(node)) { result.Add(e.Key, e.Value); } return result; }
public static object ConstructSpecializedSequence(IConstructor ctor, string pref, Node node) { RubyArray result = null; try { result = (RubyArray)Type.GetType(pref).GetConstructor(Type.EmptyTypes).Invoke(null); } catch (Exception e) { throw new ConstructorException("Can't construct a sequence from class: " + pref, e); } foreach (object x in ctor.ConstructSequence(node)) { result.Add(x); } return result; }
public static byte[] ConstructYamlBinary(IConstructor ctor, Node node) { string val = ctor.ConstructScalar(node).ToString().Replace("\r", "").Replace("\n", ""); return Convert.FromBase64String(val); }
private static object ConstructRubyScalar(RubyConstructor/*!*/ ctor, Node node) { object value = ctor.ConstructScalar(node); if (value == null) { return value; } string str = value as string; if (str != null) { return MutableString.Create(str, RubyEncoding.UTF8); } return value; }
private static object ConstructRubyTimestampYMD(RubyConstructor/*!*/ ctor, Node node) { ScalarNode scalar = node as ScalarNode; if (scalar == null) { throw new ConstructorException("Can only contruct timestamp from scalar node."); } Match match = BaseConstructor.YmdRegex.Match(scalar.Value); if (match.Success) { int year_ymd = Int32.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture); int month_ymd = Int32.Parse(match.Groups[2].Value, CultureInfo.InvariantCulture); int day_ymd = Int32.Parse(match.Groups[3].Value, CultureInfo.InvariantCulture); RubyModule module; if (ctor.GlobalScope.Context.TryGetModule(ctor.GlobalScope, "Date", out module)) { return ctor._newSite.Target(ctor._newSite, module, year_ymd, month_ymd, day_ymd); } else { throw new ConstructorException("Date class not found."); } } throw new ConstructorException("Invalid tag:yaml.org,2002:timestamp#ymd value."); }
private static Range ConstructRubyRange(RubyConstructor/*!*/ ctor, Node node) { object begin = null; object end = null; bool excludeEnd = false; ScalarNode scalar = node as ScalarNode; if (scalar != null) { string value = scalar.Value; int dotsIdx; if ((dotsIdx = value.IndexOf("...")) != -1) { begin = ParseObject(ctor, value.Substring(0, dotsIdx)); end = ParseObject(ctor, value.Substring(dotsIdx + 3)); excludeEnd = true; } else if ((dotsIdx = value.IndexOf("..")) != -1) { begin = ParseObject(ctor, value.Substring(0, dotsIdx)); end = ParseObject(ctor, value.Substring(dotsIdx + 2)); } else { throw new ConstructorException("Invalid Range: " + value); } } else { MappingNode mapping = node as MappingNode; if (mapping == null) { throw new ConstructorException("Invalid Range: " + node); } foreach (KeyValuePair<Node, Node> n in mapping.Nodes) { string key = ctor.ConstructScalar(n.Key).ToString(); switch (key) { case "begin": begin = ctor.ConstructObject(n.Value); break; case "end": end = ctor.ConstructObject(n.Value); break; case "excl": TryConstructYamlBool(ctor, n.Value, out excludeEnd); break; default: throw new ConstructorException(string.Format("'{0}' is not allowed as an instance variable name for class Range", key)); } } } var comparisonStorage = new BinaryOpStorage(ctor.GlobalScope.Context); return new Range(comparisonStorage, ctor.GlobalScope.Context, begin, end, excludeEnd); }
private string GenerateAnchor(Node node) { return string.Format(_anchorTemplate, ++_lastAnchorId); }
private static object ConstructPrivateObject(RubyConstructor/*!*/ ctor, string className, Node node) { MappingNode mapping = node as MappingNode; if (mapping == null) { throw new ConstructorException("can only construct private type from mapping node"); } RubyModule module; RubyGlobalScope globalScope = ctor.GlobalScope; if (globalScope.Context.TryGetModule(globalScope, className, out module)) { if (!module.IsClass) { throw new ConstructorException("Cannot construct module"); } Hash values = ctor.ConstructMapping(mapping); RubyMethodInfo method = module.GetMethod("yaml_initialize") as RubyMethodInfo; if (method != null) { object result = RubyUtils.CreateObject((RubyClass)module); ctor._yamlInitializeSite.Target(ctor._yamlInitializeSite, result, className, values); return result; } else { return RubyUtils.CreateObject((RubyClass)module, values, true); } } else { //TODO: YAML::Object throw new NotImplementedError("YAML::Object is not implemented yet"); } }
public static object ConstructYamlInt(IConstructor ctor, Node node) { string value = ctor.ConstructScalar(node).ToString().Replace("_","").Replace(",",""); int sign = +1; char first = value[0]; if(first == '-') { sign = -1; value = value.Substring(1); } else if(first == '+') { value = value.Substring(1); } int @base = 10; if (value == "0") { return 0; } else if (value.StartsWith("0b")) { value = value.Substring(2); @base = 2; } else if (value.StartsWith("0x")) { value = value.Substring(2); @base = 16; } else if (value.StartsWith("0")) { value = value.Substring(1); @base = 8; } else if (value.IndexOf(':') != -1) { string[] digits = value.Split(':'); int bes = 1; int val = 0; for (int i = 0, j = digits.Length; i < j; i++) { val += (int.Parse(digits[(j - i) - 1]) * bes); bes *= 60; } return sign*val; } try { // LiteralParser.ParseInteger delegate handles parsing & conversion to BigInteger (if needed) return LiteralParser.ParseInteger(sign, value, @base); } catch (Exception e) { throw new ConstructorException(string.Format("Could not parse integer value: '{0}' (sign {1}, base {2})", value, sign, @base), e); } }
private static MutableString ConstructRubyBinary(RubyConstructor/*!*/ ctor, Node node) { return MutableString.CreateBinary(BaseConstructor.ConstructYamlBinary(ctor, node)); }
public static bool TryConstructYamlBool(IConstructor ctor, Node node, out bool result) { if (BOOL_VALUES.TryGetValue(ctor.ConstructScalar(node).ToString(), out result)) { return true; } return false; }
public static object Transform(RubyScope/*!*/ scope, Node/*!*/ self) { return new RubyConstructor(scope.GlobalScope, new SimpleNodeProvider(self)).GetData(); }
public static object ConstructYamlOmap(IConstructor ctor, Node node) { return ctor.ConstructPairs(node); }
private void SerializeNode(Node node, Node parent, object index) { while (node is LinkNode) { node = ((LinkNode)node).Linked; } string tAlias; _anchors.TryGetValue(node, out tAlias); if (_serializedNodes.ContainsKey(node) && tAlias != null) { _emitter.Emit(new AliasEvent(tAlias)); } else { _serializedNodes[node] = null; //_resolver.descendResolver(parent, index); ScalarNode scalar; SequenceNode seq; MappingNode map; if ((scalar = node as ScalarNode) != null) { string tag = node.Tag; ScalarQuotingStyle style = scalar.Style; ScalarValueType type; if (tag == null) { // quote an untagged sctring scalar that might be parsed as a different scalar type if not quoted: if (style == ScalarQuotingStyle.None && ResolverScanner.Recognize(scalar.Value) != null) { style = ScalarQuotingStyle.Double; } type = ScalarValueType.String; } else if (tag == Tags.Str) { // omit the tag for strings that are not recognizable as other scalars: if (ResolverScanner.Recognize(scalar.Value) == null) { tag = null; } type = ScalarValueType.String; } else if (scalar.Value == null) { tag = null; type = ScalarValueType.Other; } else { // omit the tag for non-string scalars whose type can be recognized from their value: string detectedTag = ResolverScanner.Recognize(scalar.Value); if (detectedTag != null && tag.StartsWith(detectedTag, StringComparison.Ordinal)) { tag = null; } type = ScalarValueType.Other; } _emitter.Emit(new ScalarEvent(tAlias, tag, type, scalar.Value, style)); } else if ((seq = node as SequenceNode) != null) { _emitter.Emit(new SequenceStartEvent(tAlias, node.Tag, seq.FlowStyle)); int ix = 0; foreach (Node n in seq.Nodes) { SerializeNode(n, node, ix++); } _emitter.Emit(SequenceEndEvent.Instance); } else if ((map = node as MappingNode) != null) { _emitter.Emit(new MappingStartEvent(tAlias, node.Tag, map.FlowStyle)); foreach (KeyValuePair<Node, Node> e in map.Nodes) { SerializeNode(e.Key, node, null); SerializeNode(e.Value, node, e.Key); } _emitter.Emit(MappingEndEvent.Instance); } } }
/// <summary> /// Returns MutableString or RubySymbol. /// </summary> private static object ConstructRubyString(RubyConstructor/*!*/ ctor, Node/*!*/ node) { ScalarNode scalar = (ScalarNode)node; string value = ctor.ConstructScalar(node); if (value == null) { return null; } if (value.Length > 1 && value[0] == ':' && scalar.Style == ScalarQuotingStyle.None) { return ctor.GlobalScope.Context.CreateAsciiSymbol(value.Substring(1)); } return MutableString.CreateMutable(value, ctor.RubyEncoding); }
private static object ConstructRubySymbol(RubyConstructor/*!*/ ctor, Node/*!*/ node) { return ctor.GlobalScope.Context.CreateAsciiSymbol(((ScalarNode)node).Value); }
public LinkNode(Node linked) : base(null) { _linked = linked; }