1// Copyright 2015-2017 Jean Niklas L'orange. 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 5package edn 6 7import ( 8 "bufio" 9 "bytes" 10 "errors" 11 "fmt" 12) 13 14// RawMessage is a raw encoded, but valid, EDN value. It implements Marshaler 15// and Unmarshaler and can be used to delay EDN decoding or precompute an EDN 16// encoding. 17type RawMessage []byte 18 19// MarshalEDN returns m as the EDN encoding of m. 20func (m RawMessage) MarshalEDN() ([]byte, error) { 21 if m == nil { 22 return []byte("nil"), nil 23 } 24 return m, nil 25} 26 27// UnmarshalEDN sets *m to a copy of data. 28func (m *RawMessage) UnmarshalEDN(data []byte) error { 29 if m == nil { 30 return errors.New("edn.RawMessage: UnmarshalEDN on nil pointer") 31 } 32 *m = append((*m)[0:0], data...) 33 return nil 34} 35 36// A Keyword is an EDN keyword without : prepended in front. 37type Keyword string 38 39func (k Keyword) String() string { 40 return fmt.Sprintf(":%s", string(k)) 41} 42 43func (k Keyword) MarshalEDN() ([]byte, error) { 44 return []byte(k.String()), nil 45} 46 47// A Symbol is an EDN symbol. 48type Symbol string 49 50func (s Symbol) String() string { 51 return string(s) 52} 53 54func (s Symbol) MarshalEDN() ([]byte, error) { 55 return []byte(s), nil 56} 57 58// A Tag is a tagged value. The Tagname represents the name of the tag, and the 59// Value is the value of the element. 60type Tag struct { 61 Tagname string 62 Value interface{} 63} 64 65func (t Tag) String() string { 66 return fmt.Sprintf("#%s %v", t.Tagname, t.Value) 67} 68 69func (t Tag) MarshalEDN() ([]byte, error) { 70 str := []byte(fmt.Sprintf(`#%s `, t.Tagname)) 71 b, err := Marshal(t.Value) 72 if err != nil { 73 return nil, err 74 } 75 return append(str, b...), nil 76} 77 78func (t *Tag) UnmarshalEDN(bs []byte) error { 79 // read actual tag, using the lexer. 80 var lex lexer 81 lex.reset() 82 buf := bufio.NewReader(bytes.NewBuffer(bs)) 83 start := 0 84 endTag := 0 85tag: 86 for { 87 r, rlen, err := buf.ReadRune() 88 if err != nil { 89 return err 90 } 91 92 ls := lex.state(r) 93 switch ls { 94 case lexIgnore: 95 start += rlen 96 endTag += rlen 97 case lexError: 98 return lex.err 99 case lexEndPrev: 100 break tag 101 case lexEnd: // unexpected, assuming tag which is not ending with lexEnd 102 return errUnexpected 103 case lexCont: 104 endTag += rlen 105 } 106 } 107 t.Tagname = string(bs[start+1 : endTag]) 108 return Unmarshal(bs[endTag:], &t.Value) 109} 110 111// A Rune type is a wrapper for a rune. It can be used to encode runes as 112// characters instead of int32 values. 113type Rune rune 114 115func (r Rune) MarshalEDN() ([]byte, error) { 116 buf := bytes.NewBuffer(make([]byte, 0, 10)) 117 encodeRune(buf, rune(r)) 118 return buf.Bytes(), nil 119} 120 121func encodeRune(buf *bytes.Buffer, r rune) { 122 const hex = "0123456789abcdef" 123 if !isWhitespace(r) { 124 buf.WriteByte('\\') 125 buf.WriteRune(r) 126 } else { 127 switch r { 128 case '\b': 129 buf.WriteString(`\backspace`) 130 case '\f': 131 buf.WriteString(`\formfeed`) 132 case '\n': 133 buf.WriteString(`\newline`) 134 case '\r': 135 buf.WriteString(`\return`) 136 case '\t': 137 buf.WriteString(`\tab`) 138 case ' ': 139 buf.WriteString(`\space`) 140 default: 141 buf.WriteByte('\\') 142 buf.WriteByte('u') 143 buf.WriteByte(hex[r>>12&0xF]) 144 buf.WriteByte(hex[r>>8&0xF]) 145 buf.WriteByte(hex[r>>4&0xF]) 146 buf.WriteByte(hex[r&0xF]) 147 } 148 } 149} 150