Module: Denko::Message
- Defined in:
- lib/denko/message.rb
Constant Summary collapse
- BYTE_MAX =
255- VAL_MIN =
0- VAL_MAX =
9999
Class Method Summary collapse
- .encode(command: nil, pin: nil, value: nil, aux_message: nil) ⇒ Object
- .pack(type, data, options = {}) ⇒ Object
Class Method Details
.encode(command: nil, pin: nil, value: nil, aux_message: nil) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 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 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/denko/message.rb', line 7 def self.encode(command: nil, pin: nil, value: nil, aux_message: nil) # Start building message backwards with aux_message first. if # Convert it to String. = .to_s # Validate aux_message before escaping characters. raise ArgumentError, 'aux_message is limited to 528 characters' if .length > 528 # Escape \ and \n. = .gsub("\\","\\\\\\\\").gsub("\n", "\\\n") # Start message with aux_message. = ".#{aux_message}" else # Or start with empty message. = "" end # Prepend value if value # Validate value if (value.class != Integer || value < VAL_MIN || value > VAL_MAX) raise ArgumentError, "value must be integer in range #{VAL_MIN} to #{VAL_MAX}" end = ".#{value}#{message}" elsif !.empty? = ".#{message}" end # Prepend pin if pin # Validate pin if (pin.class != Integer || pin < 0 || pin > BYTE_MAX) raise ArgumentError, 'pin must be integer in range 0 to 255' end = ".#{pin}#{message}" elsif !.empty? = ".#{message}" end # Validate command raise ArgumentError, 'command missing from message' unless command if command.class != Integer || command < 0 || command > BYTE_MAX raise ArgumentError, 'command must be Integer in range 0 to 255' end # Prepend command and append newline. = "#{command}#{message}\n" end |
.pack(type, data, options = {}) ⇒ Object
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/denko/message.rb', line 60 def self.pack(type, data, ={}) # Always pack as little endian. template = case type when :uint64 then 'Q<*' when :uint32 then 'L<*' when :uint16 then 'S<*' when :uint8 then 'C*' else raise ArgumentError, "unsupported pack format '#{type}'" end # Can pass a single integer to get packed if we always [] then flatten. str = [data].flatten.pack(template) # Pad right with null bytes if asked. if [:pad] && [:pad] > str.length ([:pad] - str.length).times do str = str + "\x00" end end if [:min] && str.length < [:min] raise ArgumentError, "too few bytes given (expected at least #{options[:min]})" end # Max should probably always be set to avoid overruning aux message RAM. if [:max] && str.length > [:max] raise ArgumentError, "too many bytes given (expected at most #{options[:max]})" end str end |