1 // Copyright (c) 2020 Cisco and/or its affiliates.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at:
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
18 //RegisterPlugin("convert", GenerateConvert)
21 // library dependencies
23 fmtPkg = GoImportPath("fmt")
24 netPkg = GoImportPath("net")
25 timePkg = GoImportPath("time")
26 stringsPkg = GoImportPath("strings")
29 func genIPConversion(g *GenFile, structName string, ipv int) {
30 // ParseIPXAddress method
31 g.P("func Parse", structName, "(s string) (", structName, ", error) {")
33 g.P(" ip := ", netPkg.Ident("ParseIP"), "(s).To4()")
35 g.P(" ip := ", netPkg.Ident("ParseIP"), "(s).To16()")
37 g.P(" if ip == nil {")
38 g.P(" return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP address: %s\", s)")
40 g.P(" var ipaddr ", structName)
42 g.P(" copy(ipaddr[:], ip.To4())")
44 g.P(" copy(ipaddr[:], ip.To16())")
46 g.P(" return ipaddr, nil")
51 g.P("func (x ", structName, ") ToIP() ", netPkg.Ident("IP"), " {")
53 g.P(" return ", netPkg.Ident("IP"), "(x[:]).To4()")
55 g.P(" return ", netPkg.Ident("IP"), "(x[:]).To16()")
61 g.P("func (x ", structName, ") String() string {")
62 g.P(" return x.ToIP().String()")
67 g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
68 g.P(" return []byte(x.String()), nil")
72 // UnmarshalText method
73 g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
74 g.P(" ipaddr, err := Parse", structName, "(string(text))")
75 g.P(" if err !=nil {")
84 func genAddressConversion(g *GenFile, structName string) {
85 // ParseAddress method
86 g.P("func Parse", structName, "(s string) (", structName, ", error) {")
87 g.P(" ip := ", netPkg.Ident("ParseIP"), "(s)")
88 g.P(" if ip == nil {")
89 g.P(" return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid address: %s\", s)")
91 g.P(" return ", structName, "FromIP(ip), nil")
95 // AddressFromIP method
96 g.P("func ", structName, "FromIP(ip ", netPkg.Ident("IP"), ") ", structName, " {")
97 g.P(" var addr ", structName)
98 g.P(" if ip.To4() == nil {")
99 g.P(" addr.Af = ADDRESS_IP6")
100 g.P(" var ip6 IP6Address")
101 g.P(" copy(ip6[:], ip.To16())")
102 g.P(" addr.Un.SetIP6(ip6)")
104 g.P(" addr.Af = ADDRESS_IP4")
105 g.P(" var ip4 IP4Address")
106 g.P(" copy(ip4[:], ip.To4())")
107 g.P(" addr.Un.SetIP4(ip4)")
114 g.P("func (x ", structName, ") ToIP() ", netPkg.Ident("IP"), " {")
115 g.P(" if x.Af == ADDRESS_IP6 {")
116 g.P(" ip6 := x.Un.GetIP6()")
117 g.P(" return ", netPkg.Ident("IP"), "(ip6[:]).To16()")
119 g.P(" ip4 := x.Un.GetIP4()")
120 g.P(" return ", netPkg.Ident("IP"), "(ip4[:]).To4()")
126 g.P("func (x ", structName, ") String() string {")
127 g.P(" return x.ToIP().String()")
131 // MarshalText method
132 g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
133 g.P(" return []byte(x.String()), nil")
137 // UnmarshalText method
138 g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
139 g.P(" addr, err := Parse", structName, "(string(text))")
140 g.P(" if err != nil {")
149 func genIPPrefixConversion(g *GenFile, structName string, ipv int) {
150 // ParsePrefix method
151 g.P("func Parse", structName, "(s string) (prefix ", structName, ", err error) {")
152 g.P(" hasPrefix := ", stringsPkg.Ident("Contains"), "(s, \"/\")")
153 g.P(" if hasPrefix {")
154 g.P(" ip, network, err := ", netPkg.Ident("ParseCIDR"), "(s)")
155 g.P(" if err != nil {")
156 g.P(" return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", s, err)")
158 g.P(" maskSize, _ := network.Mask.Size()")
159 g.P(" prefix.Len = byte(maskSize)")
161 g.P(" prefix.Address, err = ParseIP4Address(ip.String())")
163 g.P(" prefix.Address, err = ParseIP6Address(ip.String())")
165 g.P(" if err != nil {")
166 g.P(" return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", s, err)")
169 g.P(" ip := ", netPkg.Ident("ParseIP"), "(s)")
170 g.P(" defaultMaskSize, _ := ", netPkg.Ident("CIDRMask"), "(32, 32).Size()")
171 g.P(" if ip.To4() == nil {")
172 g.P(" defaultMaskSize, _ =", netPkg.Ident("CIDRMask"), "(128, 128).Size()")
174 g.P(" prefix.Len = byte(defaultMaskSize)")
176 g.P(" prefix.Address, err = ParseIP4Address(ip.String())")
178 g.P(" prefix.Address, err = ParseIP6Address(ip.String())")
180 g.P(" if err != nil {")
181 g.P(" return ", structName, "{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", s, err)")
184 g.P(" return prefix, nil")
189 g.P("func (x ", structName, ") ToIPNet() *", netPkg.Ident("IPNet"), " {")
191 g.P(" mask := ", netPkg.Ident("CIDRMask"), "(int(x.Len), 32)")
193 g.P(" mask := ", netPkg.Ident("CIDRMask"), "(int(x.Len), 128)")
195 g.P(" ipnet := &", netPkg.Ident("IPNet"), "{IP: x.Address.ToIP(), Mask: mask}")
201 g.P("func (x ", structName, ") String() string {")
202 g.P(" ip := x.Address.String()")
203 g.P(" return ip + \"/\" + ", strconvPkg.Ident("Itoa"), "(int(x.Len))")
207 // MarshalText method
208 g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
209 g.P(" return []byte(x.String()), nil")
213 // UnmarshalText method
214 g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
215 g.P(" prefix, err := Parse", structName, "(string(text))")
216 g.P(" if err != nil {")
225 func genPrefixConversion(g *GenFile, structName string) {
226 // ParsePrefix method
227 g.P("func Parse", structName, "(ip string) (prefix ", structName, ", err error) {")
228 g.P(" hasPrefix := ", stringsPkg.Ident("Contains"), "(ip, \"/\")")
229 g.P(" if hasPrefix {")
230 g.P(" netIP, network, err := ", netPkg.Ident("ParseCIDR"), "(ip)")
231 g.P(" if err != nil {")
232 g.P(" return Prefix{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", ip, err)")
234 g.P(" maskSize, _ := network.Mask.Size()")
235 g.P(" prefix.Len = byte(maskSize)")
236 g.P(" prefix.Address, err = ParseAddress(netIP.String())")
237 g.P(" if err != nil {")
238 g.P(" return Prefix{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", ip, err)")
241 g.P(" netIP := ", netPkg.Ident("ParseIP"), "(ip)")
242 g.P(" defaultMaskSize, _ := ", netPkg.Ident("CIDRMask"), "(32, 32).Size()")
243 g.P(" if netIP.To4() == nil {")
244 g.P(" defaultMaskSize, _ =", netPkg.Ident("CIDRMask"), "(128, 128).Size()")
246 g.P(" prefix.Len = byte(defaultMaskSize)")
247 g.P(" prefix.Address, err = ParseAddress(netIP.String())")
248 g.P(" if err != nil {")
249 g.P(" return Prefix{}, ", fmtPkg.Ident("Errorf"), "(\"invalid IP %s: %s\", ip, err)")
252 g.P(" return prefix, nil")
257 g.P("func (x ", structName, ") ToIPNet() *", netPkg.Ident("IPNet"), " {")
258 g.P(" var mask ", netPkg.Ident("IPMask"))
259 g.P(" if x.Address.Af == ADDRESS_IP4 {")
260 g.P(" mask = ", netPkg.Ident("CIDRMask"), "(int(x.Len), 32)")
262 g.P(" mask = ", netPkg.Ident("CIDRMask"), "(int(x.Len), 128)")
264 g.P(" ipnet := &", netPkg.Ident("IPNet"), "{IP: x.Address.ToIP(), Mask: mask}")
270 g.P("func (x ", structName, ") String() string {")
271 g.P(" ip := x.Address.String()")
272 g.P(" return ip + \"/\" + ", strconvPkg.Ident("Itoa"), "(int(x.Len))")
276 // MarshalText method
277 g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
278 g.P(" return []byte(x.String()), nil")
282 // UnmarshalText method
283 g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
284 g.P(" prefix, err := Parse", structName, "(string(text))")
285 g.P(" if err !=nil {")
294 func genAddressWithPrefixConversion(g *GenFile, structName string) {
295 // ParseAddressWithPrefix method
296 g.P("func Parse", structName, "(s string) (", structName, ", error) {")
297 g.P(" prefix, err := ParsePrefix(s)")
298 g.P(" if err != nil {")
299 g.P(" return ", structName, "{}, err")
301 g.P(" return ", structName, "(prefix), nil")
306 g.P("func (x ", structName, ") String() string {")
307 g.P(" return Prefix(x).String()")
311 // MarshalText method
312 g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
313 g.P(" return []byte(x.String()), nil")
317 // UnmarshalText method
318 g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
319 g.P(" prefix, err := Parse", structName, "(string(text))")
320 g.P(" if err != nil {")
329 func genMacAddressConversion(g *GenFile, structName string) {
331 g.P("func Parse", structName, "(s string) (", structName, ", error) {")
332 g.P(" var macaddr ", structName)
333 g.P(" mac, err := ", netPkg.Ident("ParseMAC"), "(s)")
334 g.P(" if err != nil {")
335 g.P(" return macaddr, err")
337 g.P(" copy(macaddr[:], mac[:])")
338 g.P(" return macaddr, nil")
343 g.P("func (x ", structName, ") ToMAC() ", netPkg.Ident("HardwareAddr"), " {")
344 g.P(" return ", netPkg.Ident("HardwareAddr"), "(x[:])")
349 g.P("func (x ", structName, ") String() string {")
350 g.P(" return x.ToMAC().String()")
354 // MarshalText method
355 g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
356 g.P(" return []byte(x.String()), nil")
360 // UnmarshalText method
361 g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
362 g.P(" mac, err := Parse", structName, "(string(text))")
363 g.P(" if err != nil {")
372 func genTimestampConversion(g *GenFile, structName string) {
373 // NewTimestamp method
374 g.P("func New", structName, "(t ", timePkg.Ident("Time"), ") ", structName, " {")
375 g.P(" sec := int64(t.Unix())")
376 g.P(" nsec := int32(t.Nanosecond())")
377 g.P(" ns := float64(sec) + float64(nsec / 1e9)")
378 g.P(" return ", structName, "(ns)")
383 g.P("func (x ", structName, ") ToTime() ", timePkg.Ident("Time"), " {")
384 g.P(" ns := int64(x * 1e9)")
385 g.P(" sec := ns / 1e9")
386 g.P(" nsec := ns % 1e9")
387 g.P(" return ", timePkg.Ident("Unix"), "(sec, nsec)")
392 g.P("func (x ", structName, ") String() string {")
393 g.P(" return x.ToTime().String()")
397 // MarshalText method
398 g.P("func (x *", structName, ") MarshalText() ([]byte, error) {")
399 g.P(" return []byte(x.ToTime().Format(", timePkg.Ident("RFC3339Nano"), ")), nil")
403 // UnmarshalText method
404 g.P("func (x *", structName, ") UnmarshalText(text []byte) error {")
405 g.P(" t, err := ", timePkg.Ident("Parse"), "(", timePkg.Ident("RFC3339Nano"), ", string(text))")
406 g.P(" if err != nil {")
409 g.P(" *x = New", structName, "(t)")