dicom 0.9.5 → 0.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +13 -5
  2. data/{CHANGELOG.rdoc → CHANGELOG.md} +50 -30
  3. data/{CONTRIBUTING.rdoc → CONTRIBUTING.md} +16 -16
  4. data/Gemfile.lock +47 -0
  5. data/README.md +152 -0
  6. data/dicom.gemspec +11 -10
  7. data/lib/dicom.rb +30 -11
  8. data/lib/dicom/anonymizer.rb +654 -649
  9. data/lib/dicom/audit_trail.rb +0 -2
  10. data/lib/dicom/d_client.rb +1 -1
  11. data/lib/dicom/d_library.rb +45 -15
  12. data/lib/dicom/d_object.rb +18 -18
  13. data/lib/dicom/d_read.rb +28 -4
  14. data/lib/dicom/d_write.rb +49 -26
  15. data/lib/dicom/dictionary/{elements.txt → elements.tsv} +0 -0
  16. data/lib/dicom/dictionary/{uids.txt → uids.tsv} +0 -0
  17. data/lib/dicom/element.rb +6 -7
  18. data/lib/dicom/elemental.rb +1 -0
  19. data/lib/dicom/elemental_parent.rb +64 -0
  20. data/lib/dicom/extensions/array.rb +57 -0
  21. data/lib/dicom/extensions/hash.rb +31 -0
  22. data/lib/dicom/extensions/string.rb +126 -0
  23. data/lib/dicom/{constants.rb → general/constants.rb} +29 -38
  24. data/lib/dicom/{deprecated.rb → general/deprecated.rb} +0 -0
  25. data/lib/dicom/{logging.rb → general/logging.rb} +0 -0
  26. data/lib/dicom/{variables.rb → general/methods.rb} +0 -22
  27. data/lib/dicom/general/variables.rb +29 -0
  28. data/lib/dicom/{version.rb → general/version.rb} +1 -1
  29. data/lib/dicom/image_item.rb +0 -2
  30. data/lib/dicom/image_processor.rb +2 -0
  31. data/lib/dicom/item.rb +1 -13
  32. data/lib/dicom/link.rb +2 -1
  33. data/lib/dicom/parent.rb +34 -86
  34. data/lib/dicom/sequence.rb +1 -13
  35. data/lib/dicom/stream.rb +94 -114
  36. data/rakefile.rb +1 -1
  37. metadata +73 -36
  38. data/README.rdoc +0 -149
  39. data/lib/dicom/ruby_extensions.rb +0 -249
