Class: RightScale::Platform::PlatformHelperBase
- Defined in:
- lib/right_agent/platform.rb,
lib/right_agent/platform/windows/platform.rb,
lib/right_agent/platform/windows/mingw/platform.rb,
lib/right_agent/platform/windows/mswin/platform.rb
Overview
helpers
Direct Known Subclasses
Controller, Filesystem, Installer, Process, Rng, Shell, VolumeManager, WindowsCommon, WindowsSecurity, WindowsSystemInformation
Constant Summary collapse
- SIZEOF_DWORD =
constants
4
- SIZEOF_QWORD =
double-word
8
- WIDE =
_W (i.e. ‘wide’) Windows APIs all use little-endian unicode.
_A doesn’t correspond to any particular single/multi-byte encoding (even though n00bs get confused and think in means ASCII). _A actually means ‘use the current codepage’ for which you would need to make another API call to discover what the current thread thinks is the current codepage.
::Encoding::UTF_16LE
- API_NULL =
0
- API_FALSE =
0
- API_TRUE =
1
Instance Method Summary collapse
-
#copy_to_string_buffer(source_buffer, target_buffer, options = {}) ⇒ Integer
Performs a bytewise copy to given target buffer with respect for the encoding of the source and target buffers.
-
#with_unicode_buffer(buffer, copy_options = {}) {|buffer| ... } ⇒ String
We favor the _W APIs to ensure proper marshalling of Unicode characters to/from the ruby interpreter’s default codepage.
Instance Method Details
#copy_to_string_buffer(source_buffer, target_buffer, options = {}) ⇒ Integer
Performs a bytewise copy to given target buffer with respect for the encoding of the source and target buffers. Assumes a NUL terminator appears in the string to be copied per normal Windows API behavor.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/right_agent/platform/windows/mingw/platform.rb', line 104 def copy_to_string_buffer(source_buffer, target_buffer, = {}) = { :truncate => false }.merge() # note that a buffer of NULs will default to ASCII encoding in # ruby 1.9 so change to use default encoding automagically. this makes # it easier to support the default codepage in 1.9 but be oblivious to # it in 1.8, which does not support these encoding methods. if the # caller wants any other codepage (in 1.9) then it should be specified # on the target. if target_buffer.encoding == Encoding::ASCII # we can force encoding only if the default encoding is ASCII # compatible. we are going to clobber the bytes so the old bytes are # irrelevant unless the bytesize of the buffer would differ. if ::Encoding.default_external.ascii_compatible? # note that force_encoding modifies self even though it's not a # banged! method. target_buffer.force_encoding(::Encoding.default_external) else target_buffer.encode!(::Encoding.default_external) end end # reencode the source buffer, changing any characters that cannot be # encoded to the default replacement character, which is usually '?' target_encoding = target_buffer.encoding reencoded_source_buffer = source_buffer.encode( target_encoding, :invalid => :replace, :undef => :replace) # determine if sufficient buffer exists. result = nil nul_char = 0.chr.encode(target_encoding) reencoded_source_length = reencoded_source_buffer.index(nul_char) || reencoded_source_buffer.length if reencoded_source_length <= target_buffer.length || [:truncate] # bytewise replacement (to reuse caller's buffer instead of # reallocating the string's buffer). copy_length = [reencoded_source_length, target_buffer.length - 1].min copy_byte_count = nul_char.bytesize * copy_length reencoded_source_buffer.bytes.each_with_index do |b, b_index| break if b_index >= copy_byte_count target_buffer.setbyte(b_index, b) end target_buffer[copy_length] = nul_char result = copy_length else result = reencoded_source_length end result end |
#with_unicode_buffer(buffer, copy_options = {}) {|buffer| ... } ⇒ String
We favor the _W APIs to ensure proper marshalling of Unicode characters to/from the ruby interpreter’s default codepage. This method facilitates API calls that fill a Unicode buffer and need to marshal the buffered data to a multi-byte (default encoding) buffer.
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/right_agent/platform/windows/mingw/platform.rb', line 61 def with_unicode_buffer(buffer, = {}) # note that _W methods always expect UTF-16 LE (Little Endian) due to # the Intel chipset representing word values as LE. Windows runs on # other chipsets but LE is always used by API calls. if buffer && buffer.encoding != WIDE unicode_buffer = 0.chr.encode(WIDE) * buffer.size unicode_length_or_buffer_count = yield(unicode_buffer) if unicode_length_or_buffer_count > 0 && unicode_length_or_buffer_count < unicode_buffer.size # reencode to non-Unicode buffer, including trailing NUL character. # # note that reencoding may exceed given (Unicode) buffer size # because of two-byte chars expanded from single unicode chars. # in this case the required multi-byte buffer size will be returned # and then promoted to a 'doubled' Unicode buffer size on next call. result = copy_to_string_buffer( unicode_buffer[0, unicode_length_or_buffer_count + 1], buffer, ) else result = unicode_length_or_buffer_count end else # buffer is already UTF-16LE or else nil result = yield(buffer) end result end |