func formatObjectOneLine(v otto.Value, limit int, seen map[otto.Value]bool) (string, error) { if limit == 0 { return "...", nil } if seen[v] { return "[circular]", nil } o := v.Object() bits := []string{} keys := o.Keys() for _, k := range keys { e, err := o.Get(k) if err != nil { return "", err } d, err := formatOneLine(e, limit-1, seenWith(seen, v)) if err != nil { return "", err } bits = append(bits, k+": "+d) } return "{" + strings.Join(bits, ", ") + "}", nil }
func convertValToMysqlConnInfo(v *otto.Value) *MysqlConnInfo { connInfo := &MysqlConnInfo{} if v.IsDefined() && v.IsObject() { obj := v.Object() // get username if u, err := obj.Get("username"); err == nil && u.IsString() { connInfo.Username, _ = u.ToString() } // get password if p, err := obj.Get("password"); err == nil && p.IsString() { connInfo.Password, _ = p.ToString() } // get host if h, err := obj.Get("host"); err == nil && h.IsString() { connInfo.Host, _ = h.ToString() } // get port if p, err := obj.Get("port"); err == nil && p.IsNumber() { connInfo.Port, _ = p.ToInteger() } } return connInfo }
func formatOneLine(v otto.Value, limit int, seen map[otto.Value]bool) (string, error) { if limit == 0 { return "...", nil } switch { case v.IsBoolean(), v.IsNull(), v.IsNumber(), v.IsUndefined(): return v.String(), nil case v.IsString(): return fmt.Sprintf("%q", v.String()), nil case v.IsFunction(): n, err := v.Object().Get("name") if err != nil { return "", err } if n.IsUndefined() { return "function", nil } return fmt.Sprintf("function %s", n.String()), nil case v.IsObject(): switch v.Class() { case "Array": return formatArrayOneLine(v, limit, seen) default: return formatObjectOneLine(v, limit, seen) } default: return "", fmt.Errorf("couldn't format type %s", v.Class()) } }
func formatObject(v otto.Value, width, indent, limit, level int, seen map[otto.Value]bool) (string, error) { if seen[v] { return strings.Repeat(" ", level*indent) + "[circular]", nil } o := v.Object() bits := []string{"{"} keys := o.Keys() for i, k := range keys { e, err := o.Get(k) d, err := formatIndent(e, width, indent, limit-1, level+1, len(k)+2, seenWith(seen, v)) if err != nil { return "", err } bits = append(bits, strings.Repeat(" ", (level+1)*indent)+k+": "+d+",") i++ } bits = append(bits, strings.Repeat(" ", level*indent)+"}") return strings.Join(bits, "\n"), nil }
// Converts an Otto value to a Go value. Handles all JSON-compatible types. func ottoToGo(value otto.Value) (interface{}, error) { if value.IsBoolean() { return value.ToBoolean() } else if value.IsNull() || value.IsUndefined() { return nil, nil } else if value.IsNumber() { return value.ToFloat() } else if value.IsString() { return value.ToString() } else { switch value.Class() { case "Array": return ottoToGoArray(value.Object()) } } return nil, fmt.Errorf("Unsupported Otto value: %v", value) }
func buildIteratorFromValue(val otto.Value, ts graph.TripleStore) graph.Iterator { if val.IsNull() || val.IsUndefined() { return ts.GetNodesAllIterator() } if val.IsPrimitive() { thing, _ := val.Export() switch v := thing.(type) { case string: it := ts.MakeFixed() it.AddValue(ts.GetIdFor(v)) return it default: glog.Errorln("Trying to build unknown primitive value.") } } switch val.Class() { case "Object": return buildIteratorTree(val.Object(), ts) case "Array": // Had better be an array of strings strings := makeListOfStringsFromArrayValue(val.Object()) it := ts.MakeFixed() for _, x := range strings { it.AddValue(ts.GetIdFor(x)) } return it case "Number": fallthrough case "Boolean": fallthrough case "Date": fallthrough case "String": it := ts.MakeFixed() str, _ := val.ToString() it.AddValue(ts.GetIdFor(str)) return it default: glog.Errorln("Trying to handle unsupported Javascript value.") return graph.NewNullIterator() } }
func formatArrayOneLine(v otto.Value, limit int, seen map[otto.Value]bool) (string, error) { if limit == 0 { return "...", nil } if seen[v] { return "[circular]", nil } o := v.Object() lv, err := o.Get("length") if err != nil { return "", err } li, err := lv.Export() if err != nil { return "", err } l, ok := li.(uint32) if !ok { return "", fmt.Errorf("length property must be a number; was %T", li) } var bits []string for i := 0; i < int(l); i++ { e, err := o.Get(fmt.Sprintf("%d", i)) if err != nil { return "", err } d, err := formatOneLine(e, limit-1, seenWith(seen, v)) if err != nil { return "", err } bits = append(bits, d) } return "[" + strings.Join(bits, ", ") + "]", nil }
func buildIteratorFromValue(val otto.Value, qs graph.QuadStore) graph.Iterator { if val.IsNull() || val.IsUndefined() { return qs.NodesAllIterator() } if val.IsPrimitive() { thing, _ := val.Export() switch v := thing.(type) { case string: it := qs.FixedIterator() it.Add(qs.ValueOf(v)) return it default: glog.Errorln("Trying to build unknown primitive value.") } } switch val.Class() { case "Object": return buildIteratorTree(val.Object(), qs) case "Array": // Had better be an array of strings strings := stringsFrom(val.Object()) it := qs.FixedIterator() for _, x := range strings { it.Add(qs.ValueOf(x)) } return it case "Number": fallthrough case "Boolean": fallthrough case "Date": fallthrough case "String": it := qs.FixedIterator() it.Add(qs.ValueOf(val.String())) return it default: glog.Errorln("Trying to handle unsupported Javascript value.") return iterator.NewNull() } }
func formatArray(v otto.Value, width, indent, limit, level int, seen map[otto.Value]bool) (string, error) { if seen[v] { return strings.Repeat(" ", level*indent) + "[circular]", nil } o := v.Object() lv, err := o.Get("length") if err != nil { return "", err } li, err := lv.Export() if err != nil { return "", err } l, ok := li.(uint32) if !ok { return "", fmt.Errorf("length property must be a number; was %T", li) } bits := []string{"["} for i := 0; i < int(l); i++ { e, err := o.Get(fmt.Sprintf("%d", i)) if err != nil { return "", err } d, err := formatIndent(e, width, indent, limit-1, level+1, 0, seenWith(seen, v)) if err != nil { return "", err } bits = append(bits, strings.Repeat(" ", (level+1)*indent)+d+",") } bits = append(bits, strings.Repeat(" ", level*indent)+"]") return strings.Join(bits, "\n"), nil }
func buildPathFromValue(val otto.Value) (out []interface{}) { if val.IsNull() || val.IsUndefined() { return nil } if val.IsPrimitive() { thing, _ := val.Export() switch v := thing.(type) { case string: out = append(out, v) return default: clog.Errorf("Trying to build unknown primitive value.") } } switch val.Class() { case "Object": out = append(out, buildPathFromObject(val.Object())) return case "Array": // Had better be an array of strings for _, x := range stringsFrom(val.Object()) { out = append(out, x) } return case "Number": fallthrough case "Boolean": fallthrough case "Date": fallthrough case "String": out = append(out, val.String()) return default: clog.Errorf("Trying to handle unsupported Javascript value.") return nil } }
func (ctx ppctx) printValue(v otto.Value, level int, inArray bool) { switch { case v.IsObject(): ctx.printObject(v.Object(), level, inArray) case v.IsNull(): specialColor.Print("null") case v.IsUndefined(): specialColor.Print("undefined") case v.IsString(): s, _ := v.ToString() stringColor.Printf("%q", s) case v.IsBoolean(): b, _ := v.ToBoolean() specialColor.Printf("%t", b) case v.IsNaN(): numberColor.Printf("NaN") case v.IsNumber(): s, _ := v.ToString() numberColor.Printf("%s", s) default: fmt.Printf("<unprintable>") } }
func formatIndent(v otto.Value, width, indent, limit, level, additional int, seen map[otto.Value]bool) (string, error) { if limit == 0 { return "...", nil } switch { case v.IsBoolean(), v.IsNull(), v.IsNumber(), v.IsUndefined(): return v.String(), nil case v.IsString(): return fmt.Sprintf("%q", v.String()), nil case v.IsFunction(): n, err := v.Object().Get("name") if err != nil { return "", err } if n.IsUndefined() { return "function", nil } return fmt.Sprintf("function %s", n.String()), nil case v.IsObject(): if d, err := formatOneLine(v, limit, seen); err != nil { return "", err } else if level*indent+additional+len(d) <= width { return d, nil } switch v.Class() { case "Array": return formatArray(v, width, indent, limit, level, seen) default: return formatObject(v, width, indent, limit, level, seen) } default: return "", fmt.Errorf("couldn't format type %s", v.Class()) } }