summaryrefslogtreecommitdiff
path: root/vendor/github.com/tkrajina/gpxgo/gpx/nullable_float64.go
blob: 3df52ef1afbf4abcd07bd4d91bcae0b388777256 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright 2013, 2014 Peter Vasil, Tomo Krajina. All
// rights reserved. Use of this source code is governed
// by a BSD-style license that can be found in the
// LICENSE file.

package gpx

import (
	"encoding/xml"
	"fmt"
	"strconv"
	"strings"
)

type NullableFloat64 struct {
	data    float64
	notNull bool
}

func (n *NullableFloat64) Null() bool {
	return !n.notNull
}

func (n *NullableFloat64) NotNull() bool {
	return n.notNull
}

func (n *NullableFloat64) Value() float64 {
	return n.data
}

func (n *NullableFloat64) SetValue(data float64) {
	n.data = data
	n.notNull = true
}

func (n *NullableFloat64) SetNull() {
	var defaultValue float64
	n.data = defaultValue
	n.notNull = false
}

func NewNullableFloat64(data float64) *NullableFloat64 {
	result := new(NullableFloat64)
	result.data = data
	result.notNull = true
	return result
}

func (n *NullableFloat64) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	t, err := d.Token()
	if err != nil {
		n.SetNull()
		return nil
	}
	if charData, ok := t.(xml.CharData); ok {
		strData := strings.Trim(string(charData), " ")
		value, err := strconv.ParseFloat(strData, 64)
		if err != nil {
			n.SetNull()
			return nil
		}
		n.SetValue(value)
	}
	d.Skip()
	return nil
}

func (n *NullableFloat64) UnmarshalXMLAttr(attr xml.Attr) error {
	strData := strings.Trim(string(attr.Value), " ")
	value, err := strconv.ParseFloat(strData, 64)
	if err != nil {
		n.SetNull()
		return nil
	}
	n.SetValue(value)
	return nil
}

func (n NullableFloat64) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	if n.Null() {
		return nil
	}
	xmlName := xml.Name{Local: start.Name.Local}
	e.EncodeToken(xml.StartElement{Name: xmlName})
	e.EncodeToken(xml.CharData([]byte(fmt.Sprintf("%g", n.Value()))))
	e.EncodeToken(xml.EndElement{Name: xmlName})
	return nil
}

func (n NullableFloat64) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
	var result xml.Attr
	if n.Null() {
		return result, nil
	}
	return xml.Attr{
			Name:  xml.Name{Local: name.Local},
			Value: fmt.Sprintf("%g", n.Value())},
		nil
}