Allow access (as strings) to the rdata of each RR

This commit is contained in:
Miek Gieben 2015-01-11 21:01:54 +00:00
parent 74b8577dc6
commit 735efcbd10
2 changed files with 41 additions and 20 deletions

View File

@ -15,26 +15,39 @@
// %D the TTL in seconds
// %Y the type: MX, A, etc.
//
// The rdata of each RR differs, we allow each field to be printed as a string.
//
// Rdata: (TODO)
//
// %0 the first rdata field
// %1 the second rdata field
// %2 the third rdata field
// .. ...
// %9 the nineth rdata field
// %R all rdata fields
//
// Non exsiting rdata fields will be printed as the empty string.
// The rdata of each RR differs, we allow each field to be accessed as a string with
// the Field function.
//
package dns
import (
"fmt"
"reflect"
"strconv"
)
// Field returns the rdata field i as a string. Fields are indexed starting from 1.
func Field(r RR, i int) string {
if i == 0 {
return ""
}
d := reflect.ValueOf(r).Elem().Field(i)
switch d.Kind() {
case reflect.String:
return d.String()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return strconv.FormatInt(d.Int(), 10)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return strconv.FormatUint(d.Uint(), 10)
}
return ""
}
// NumField returns the number of rdata fields r has.
func NumField(r RR) int {
return reflect.ValueOf(r).Elem().NumField() - 1 // Remove RR_Header
}
func format(r RR, f fmt.State, c rune) {
switch c {
case 'N':
@ -47,7 +60,6 @@ func format(r RR, f fmt.State, c rune) {
f.Write([]byte(Type(r.Header().Rrtype).String()))
case 's':
f.Write([]byte(r.String()))
}
}

View File

@ -1341,22 +1341,31 @@ func TestNewRRSpecial(t *testing.T) {
func TestPrintfVerbs(t *testing.T) {
x, _ := NewRR("www.miek.nl. IN A 127.0.0.1")
if fmt.Sprintf("%N", x) != "www.miek.nl." {
t.Errorf("%N does not return name")
t.Errorf("%%N does not return name")
}
if fmt.Sprintf("%C", x) != "IN" {
t.Errorf("%C does not return class")
t.Errorf("%%C does not return class")
}
if fmt.Sprintf("%D", x) != "3600" {
t.Errorf("%D does not return ttl")
t.Errorf("%%D does not return ttl")
}
if fmt.Sprintf("%Y", x) != "A" {
t.Errorf("%Y does not return type")
t.Errorf("%%Y does not return type")
}
if fmt.Sprintf("%Y %d", x, 5) != "A 5" {
t.Errorf("%N does not return name")
t.Errorf("%%N does not return name")
}
if fmt.Sprintf("%s", x) != "www.miek.nl.\t3600\tIN\tA\t127.0.0.1" {
t.Errorf("%s does return the correct string")
t.Errorf("%%s does return the correct string")
}
}
func TestPrintfVerbsRdata(t *testing.T) {
x, _ := NewRR("www.miek.nl. IN MX 20 mx.miek.nl.")
if Field(x, 1) != "20" {
t.Errorf("should be 20")
}
if Field(x, 2) != "mx.miek.nl." {
t.Errorf("should be mx.miek.nl.")
}
// TODO(miek): RDATA
}