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.
91 92 93 |
# File 'lib/cztop/metadata.rb', line 91 def initialize(properties) @properties = properties end |
Class Method Details
.dump(metadata) ⇒ String
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/cztop/metadata.rb', line 35 def self.dump() ic_names = Set.new .map do |k, v| ic_name = k.to_sym.downcase raise ArgumentError, "property #{k.inspect}: duplicate name" if ic_names.include? ic_name ic_names << ic_name name = k.to_s raise ArgumentError, "property #{k.inspect}: invalid name" if NAME_REGEX !~ name value = v.to_s raise ArgumentError, "property #{k.inspect}: value too long" if value.bytesize > VALUE_MAXLEN [name.size, name, value.bytesize, value].pack('CA*NA*') end.join end |
.load(data) ⇒ Hash
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 |
# File 'lib/cztop/metadata.rb', line 57 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).unpack1('C') # 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 raise InvalidData, "property #{name.inspect}: duplicate name" if properties.key?(name_sym) consumed += 1 + name.bytesize # read property value value_length = data.byteslice(consumed, 4).unpack1('N') 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.
100 101 102 |
# File 'lib/cztop/metadata.rb', line 100 def [](name) @properties[name.to_sym.downcase] end |
#to_h ⇒ Hash<Symbol, String] all properties
Returns Hash<Symbol, String] all properties.
106 107 108 |
# File 'lib/cztop/metadata.rb', line 106 def to_h @properties end |