diff --git a/xml.go b/xml.go index 6d8a54d..0cb7bf5 100644 --- a/xml.go +++ b/xml.go @@ -13,15 +13,15 @@ const ( ) type RootDevice struct { - URLBase *url.URL `xml:"-"` Name xml.Name `xml:"root` SpecVersion SpecVersion `xml:"specVersion"` + URLBase url.URL `xml:"-"` URLBaseStr string `xml:"URLBase"` Device *Device `xml:"device"` } func (root *RootDevice) SetURLBase(urlBase *url.URL) { - root.URLBase = urlBase + root.URLBase = *urlBase root.URLBaseStr = urlBase.String() root.Device.SetURLBase(urlBase) } @@ -32,15 +32,14 @@ type SpecVersion struct { } type Device struct { - URLBase *url.URL `xml:"-"` DeviceType string `xml:"deviceType"` FriendlyName string `xml:"friendlyName"` Manufacturer string `xml:"manufacturer"` - ManufacturerURL string `xml:"manufacturerURL"` + ManufacturerURL URLField `xml:"manufacturerURL"` ModelDescription string `xml:"modelDescription"` ModelName string `xml:"modelName"` ModelNumber string `xml:"modelNumber"` - ModelURL string `xml:"modelURL"` + ModelURL URLField `xml:"modelURL"` SerialNumber string `xml:"serialNumber"` UDN string `xml:"UDN"` UPC string `xml:"UPC,omitempty"` @@ -49,11 +48,15 @@ type Device struct { Devices []*Device `xml:"deviceList>device,omitempty"` // Extra observed elements: - PresentationURL string `xml:"presentationURL"` + PresentationURL URLField `xml:"presentationURL"` } func (device *Device) SetURLBase(urlBase *url.URL) { - device.URLBase = urlBase + device.ManufacturerURL.SetURLBase(urlBase) + device.ModelURL.SetURLBase(urlBase) + for _, icon := range device.Icons { + icon.SetURLBase(urlBase) + } for _, srv := range device.Services { srv.SetURLBase(urlBase) } @@ -67,26 +70,49 @@ func (device *Device) String() string { } type Icon struct { - Mimetype string `xml:"mimetype"` - Width int32 `xml:"width"` - Height int32 `xml:"height"` - Depth int32 `xml:"depth"` - URL string `xml:"url"` + Mimetype string `xml:"mimetype"` + Width int32 `xml:"width"` + Height int32 `xml:"height"` + Depth int32 `xml:"depth"` + URL URLField `xml:"url"` +} + +func (icon *Icon) SetURLBase(url *url.URL) { + icon.URL.SetURLBase(url) } type Service struct { - URLBase *url.URL `xml:"-"` ServiceType string `xml:"serviceType"` ServiceId string `xml:"serviceId"` - SCPDURL string `xml:"SCPDURL"` - ControlURL string `xml:"controlURL"` - EventSubURL string `xml:"eventSubURL"` + SCPD URLField `xml:"SCPDURL"` + Control URLField `xml:"controlURL"` + EventSub URLField `xml:"eventSubURL"` } func (srv *Service) SetURLBase(urlBase *url.URL) { - srv.URLBase = urlBase + srv.SCPD.SetURLBase(urlBase) + srv.Control.SetURLBase(urlBase) + srv.EventSub.SetURLBase(urlBase) } func (srv *Service) String() string { return fmt.Sprintf("Service ID %s : %s", srv.ServiceId, srv.ServiceType) } + +type URLField struct { + URL url.URL `xml:"-"` + Ok bool `xml:"-"` + Str string `xml:",chardata"` +} + +func (uf *URLField) SetURLBase(urlBase *url.URL) { + refUrl, err := url.Parse(uf.Str) + if err != nil { + uf.URL = url.URL{} + uf.Ok = false + return + } + + uf.URL = *urlBase.ResolveReference(refUrl) + uf.Ok = true +}