Class: CZTop::Metadata
- Inherits:
-
Object
- Object
- CZTop::Metadata
- Defined in:
- lib/cztop/metadata.rb
Overview
Useful to encode and decode metadata as defined by ZMTP.
ABNF:
metadata = *property
property = name value
name = OCTET 1*255name-char
name-char = ALPHA | DIGIT | "-" | "_" | "." | "+"
value = 4OCTET *OCTET ; Size in network byte order
Defined Under Namespace
Classes: InvalidData
Constant Summary collapse
- VALUE_MAXLEN =
2**31-1
- NAME_REGEX =
regular expression used to validate property names
/\A[[:alnum:]_.+-]{1,255}\Z/.freeze
Class Method Summary collapse
Instance Method Summary collapse
-
#[](name) ⇒ String
Gets the value corresponding to a property name.
-
#initialize(properties) ⇒ Metadata
constructor
A new instance of Metadata.
-
#to_h ⇒ Hash<Symbol, String] all properties
Hash<Symbol, String] all properties.
Constructor Details
#initialize(properties) ⇒ Metadata
Returns a new instance of Metadata.
83 84 85 |
# File 'lib/cztop/metadata.rb', line 83 def initialize(properties) @properties = properties end |
Class Method Details
.dump(metadata) ⇒ String
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/cztop/metadata.rb', line 30 def self.dump() ic_names = Set.new .map do |k, v| ic_name = k.to_sym.downcase if ic_names.include?(ic_name) raise ArgumentError, "property #{k.inspect}: duplicate name" else ic_names << ic_name end name = k.to_s if NAME_REGEX !~ name raise ArgumentError, "property #{k.inspect}: invalid name" end value = v.to_s if value.bytesize > VALUE_MAXLEN raise ArgumentError, "property #{k.inspect}: value too long" end [name.size, name, value.bytesize, value].pack("CA*NA*") end.join end |
.load(data) ⇒ Hash
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 |
# File 'lib/cztop/metadata.rb', line 53 def self.load(data) properties = {} consumed = 0 while consumed < data.bytesize # while there are bytes to read # read property name name_length = data.byteslice(consumed).unpack("C").first # never nil raise InvalidData, "zero-length property name" if name_length.zero? name = data.byteslice(consumed + 1, name_length) raise InvalidData, "incomplete name" if name.bytesize != name_length name_sym = name.to_sym.downcase if properties.has_key?(name_sym) raise InvalidData, "property #{name.inspect}: duplicate name" end consumed += 1 + name.bytesize # read property value value_length = data.byteslice(consumed, 4).unpack("N").first or raise InvalidData, "incomplete length" value = data.byteslice(consumed + 4, value_length) raise InvalidData, "incomplete value" if value.bytesize != value_length consumed += 4 + value.bytesize # remember properties[name_sym] = value end new(properties) end |
Instance Method Details
#[](name) ⇒ String
Gets the value corresponding to a property name. The case of the name is insignificant.
91 92 93 |
# File 'lib/cztop/metadata.rb', line 91 def [](name) @properties[name.to_sym.downcase] end |
#to_h ⇒ Hash<Symbol, String] all properties
Returns Hash<Symbol, String] all properties.
96 97 98 |
# File 'lib/cztop/metadata.rb', line 96 def to_h @properties end |