Class: Xap::XapAddress
- Inherits:
-
Object
- Object
- Xap::XapAddress
- Defined in:
- lib/xap/xap_address.rb
Overview
Represents an xAP address. Matching is case-insensitive.
Wildcard characters supported: * and >. * matches anything within a subsection, but will not match across . or : (e.g. a.*.c will match a.b.c but not a.b.d.c). * must occur by itself in a subsection (e.g. *.a.b and a.*.b are OK, but ab*.c*d.*e is not). > matches anything to the end of the section if specified before a :, or anything to the end of an address being tested if at the end of the wildcarded address.
Instance Attribute Summary collapse
-
#basewildcard ⇒ Object
Returns the value of attribute basewildcard.
-
#endpoint ⇒ Object
Returns the value of attribute endpoint.
-
#epwildcard ⇒ Object
Returns the value of attribute epwildcard.
-
#instance ⇒ Object
Returns the value of attribute instance.
-
#product ⇒ Object
Returns the value of attribute product.
-
#vendor ⇒ Object
Returns the value of attribute vendor.
-
#wildcard ⇒ Object
Returns the value of attribute wildcard.
Class Method Summary collapse
-
.parse(addr) ⇒ Object
Parses the given address string into an XapAddress.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Returns true if all fields are == when converted to lowercase.
-
#=~(other) ⇒ Object
(also: #match)
Returns true if other == self or self is a wildcard address that matches other (which may either be an XapAddress or anything that can be converted to a String with to_s).
-
#base ⇒ Object
Returns an XapAddress that contains the base of this address with no endpoint.
-
#base_match(other) ⇒ Object
Returns true if this address’s base components (i.e. everything before the colon) match the base components of the given other address.
-
#endpoint_match(other) ⇒ Object
Returns true if this address’s endpoint matches the endpoint of the given other address.
-
#for_endpoint(ep_name) ⇒ Object
Returns a new XapAddress that contains this address’s base components with the given endpoint.
-
#initialize(vendor, product, instance, endpoint = nil) ⇒ XapAddress
constructor
vendor - xAP-assigned vendor ID (e.g. ACME) product - vendor-assigned product name (e.g. Controller) instance - user-assigned product instance (e.g. Apartment) endpoint - user- or device-assigned name (e.g. Zone1), or nil.
-
#to_s ⇒ Object
Returns a correctly-formatted string representation of the address, suitable for inclusion in an xAP message.
-
#wildcard? ⇒ Boolean
Whether this address is a wildcard address.
Constructor Details
#initialize(vendor, product, instance, endpoint = nil) ⇒ XapAddress
vendor - xAP-assigned vendor ID (e.g. ACME) product - vendor-assigned product name (e.g. Controller) instance - user-assigned product instance (e.g. Apartment) endpoint - user- or device-assigned name (e.g. Zone1), or nil
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 |
# File 'lib/xap/xap_address.rb', line 52 def initialize vendor, product, instance, endpoint=nil # This would be a nice application of macros (e.g. "check_type var, String") raise 'vendor must be (convertible to) a String' unless vendor.respond_to? :to_s raise 'product must be (convertible to) a String' unless product.respond_to? :to_s raise 'instance must be (convertible to) a String' unless instance.respond_to? :to_s raise 'endpoint must be (convertible to) a String' unless endpoint.respond_to? :to_s # TODO: Validate characters in the address @vendor = vendor.to_s @product = product.to_s @instance = instance.to_s @endpoint = endpoint ? endpoint.to_s : nil # Many of the xAP standard's own examples violate the length limits... #raise 'vendor is too long' if @vendor.length > 8 #raise 'product is too long' if @product.length > 8 # Build the string representation of this address @str = "#{@vendor}.#{@product}.#{@instance}" @str << ":#{@endpoint}" if @endpoint # Build a regex for matching wildcarded addresses raise "Address #{@str} contains * in the middle of a word" if @str =~ /([^.:]\*)|(\*[^.:])/ raise "Address #{@str} contains > not at the end of a section" if @str =~ />(?!\:|$)/ @regex, @wildcard = build_regex @str @baseregex, @basewildcard = build_regex("#{@vendor}.#{@product}.#{@instance}") if @endpoint @epregex, @epwildcard = build_regex(@endpoint) elsif @str.end_with? '>' # FIXME: I believe xAP wildcard addresses are supposed to treat . and : indistinguishably @epregex = // @epwildcard = true else @epregex = /^$/ @epwildcard = false end end |
Instance Attribute Details
#basewildcard ⇒ Object
Returns the value of attribute basewildcard.
14 15 16 |
# File 'lib/xap/xap_address.rb', line 14 def basewildcard @basewildcard end |
#endpoint ⇒ Object
Returns the value of attribute endpoint.
14 15 16 |
# File 'lib/xap/xap_address.rb', line 14 def endpoint @endpoint end |
#epwildcard ⇒ Object
Returns the value of attribute epwildcard.
14 15 16 |
# File 'lib/xap/xap_address.rb', line 14 def epwildcard @epwildcard end |
#instance ⇒ Object
Returns the value of attribute instance.
14 15 16 |
# File 'lib/xap/xap_address.rb', line 14 def instance @instance end |
#product ⇒ Object
Returns the value of attribute product.
14 15 16 |
# File 'lib/xap/xap_address.rb', line 14 def product @product end |
#vendor ⇒ Object
Returns the value of attribute vendor.
14 15 16 |
# File 'lib/xap/xap_address.rb', line 14 def vendor @vendor end |
#wildcard ⇒ Object
Returns the value of attribute wildcard.
14 15 16 |
# File 'lib/xap/xap_address.rb', line 14 def wildcard @wildcard end |
Class Method Details
.parse(addr) ⇒ Object
Parses the given address string into an XapAddress. If addr is nil, returns nil.
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 |
# File 'lib/xap/xap_address.rb', line 18 def self.parse addr return nil unless addr raise 'addr must be a String' unless addr.is_a? String # As far as I can tell, the xAP spec isn't very clear on how # long an address can be, whether the subaddress is specified # by a colon or a period, etc. # # This section says that both instance and subaddr can have any depth # http://www.xapautomation.org/index.php?title=Protocol_definition#Message_Addressing_Schemes # # This section has additional information on addresses # (including vendor and device length limits of 8 characters, # which are broken in many of the xAP BSC examples...) # http://www.xapautomation.org/index.php?title=Protocol_definition#Message_Header_Structure # # This section makes the distinction between : and . less clear # http://www.xapautomation.org/index.php?title=Protocol_definition#Wildcarding_of_Addresses_via_Header # # Here's documentation for an xAP plugin for some other # software that ignores the UID rules entirely and uses the > # wildcard character in the middle of an address # http://www.erspearson.com/xAP/Slim/Manual.html#id616380 tokens = addr.strip.split ':', 2 addr = tokens[0].split '.', 3 subaddr = tokens[1] self.new addr[0], addr[1], addr[2], subaddr end |
Instance Method Details
#==(other) ⇒ Object
Returns true if all fields are == when converted to lowercase
93 94 95 96 97 98 99 |
# File 'lib/xap/xap_address.rb', line 93 def == other if other.is_a? XapAddress other.to_s.downcase == to_s.downcase else false end end |
#=~(other) ⇒ Object Also known as: match
Returns true if other == self or self is a wildcard address that matches other (which may either be an XapAddress or anything that can be converted to a String with to_s). Note that (self =~ other) != (other =~ self).
105 106 107 |
# File 'lib/xap/xap_address.rb', line 105 def =~ other other == self || (other.to_s =~ @regex) == 0 end |
#base ⇒ Object
Returns an XapAddress that contains the base of this address with no endpoint. Wildcards in the base address components are preserved.
112 113 114 |
# File 'lib/xap/xap_address.rb', line 112 def base XapAddress.new @vendor, @product, @instance end |
#base_match(other) ⇒ Object
Returns true if this address’s base components (i.e. everything before the colon) match the base components of the given other address. If matching a wildcarded address, call this on the wildcarded address (e.g. wild.base_match(other) rather than other.base_match(wild).
127 128 129 |
# File 'lib/xap/xap_address.rb', line 127 def base_match other other.base.to_s =~ @baseregex end |
#endpoint_match(other) ⇒ Object
Returns true if this address’s endpoint matches the endpoint of the given other address. If other is a String, then it will be matched as if it were an XapAddress endpoint.
134 135 136 137 138 139 140 141 142 |
# File 'lib/xap/xap_address.rb', line 134 def endpoint_match other if other.is_a? String other =~ @epregex elsif other.respond_to?(:endpoint) other.endpoint =~ @epregex else false end end |
#for_endpoint(ep_name) ⇒ Object
Returns a new XapAddress that contains this address’s base components with the given endpoint.
118 119 120 |
# File 'lib/xap/xap_address.rb', line 118 def for_endpoint ep_name XapAddress.new @vendor, @product, @instance, ep_name end |
#to_s ⇒ Object
Returns a correctly-formatted string representation of the address, suitable for inclusion in an xAP message.
146 147 148 |
# File 'lib/xap/xap_address.rb', line 146 def to_s @str end |
#wildcard? ⇒ Boolean
Whether this address is a wildcard address.
151 152 153 |
# File 'lib/xap/xap_address.rb', line 151 def wildcard? @wildcard end |