mirror of
https://github.com/jimeh/rbheap.git
synced 2026-02-19 04:46:40 +00:00
Initial starting point for a inspect command
This commit is contained in:
39
cmd/inspect.go
Normal file
39
cmd/inspect.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jimeh/rbheap/inspect"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// inspectCmd represents the inspect command
|
||||
var inspectCmd = &cobra.Command{
|
||||
Use: "inspect [flags] <dump-file>",
|
||||
Short: "Inspect ObjectSpace dumps from Ruby proceees",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 1 {
|
||||
usage_er(cmd, fmt.Sprintf("requires 1 arg, received %d", len(args)))
|
||||
}
|
||||
|
||||
inspector := inspect.New(args[0])
|
||||
inspector.Verbose = inspectOpts.Verbose
|
||||
inspector.Process()
|
||||
|
||||
inspector.PrintCountByFileAndLines()
|
||||
},
|
||||
}
|
||||
|
||||
var inspectOpts = struct {
|
||||
Verbose bool
|
||||
}{}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(inspectCmd)
|
||||
|
||||
inspectCmd.PersistentFlags().BoolVarP(
|
||||
&inspectOpts.Verbose,
|
||||
"verbose", "v", false,
|
||||
"print verbose information",
|
||||
)
|
||||
}
|
||||
74
inspect/dump.go
Normal file
74
inspect/dump.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package inspect
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func NewDump(filePath string) *Dump {
|
||||
return &Dump{FilePath: filePath}
|
||||
}
|
||||
|
||||
// Dump contains all relevant data for a single heap dump.
|
||||
type Dump struct {
|
||||
FilePath string
|
||||
ByAddress map[string]*Object
|
||||
ByFile map[string][]*Object
|
||||
ByFileAndLine map[string][]*Object
|
||||
ByGeneration map[int][]*Object
|
||||
}
|
||||
|
||||
// Process processes the heap dump referenced in FilePath.
|
||||
func (s *Dump) Process() error {
|
||||
file, err := os.Open(s.FilePath)
|
||||
defer file.Close()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.ByAddress = map[string]*Object{}
|
||||
s.ByFile = map[string][]*Object{}
|
||||
s.ByFileAndLine = map[string][]*Object{}
|
||||
s.ByGeneration = map[int][]*Object{}
|
||||
|
||||
reader := bufio.NewReader(file)
|
||||
for {
|
||||
line, err := reader.ReadBytes(byte('\n'))
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
object, err := NewObject(line)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.AddObject(object)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddObject adds a *Object to the Dump.
|
||||
func (s *Dump) AddObject(obj *Object) {
|
||||
s.ByAddress[obj.Address] = obj
|
||||
|
||||
if obj.File != "" {
|
||||
s.ByFile[obj.File] = append(s.ByFile[obj.File], obj)
|
||||
}
|
||||
|
||||
if obj.File != "" && obj.Line != 0 {
|
||||
key := obj.File + ":" + strconv.Itoa(obj.Line)
|
||||
s.ByFileAndLine[key] = append(s.ByFileAndLine[key], obj)
|
||||
}
|
||||
|
||||
if obj.Generation != 0 {
|
||||
s.ByGeneration[obj.Generation] =
|
||||
append(s.ByGeneration[obj.Generation], obj)
|
||||
}
|
||||
}
|
||||
47
inspect/inspector.go
Normal file
47
inspect/inspector.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package inspect
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func New(filePath string) *Inspector {
|
||||
|
||||
return &Inspector{
|
||||
FilePath: filePath,
|
||||
Dump: NewDump(filePath),
|
||||
}
|
||||
}
|
||||
|
||||
type Inspector struct {
|
||||
FilePath string
|
||||
Dump *Dump
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
func (s *Inspector) Process() {
|
||||
|
||||
start := time.Now()
|
||||
s.log(fmt.Sprintf("Parsing %s", s.FilePath))
|
||||
|
||||
s.Dump.Process()
|
||||
|
||||
elapsed := time.Now().Sub(start)
|
||||
s.log(fmt.Sprintf(
|
||||
"Parsed %d objects in %.6f seconds",
|
||||
len(s.Dump.ByAddress),
|
||||
elapsed.Seconds(),
|
||||
))
|
||||
}
|
||||
|
||||
func (s *Inspector) PrintCountByFileAndLines() {
|
||||
for k, objects := range s.Dump.ByFileAndLine {
|
||||
fmt.Printf("%s: %d objects\n", k, len(objects))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Inspector) log(msg string) {
|
||||
if s.Verbose {
|
||||
fmt.Println(msg)
|
||||
}
|
||||
}
|
||||
62
inspect/object.go
Normal file
62
inspect/object.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package inspect
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
//go:generate easyjson -all object.go
|
||||
|
||||
// NewObject returns a new *Object instance with it's attributes populated from
|
||||
// the given input JSON data.
|
||||
func NewObject(inputJSON []byte) (*Object, error) {
|
||||
var obj Object
|
||||
err := json.Unmarshal(inputJSON, &obj)
|
||||
|
||||
return &obj, err
|
||||
}
|
||||
|
||||
// Object is a representation of a Ruby heap object as exported from Ruby via
|
||||
// `ObjectSpace.dump_all`.
|
||||
type Object struct {
|
||||
Address string `json:"address"`
|
||||
Bytesize int `json:"bytesize"`
|
||||
Capacity int `json:"capacity"`
|
||||
Class string `json:"class"`
|
||||
Default string `json:"default"`
|
||||
Embedded bool `json:"embedded"`
|
||||
Encoding string `json:"encoding"`
|
||||
Fd int `json:"fd"`
|
||||
File string `json:"file"`
|
||||
Flags ObjectFlags `json:"flags"`
|
||||
Frozen bool `json:"frozen"`
|
||||
Fstring bool `json:"fstring"`
|
||||
Generation int `json:"generation"`
|
||||
ImemoType string `json:"imemo_type"`
|
||||
Ivars int `json:"ivars"`
|
||||
Length int `json:"length"`
|
||||
Line int `json:"line"`
|
||||
Memsize int `json:"memsize"`
|
||||
Method string `json:"method"`
|
||||
Name string `json:"name"`
|
||||
References ObjectReferences `json:"references"`
|
||||
Root string `json:"root"`
|
||||
Shared bool `json:"shared"`
|
||||
Size int `json:"size"`
|
||||
Struct string `json:"struct"`
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// Index returns a unique index for the given Object.
|
||||
func (s *Object) Index() string {
|
||||
return s.Address + ":" + s.Type
|
||||
}
|
||||
|
||||
// ObjectFlags represents the available flags on an Object.
|
||||
type ObjectFlags struct {
|
||||
Marked bool `json:"marked"`
|
||||
Old bool `json:"old"`
|
||||
Uncollectible bool `json:"uncollectible"`
|
||||
WbProtected bool `json:"wb_protected"`
|
||||
}
|
||||
|
||||
// ObjectReferences represents the list of references in an Object.
|
||||
type ObjectReferences []string
|
||||
543
inspect/object_easyjson.go
Normal file
543
inspect/object_easyjson.go
Normal file
@@ -0,0 +1,543 @@
|
||||
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
|
||||
|
||||
package inspect
|
||||
|
||||
import (
|
||||
json "encoding/json"
|
||||
easyjson "github.com/mailru/easyjson"
|
||||
jlexer "github.com/mailru/easyjson/jlexer"
|
||||
jwriter "github.com/mailru/easyjson/jwriter"
|
||||
)
|
||||
|
||||
// suppress unused package warning
|
||||
var (
|
||||
_ *json.RawMessage
|
||||
_ *jlexer.Lexer
|
||||
_ *jwriter.Writer
|
||||
_ easyjson.Marshaler
|
||||
)
|
||||
|
||||
func easyjsonE44bcf2dDecodeGithubComJimehRbheapInspect(in *jlexer.Lexer, out *ObjectFlags) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeString()
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "marked":
|
||||
out.Marked = bool(in.Bool())
|
||||
case "old":
|
||||
out.Old = bool(in.Bool())
|
||||
case "uncollectible":
|
||||
out.Uncollectible = bool(in.Bool())
|
||||
case "wb_protected":
|
||||
out.WbProtected = bool(in.Bool())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonE44bcf2dEncodeGithubComJimehRbheapInspect(out *jwriter.Writer, in ObjectFlags) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"marked\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.Marked))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"old\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.Old))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"uncollectible\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.Uncollectible))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"wb_protected\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.WbProtected))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v ObjectFlags) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonE44bcf2dEncodeGithubComJimehRbheapInspect(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v ObjectFlags) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonE44bcf2dEncodeGithubComJimehRbheapInspect(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *ObjectFlags) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonE44bcf2dDecodeGithubComJimehRbheapInspect(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *ObjectFlags) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonE44bcf2dDecodeGithubComJimehRbheapInspect(l, v)
|
||||
}
|
||||
func easyjsonE44bcf2dDecodeGithubComJimehRbheapInspect1(in *jlexer.Lexer, out *Object) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeString()
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "address":
|
||||
out.Address = string(in.String())
|
||||
case "bytesize":
|
||||
out.Bytesize = int(in.Int())
|
||||
case "capacity":
|
||||
out.Capacity = int(in.Int())
|
||||
case "class":
|
||||
out.Class = string(in.String())
|
||||
case "default":
|
||||
out.Default = string(in.String())
|
||||
case "embedded":
|
||||
out.Embedded = bool(in.Bool())
|
||||
case "encoding":
|
||||
out.Encoding = string(in.String())
|
||||
case "fd":
|
||||
out.Fd = int(in.Int())
|
||||
case "file":
|
||||
out.File = string(in.String())
|
||||
case "flags":
|
||||
if data := in.Raw(); in.Ok() {
|
||||
in.AddError((out.Flags).UnmarshalJSON(data))
|
||||
}
|
||||
case "frozen":
|
||||
out.Frozen = bool(in.Bool())
|
||||
case "fstring":
|
||||
out.Fstring = bool(in.Bool())
|
||||
case "generation":
|
||||
out.Generation = int(in.Int())
|
||||
case "imemo_type":
|
||||
out.ImemoType = string(in.String())
|
||||
case "ivars":
|
||||
out.Ivars = int(in.Int())
|
||||
case "length":
|
||||
out.Length = int(in.Int())
|
||||
case "line":
|
||||
out.Line = int(in.Int())
|
||||
case "memsize":
|
||||
out.Memsize = int(in.Int())
|
||||
case "method":
|
||||
out.Method = string(in.String())
|
||||
case "name":
|
||||
out.Name = string(in.String())
|
||||
case "references":
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
out.References = nil
|
||||
} else {
|
||||
in.Delim('[')
|
||||
if out.References == nil {
|
||||
if !in.IsDelim(']') {
|
||||
out.References = make(ObjectReferences, 0, 4)
|
||||
} else {
|
||||
out.References = ObjectReferences{}
|
||||
}
|
||||
} else {
|
||||
out.References = (out.References)[:0]
|
||||
}
|
||||
for !in.IsDelim(']') {
|
||||
var v1 string
|
||||
v1 = string(in.String())
|
||||
out.References = append(out.References, v1)
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim(']')
|
||||
}
|
||||
case "root":
|
||||
out.Root = string(in.String())
|
||||
case "shared":
|
||||
out.Shared = bool(in.Bool())
|
||||
case "size":
|
||||
out.Size = int(in.Int())
|
||||
case "struct":
|
||||
out.Struct = string(in.String())
|
||||
case "type":
|
||||
out.Type = string(in.String())
|
||||
case "value":
|
||||
out.Value = string(in.String())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjsonE44bcf2dEncodeGithubComJimehRbheapInspect1(out *jwriter.Writer, in Object) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
{
|
||||
const prefix string = ",\"address\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Address))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"bytesize\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Int(int(in.Bytesize))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"capacity\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Int(int(in.Capacity))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"class\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Class))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"default\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Default))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"embedded\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.Embedded))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"encoding\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Encoding))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"fd\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Int(int(in.Fd))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"file\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.File))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"flags\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Raw((in.Flags).MarshalJSON())
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"frozen\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.Frozen))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"fstring\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.Fstring))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"generation\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Int(int(in.Generation))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"imemo_type\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.ImemoType))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"ivars\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Int(int(in.Ivars))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"length\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Int(int(in.Length))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"line\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Int(int(in.Line))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"memsize\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Int(int(in.Memsize))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"method\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Method))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"name\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Name))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"references\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
if in.References == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
|
||||
out.RawString("null")
|
||||
} else {
|
||||
out.RawByte('[')
|
||||
for v2, v3 := range in.References {
|
||||
if v2 > 0 {
|
||||
out.RawByte(',')
|
||||
}
|
||||
out.String(string(v3))
|
||||
}
|
||||
out.RawByte(']')
|
||||
}
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"root\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Root))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"shared\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.Shared))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"size\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Int(int(in.Size))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"struct\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Struct))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"type\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Type))
|
||||
}
|
||||
{
|
||||
const prefix string = ",\"value\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Value))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
|
||||
// MarshalJSON supports json.Marshaler interface
|
||||
func (v Object) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{}
|
||||
easyjsonE44bcf2dEncodeGithubComJimehRbheapInspect1(&w, v)
|
||||
return w.Buffer.BuildBytes(), w.Error
|
||||
}
|
||||
|
||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||
func (v Object) MarshalEasyJSON(w *jwriter.Writer) {
|
||||
easyjsonE44bcf2dEncodeGithubComJimehRbheapInspect1(w, v)
|
||||
}
|
||||
|
||||
// UnmarshalJSON supports json.Unmarshaler interface
|
||||
func (v *Object) UnmarshalJSON(data []byte) error {
|
||||
r := jlexer.Lexer{Data: data}
|
||||
easyjsonE44bcf2dDecodeGithubComJimehRbheapInspect1(&r, v)
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||
func (v *Object) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||
easyjsonE44bcf2dDecodeGithubComJimehRbheapInspect1(l, v)
|
||||
}
|
||||
Reference in New Issue
Block a user