@@ -0,0 +1,31 @@
1
+ # Extensions to the Hash class used by the dicom gem.
2
+ #
3
+ class Hash
4
+
5
+ # Creates a gap in the integer keys at the specified index.
6
+ # This is achieved by incrementing by one all existing index keys that are equal or
7
+ # bigger than the given index.
8
+ #
9
+ # @note It is assumed that this hash features integers as keys and items as values!
10
+ # @param [Integer] index the index at which to clear
11
+ # @return [Hash] the modified self
12
+ #
13
+ def create_key_gap_at(index)
14
+ # Extract existing Hash entries to an array:
15
+ pairs = self.sort
16
+ h = Hash.new
17
+ # Change the key of those equal or larger than index and put these key,value pairs back in a new Hash:
18
+ pairs.each do |pair|
19
+ if pair[0] < index
20
+ # The key keeps its old index:
21
+ h[pair[0]] = pair[1]
22
+ else
23
+ # The key (and the value Item) gets its index incremented by one:
24
+ h[pair[0]+1] = pair[1]
25
+ pair[1].index = pair[0]+1
26
+ end
27
+ end
28
+ h
29
+ end
30
+
31
+ end
@@ -0,0 +1,126 @@
1
+ # encoding: UTF-8
2
+
3
+ # Extension to the String class. These mainly facilitate the processing and analysis of element tags.
4
+ # A tag string (as used by the ruby-dicom library) is 9 characters long and of the form 'GGGG,EEEE'
5
+ # (where G represents a group hexadecimal, and E represents an element hexadecimal).
6
+ #
7
+ class String
8
+
9
+ # Checks if a string value LOOKS like a DICOM name - it may still not be valid one.
10
+ #
11
+ # @return [Boolean] true if a string looks like a DICOM name, and false if not
12
+ #
13
+ def dicom_name?
14
+ self == self.dicom_titleize
15
+ end
16
+
17
+ # Checks if a string value LOOKS like a DICOM method name - it may still not be valid one.
18
+ #
19
+ # @return [Boolean] true if a string looks like a DICOM method name, and false if not
20
+ #
21
+ def dicom_method?
22
+ self == self.dicom_underscore
23
+ end
24
+
25
+ # Capitalizes all the words in the string and replaces some characters to make a nicer looking title.
26
+ #
27
+ # @return [String] a formatted, capitalized string
28
+ #
29
+ def dicom_titleize
30
+ self.dicom_underscore.gsub(/_/, ' ').gsub(/\b('?[a-z])/) { $1.capitalize }
31
+ end
32
+
33
+ # Makes an underscored, lowercased version of the string.
34
+ #
35
+ # @return [String] an underscored, lower case string
36
+ #
37
+ def dicom_underscore
38
+ word = self.dup
39
+ word.tr!('-', '_')
40
+ word.downcase!
41
+ word
42
+ end
43
+
44
+ # Divides a string into a number of sub-strings of exactly equal length.
45
+ #
46
+ # @note The length of self must be a multiple of parts, or an exception will be raised.
47
+ # @param [Integer] parts the number of sub-strings to create
48
+ # @return [Array<String>] the divided sub-strings
49
+ #
50
+ def divide(parts)
51
+ parts = parts.to_i
52
+ raise ArgumentError, "Argument must be in the range <1 - self.length (#{self.length})>. Got #{parts}." if parts < 1 or parts > self.length
53
+ raise ArgumentError, "Length of self (#{self.length}) must be a multiple of parts (#{parts})." if (self.length/parts.to_f % 1) != 0
54
+ sub_strings = Array.new
55
+ sub_length = self.length/parts
56
+ start_index = 0
57
+ parts.times {
58
+ sub_strings << self.slice(start_index, sub_length)
59
+ start_index += sub_length
60
+ }
61
+ sub_strings
62
+ end
63
+
64
+ # Extracts the element part of the tag string: The last 4 characters.
65
+ #
66
+ # @return [String] the element part of the tag
67
+ #
68
+ def element
69
+ return self[5..8]
70
+ end
71
+
72
+ # Returns the group part of the tag string: The first 4 characters.
73
+ #
74
+ # @return [String] the group part of the tag
75
+ #
76
+ def group
77
+ return self[0..3]
78
+ end
79
+
80
+ # Returns the "Group Length" ('GGGG,0000') tag which corresponds to the original tag/group string.
81
+ # The original string may either be a 4 character group string, or a 9 character custom tag.
82
+ #
83
+ # @return [String] a group length tag
84
+ #
85
+ def group_length
86
+ if self.length == 4
87
+ return self + ',0000'
88
+ else
89
+ return self.group + ',0000'
90
+ end
91
+ end
92
+
93
+ # Checks if the string is a "Group Length" tag (its element part is '0000').
94
+ #
95
+ # @return [Boolean] true if it is a group length tag, and false if not
96
+ #
97
+ def group_length?
98
+ return (self.element == '0000' ? true : false)
99
+ end
100
+
101
+ # Checks if the string is a private tag (has an odd group number).
102
+ #
103
+ # @return [Boolean] true if it is a private tag, and false if not
104
+ #
105
+ def private?
106
+ return ((self.upcase =~ /\A\h{3}[1,3,5,7,9,B,D,F],\h{4}\z/) == nil ? false : true)
107
+ end
108
+
109
+ # Checks if the string is a valid tag (as defined by ruby-dicom: 'GGGG,EEEE').
110
+ #
111
+ # @return [Boolean] true if it is a valid tag, and false if not
112
+ #
113
+ def tag?
114
+ # Test that the string is composed of exactly 4 HEX characters, followed by a comma, then 4 more HEX characters:
115
+ return ((self.upcase =~ /\A\h{4},\h{4}\z/) == nil ? false : true)
116
+ end
117
+
118
+ # Converts the string to a proper DICOM element method name symbol.
119
+ #
120
+ # @return [Symbol] a DICOM element method name
121
+ #
122
+ def to_element_method
123
+ self.gsub(/^3/,'three_').gsub(/[#*?!]/,' ').gsub(', ',' ').gsub('&','and').gsub(' - ','_').gsub(' / ','_').gsub(/[\s\-\.\,\/\\]/,'_').gsub(/[\(\)\']/,'').gsub(/\_+/, '_').downcase.to_sym
124
+ end
125
+
126
+ end
@@ -1,8 +1,5 @@
1
1
  module DICOM
2
2
 
3
- # Defines the gem root directory in the file system.
4
- ROOT_DIR = "#{File.dirname(__FILE__)}"
5
-
6
3
  # Ruby DICOM's registered DICOM UID root (Implementation Class UID).
7
4
  UID_ROOT = "1.2.826.0.1.3680043.8.641"
8
5
  # Ruby DICOM name & version (max 16 characters).
@@ -109,14 +106,6 @@ module DICOM
109
106
  # System (CPU) Endianness.
110
107
  CPU_ENDIAN = endian_type[Array(x).pack("L*")]
111
108
 
112
- # Custom string used for (un)packing big endian signed short.
113
- CUSTOM_SS = "k*"
114
- # Custom string used for (un)packing big endian signed long.
115
- CUSTOM_SL = "r*"
116
-
117
- # ruby-dicom's library instance (data dictionary).
118
- LIBRARY = DICOM::DLibrary.new
119
-
120
109
  # Transfer Syntaxes (taken from the DICOM Specification PS 3.5, Chapter 10).
121
110
 
122
111
  # General
@@ -184,36 +173,38 @@ module DICOM
184
173
  'GB18030' => 'GB18030',
185
174
  'ISO_IR 192' => 'UTF-8'
186
175
  }
176
+ ENCODING_NAME.default = 'ASCII-8BIT'
187
177
 
188
178
  # The type conversion (method) used for the various value representations.
189
179
  VALUE_CONVERSION = {
190
- 'BY' => :to_i,
191
- 'US' => :to_i,
192
- 'SS' => :to_i,
193
- 'UL' => :to_i,
194
- 'SL' => :to_i,
195
- 'OB' => :to_i,
196
- 'OW' => :to_i,
197
- 'OF' => :to_f,
198
- 'FL' => :to_f,
199
- 'FD' => :to_f,
200
- 'AT' => :to_s,
201
- 'AE' => :to_s,
202
- 'AS' => :to_s,
203
- 'CS' => :to_s,
204
- 'DA' => :to_s,
205
- 'DS' => :to_s,
206
- 'DT' => :to_s,
207
- 'IS' => :to_s,
208
- 'LO' => :to_s,
209
- 'LT' => :to_s,
210
- 'PN' => :to_s,
211
- 'SH' => :to_s,
212
- 'ST' => :to_s,
213
- 'TM' => :to_s,
214
- 'UI' => :to_s,
215
- 'UT' => :to_s
216
- }
180
+ 'BY' => :to_i,
181
+ 'US' => :to_i,
182
+ 'SS' => :to_i,
183
+ 'UL' => :to_i,
184
+ 'SL' => :to_i,
185
+ 'OB' => :to_i,
186
+ 'OW' => :to_i,
187
+ 'OF' => :to_f,
188
+ 'FL' => :to_f,
189
+ 'FD' => :to_f,
190
+ 'AT' => :to_s,
191
+ 'AE' => :to_s,
192
+ 'AS' => :to_s,
193
+ 'CS' => :to_s,
194
+ 'DA' => :to_s,
195
+ 'DS' => :to_s,
196
+ 'DT' => :to_s,
197
+ 'IS' => :to_s,
198
+ 'LO' => :to_s,
199
+ 'LT' => :to_s,
200
+ 'PN' => :to_s,
201
+ 'SH' => :to_s,
202
+ 'ST' => :to_s,
203
+ 'TM' => :to_s,
204
+ 'UI' => :to_s,
205
+ 'UT' => :to_s
206
+ }
207
+ VALUE_CONVERSION.default = :to_s
217
208
 
218
209
  end
219
210
 
@@ -2,17 +2,6 @@ module DICOM
2
2
 
3
3
  class << self
4
4
 
5
- #--
6
- # Module attributes:
7
- #++
8
-
9
- # The ruby-dicom image processor to be used.
10
- attr_accessor :image_processor
11
- # The key representation for hashes, json, yaml.
12
- attr_accessor :key_representation
13
- # Source Application Entity Title (gets written to the DICOM header in files where it is undefined).
14
- attr_accessor :source_app_title
15
-
16
5
  #--
17
6
  # Module methods:
18
7
  #++
@@ -91,15 +80,4 @@ module DICOM
91
80
 
92
81
  end
93
82
 
94
- #--
95
- # Default variable settings:
96
- #++
97
-
98
- # The default image processor.
99
- self.image_processor = :rmagick
100
- # The default key representation.
101
- self.key_representation = :name
102
- # The default source application entity title.
103
- self.source_app_title = 'RUBY-DICOM'
104
-
105
83
  end
@@ -0,0 +1,29 @@
1
+ module DICOM
2
+
3
+ class << self
4
+
5
+ #--
6
+ # Module attributes:
7
+ #++
8
+
9
+ # The ruby-dicom image processor to be used.
10
+ attr_accessor :image_processor
11
+ # The key representation for hashes, json, yaml.
12
+ attr_accessor :key_representation
13
+ # Source Application Entity Title (gets written to the DICOM header in files where it is undefined).
14
+ attr_accessor :source_app_title
15
+
16
+ end
17
+
18
+ #--
19
+ # Default variable settings:
20
+ #++
21
+
22
+ # The default image processor.
23
+ self.image_processor = :rmagick
24
+ # The default key representation.
25
+ self.key_representation = :name
26
+ # The default source application entity title.
27
+ self.source_app_title = 'RUBY-DICOM'
28
+
29
+ end
@@ -1,6 +1,6 @@
1
1
  module DICOM
2
2
 
3
3
  # The ruby-dicom version string.
4
- VERSION = '0.9.5'
4
+ VERSION = '0.9.6'
5
5
 
6
6
  end
@@ -119,7 +119,6 @@ module DICOM
119
119
  # image frames, the first image frame is returned, unless the :frame option is used.
120
120
  #
121
121
  # @note Creates an image object in accordance with the selected image processor. Available processors are :rmagick and :mini_magick.
122
- # @note When calling this method the corresponding image processor gem must have been loaded in advance (example: require 'RMagick').
123
122
  #
124
123
  # @param [Hash] options the options to use for extracting the image
125
124
  # @option options [Integer] :frame for DICOM objects containing multiple frames, this option can be used to extract a specific image frame (defaults to 0)
@@ -145,7 +144,6 @@ module DICOM
145
144
  # the image related elements in the DICOM object.
146
145
  #
147
146
  # @note Creates an array of image objects in accordance with the selected image processor. Available processors are :rmagick and :mini_magick.
148
- # @note When calling this method the corresponding image processor gem must have been loaded in advance (example: require 'RMagick').
149
147
  #
150
148
  # @param [Hash] options the options to use for extracting the images
151
149
  # @option options [Integer] :frame makes the method return an array containing only the image object corresponding to the specified frame number
@@ -66,8 +66,10 @@ module DICOM
66
66
  def image_module
67
67
  case DICOM.image_processor
68
68
  when :mini_magick
69
+ require 'mini_magick'
69
70
  DcmMiniMagick
70
71
  when :rmagick
72
+ require 'rmagick'
71
73
  DcmRMagick
72
74
  else
73
75
  raise "Uknown image processor #{DICOM.image_processor}"
@@ -9,8 +9,8 @@ module DICOM
9
9
  #
10
10
  class Item < ImageItem
11
11
 
12
- # Include the Elemental mix-in module:
13
12
  include Elemental
13
+ include ElementalParent
14
14
 
15
15
  # The index of this Item in the group of items belonging to its parent. If the Item is without parent, index is nil.
16
16
  attr_accessor :index
@@ -98,18 +98,6 @@ module DICOM
98
98
  state.hash
99
99
  end
100
100
 
101
- # Loads data from an encoded DICOM string and creates
102
- # sequences and elements which are linked to this instance.
103
- #
104
- # @param [String] bin an encoded binary string containing DICOM information
105
- # @param [String] syntax the transfer syntax to use when decoding the DICOM string
106
- #
107
- def parse(bin, syntax)
108
- raise ArgumentError, "Invalid argument 'bin'. Expected String, got #{bin.class}." unless bin.is_a?(String)
109
- raise ArgumentError, "Invalid argument 'syntax'. Expected String, got #{syntax.class}." unless syntax.is_a?(String)
110
- read(bin, signature=false, :syntax => syntax)
111
- end
112
-
113
101
  # Returns self.
114
102
  #
115
103
  # @return [Item] self
@@ -1426,6 +1426,7 @@ module DICOM
1426
1426
  response = IO.select([@session], nil, nil, @timeout)
1427
1427
  if response.nil?
1428
1428
  logger.error("No answer was received within the specified timeout period. Aborting.")
1429
+ stop_receiving
1429
1430
  else
1430
1431
  data = @session.recv(@max_receive_size)
1431
1432
  end
@@ -1486,7 +1487,7 @@ module DICOM
1486
1487
  if info[:role_negotiation]
1487
1488
  pos = 3
1488
1489
  info[:role_negotiation].each do |role|
1489
- msg = Stream.new(message, @net_endian)
1490
+ msg = Stream.new('', @net_endian)
1490
1491
  uid = role[:sop_uid]
1491
1492
  # Length of UID (2 bytes):
1492
1493
  msg.encode_first(uid.length, "US")
@@ -61,76 +61,6 @@ module DICOM
61
61
  end
62
62
  end
63
63
 
64
- # Adds a child item to a Sequence (or Item in some cases where pixel data is encapsulated).
65
- #
66
- # If no existing Item is given, a new item will be created and added.
67
- #
68
- # @note Items are specified by index (starting at 0) instead of a tag string!
69
- #
70
- # @param [Item] item the Item instance to be added
71
- # @param [Hash] options the options used for adding the item
72
- # option options [Integer] :if specified, forces the item to be inserted at that specific index (Item number)
73
- # option options [Boolean] :no_follow when true, the method does not update the parent attribute of the child that is added
74
- # * <tt>options</tt> -- A hash of parameters.
75
- # @example Add an empty Item to a specific Sequence
76
- # dcm["3006,0020"].add_item
77
- # @example Add an existing Item at the 2nd item position/index in the specific Sequence
78
- # dcm["3006,0020"].add_item(my_item, :index => 1)
79
- #
80
- def add_item(item=nil, options={})
81
- unless self.is_a?(DObject)
82
- if item
83
- if item.is_a?(Item)
84
- if options[:index]
85
- # This Item will take a specific index, and all existing Items with index higher or equal to this number will have their index increased by one.
86
- # Check if index is valid (must be an existing index):
87
- if options[:index] >= 0
88
- # If the index value is larger than the max index present, we dont need to modify the existing items.
89
- if options[:index] < @tags.length
90
- # Extract existing Hash entries to an array:
91
- pairs = @tags.sort
92
- @tags = Hash.new
93
- # Change the key of those equal or larger than index and put these key,value pairs back in a new Hash:
94
- pairs.each do |pair|
95
- if pair[0] < options[:index]
96
- @tags[pair[0]] = pair[1] # (Item keeps its old index)
97
- else
98
- @tags[pair[0]+1] = pair[1]
99
- pair[1].index = pair[0]+1 # (Item gets updated with its new index)
100
- end
101
- end
102
- else
103
- # Set the index value one higher than the already existing max value:
104
- options[:index] = @tags.length
105
- end
106
- #,Add the new Item and set its index:
107
- @tags[options[:index]] = item
108
- item.index = options[:index]
109
- else
110
- raise ArgumentError, "The specified index (#{options[:index]}) is out of range (Must be a positive integer)."
111
- end
112
- else
113
- # Add the existing Item to this Sequence:
114
- index = @tags.length
115
- @tags[index] = item
116
- # Let the Item know what index key it's got in it's parent's Hash:
117
- item.index = index
118
- end
119
- # Set ourself as this item's new parent:
120
- item.set_parent(self) unless options[:no_follow]
121
- else
122
- raise ArgumentError, "The specified parameter is not an Item. Only Items are allowed to be added to a Sequence."
123
- end
124
- else
125
- # Create an empty Item with self as parent.
126
- index = @tags.length
127
- item = Item.new(:parent => self)
128
- end
129
- else
130
- raise "An Item #{item} was attempted added to a DObject instance #{self}, which is not allowed."
131
- end
132
- end
133
-
134
64
  # Retrieves all (immediate) child elementals in an array (sorted by element tag).
135
65
  #
136
66
  # @return [Array<Element, Item, Sequence>] the parent's child elementals (an empty array if childless)
@@ -196,12 +126,7 @@ module DICOM
196
126
  # dcm["3006,0020"].delete(1)
197
127
  #
198
128
  def delete(tag_or_index, options={})
199
- if tag_or_index.is_a?(String) or tag_or_index.is_a?(Integer)
200
- raise ArgumentError, "Argument (#{tag_or_index}) is not a valid tag string." if tag_or_index.is_a?(String) && !tag_or_index.tag?
201
- raise ArgumentError, "Negative Integer argument (#{tag_or_index}) is not allowed." if tag_or_index.is_a?(Integer) && tag_or_index < 0
202
- else
203
- raise ArgumentError, "Expected String or Integer, got #{tag_or_index.class}."
204
- end
129
+ check_key(tag_or_index, :delete)
205
130
  # We need to delete the specified child element's parent reference in addition to removing it from the tag Hash.
206
131
  element = self[tag_or_index]
207
132
  if element
@@ -528,13 +453,15 @@ module DICOM
528
453
  # @param [Symbol] sym a method name
529
454
  #
530
455
  def method_missing(sym, *args, &block)
456
+ s = sym.to_s
457
+ action = s[-1]
531
458
  # Try to match the method against a tag from the dictionary:
532
- tag = LIBRARY.as_tag(sym.to_s) || LIBRARY.as_tag(sym.to_s[0..-2])
459
+ tag = LIBRARY.as_tag(s) || LIBRARY.as_tag(s[0..-2])
533
460
  if tag
534
- if sym.to_s[-1..-1] == '?'
461
+ if action == '?'
535
462
  # Query:
536
463
  return self.exists?(tag)
537
- elsif sym.to_s[-1..-1] == '='
464
+ elsif action == '='
538
465
  # Assignment:
539
466
  unless args.length==0 || args[0].nil?
540
467
  # What kind of element to create?
@@ -550,7 +477,7 @@ module DICOM
550
477
  end
551
478
  else
552
479
  # Retrieval:
553
- return self[tag] rescue nil
480
+ return self[tag]
554
481
  end
555
482
  end
556
483
  # Forward to Object#method_missing:
@@ -595,6 +522,16 @@ module DICOM
595
522
  return elements
596
523
  end
597
524
 
525
+ # Gives a string which represents this DICOM parent. The DOBject is
526
+ # is represented by its class name, whereas elemental parents (Sequence,
527
+ # Item) is represented by their tags.
528
+ #
529
+ # @return [String] a representation of the DICOM parent
530
+ #
531
+ def representation
532
+ self.is_a?(DObject) ? 'DObject' : self.tag
533
+ end
534
+
598
535
  # Resets the length of a Sequence or Item to -1, which is the number used for 'undefined' length.
599
536
  #
600
537
  def reset_length
@@ -701,12 +638,7 @@ module DICOM
701
638
  # uid = dcm["3006,0010"][0].value("0020,0052")
702
639
  #
703
640
  def value(tag)
704
- if tag.is_a?(String) or tag.is_a?(Integer)
705
- raise ArgumentError, "Argument (#{tag}) is not a valid tag string." if tag.is_a?(String) && !tag.tag?
706
- raise ArgumentError, "Negative Integer argument (#{tag}) is not allowed." if tag.is_a?(Integer) && tag < 0
707
- else
708
- raise ArgumentError, "Expected String or Integer, got #{tag.class}."
709
- end
641
+ check_key(tag, :value)
710
642
  if exists?(tag)
711
643
  if self[tag].is_parent?
712
644
  raise ArgumentError, "Illegal parameter '#{tag}'. Parent elements, like the referenced '#{@tags[tag].class}', have no value. Only Element tags are valid."
@@ -722,6 +654,22 @@ module DICOM
722
654
  private
723
655
 
724
656
 
657
+ # Checks the given key argument and logs a warning if an obviously
658
+ # incorrect key argument is used.
659
+ #
660
+ # @param [String, Integer] tag_or_index the tag string or item index indentifying a given elemental
661
+ # @param [Symbol] method a representation of the method calling this method
662
+ #
663
+ def check_key(tag_or_index, method)
664
+ if tag_or_index.is_a?(String)
665
+ logger.warn("Parent##{method} called with an invalid tag argument: #{tag_or_index}") unless tag_or_index.tag?
666
+ elsif tag_or_index.is_a?(Integer)
667
+ logger.warn("Parent##{method} called with a negative Integer argument: #{tag_or_index}") if tag_or_index < 0
668
+ else
669
+ logger.warn("Parent##{method} called with an unexpected argument. Expected String or Integer, got: #{tag_or_index.class}")
670
+ end
671
+ end
672
+
725
673
  # Re-encodes the value of a child Element (but only if the
726
674
  # Element encoding is influenced by a shift in endianness).
727
675
  #