go-hep.org/x/hep@v0.38.1/hbook/ann.go (about) 1 // Copyright ©2020 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package hbook 6 7 import ( 8 "bufio" 9 "bytes" 10 "encoding/gob" 11 "fmt" 12 "io" 13 "sort" 14 "strings" 15 16 "gopkg.in/yaml.v3" 17 ) 18 19 // Annotation is a bag of attributes that are attached to a histogram. 20 type Annotation map[string]any 21 22 func (ann Annotation) clone() Annotation { 23 buf := new(bytes.Buffer) 24 err := gob.NewEncoder(buf).Encode(&ann) 25 if err != nil { 26 panic(err) 27 } 28 out := make(Annotation, len(ann)) 29 err = gob.NewDecoder(buf).Decode(&out) 30 if err != nil { 31 panic(err) 32 } 33 return out 34 } 35 36 // MarshalYODA implements the YODAMarshaler interface. 37 func (ann Annotation) MarshalYODA() ([]byte, error) { 38 return ann.marshalYODAv2() 39 } 40 41 // marshalYODAv1 implements the YODAMarshaler interface. 42 func (ann Annotation) marshalYODAv1() ([]byte, error) { 43 keys := make([]string, 0, len(ann)) 44 for k := range ann { 45 if k == "" { 46 continue 47 } 48 keys = append(keys, k) 49 } 50 sort.Strings(keys) 51 buf := new(bytes.Buffer) 52 for _, k := range keys { 53 fmt.Fprintf(buf, "%s=%v\n", k, ann[k]) 54 } 55 return buf.Bytes(), nil 56 } 57 58 // marshalYODAv2 implements the YODAMarshaler interface. 59 func (ann Annotation) marshalYODAv2() ([]byte, error) { 60 return yaml.Marshal(ann) 61 } 62 63 // UnmarshalYODA implements the YODAUnmarshaler interface. 64 func (ann *Annotation) UnmarshalYODA(data []byte) error { 65 return ann.unmarshalYODAv2(data) 66 } 67 68 // unmarshalYODAv1 unmarshal YODA v1. 69 func (ann *Annotation) unmarshalYODAv1(data []byte) error { 70 var err error 71 s := bufio.NewScanner(bytes.NewReader(data)) 72 for s.Scan() { 73 txt := s.Text() 74 i := strings.Index(txt, "=") 75 k := txt[:i] 76 v := txt[i+1:] 77 (*ann)[k] = v 78 } 79 err = s.Err() 80 if err == io.EOF { 81 err = nil 82 } 83 return err 84 } 85 86 // unmarshalYODAv2 unmarshal YODA v2. 87 func (ann *Annotation) unmarshalYODAv2(data []byte) error { 88 return yaml.Unmarshal(data, ann) 89 } 90 91 // MarshalBinary implements encoding.BinaryMarshaler 92 func (ann *Annotation) MarshalBinary() ([]byte, error) { 93 var v map[string]any = *ann 94 buf := new(bytes.Buffer) 95 err := gob.NewEncoder(buf).Encode(v) 96 return buf.Bytes(), err 97 } 98 99 // UnmarshalBinary implements encoding.BinaryUnmarshaler 100 func (ann *Annotation) UnmarshalBinary(data []byte) error { 101 var v = make(map[string]any) 102 buf := bytes.NewReader(data) 103 err := gob.NewDecoder(buf).Decode(&v) 104 if err != nil { 105 return err 106 } 107 *ann = Annotation(v) 108 return nil 109 }