note description: "UTF-16 encoding routines" library: "Gobo Eiffel Kernel Library" copyright: "Copyright (c) 2002-2018, Eric Bezault and others" license: "MIT License" date: "$Date: 2019-02-07 22:54:15 +0000 (Thu, 07 Feb 2019) $" revision: "$Revision: 102807 $" class UC_UTF16_ROUTINES create default_create feature {NONE} -- Initialization default_create -- Process instances of classes with no creation clause. -- (Default: do nothing.) -- (from ANY) do end feature -- Access Any_: KL_ANY_ROUTINES -- Routines that ought to be in class ANY -- (from KL_IMPORTED_ANY_ROUTINES) once create Result ensure -- from KL_IMPORTED_ANY_ROUTINES instance_free: class any_routines_not_void: Result /= Void end Canonical_decomposition_mapping: INTEGER_32 = 0 -- Decomposition mapping is canonical -- (from UC_UNICODE_CONSTANTS) Close_punctuation_category: INTEGER_32 = 15 -- Close punctuation -- (from UC_UNICODE_CONSTANTS) Compatibility_decomposition_mapping: INTEGER_32 = 16 -- Decomposition mapping for unspecified compatibility character -- (from UC_UNICODE_CONSTANTS) Connector_punctuation_category: INTEGER_32 = 12 -- Connector punctuation -- (from UC_UNICODE_CONSTANTS) Control_other_category: INTEGER_32 = 26 -- Control character -- (from UC_UNICODE_CONSTANTS) Currency_symbol_category: INTEGER_32 = 20 -- Currency symbol -- (from UC_UNICODE_CONSTANTS) Dash_punctuation_category: INTEGER_32 = 13 -- Dash punctuation -- (from UC_UNICODE_CONSTANTS) Decimal_digit_number_category: INTEGER_32 = 9 -- Decimal digit number -- (from UC_UNICODE_CONSTANTS) Encircled_decomposition_mapping: INTEGER_32 = 7 -- Decomposition mapping for encircled form -- (from UC_UNICODE_CONSTANTS) Enclosing_mark_category: INTEGER_32 = 8 -- Enclosing mark -- (from UC_UNICODE_CONSTANTS) Final_decomposition_mapping: INTEGER_32 = 5 -- Decomposition mapping for Arabic final presentation form -- (from UC_UNICODE_CONSTANTS) Final_quote_punctuation_category: INTEGER_32 = 17 -- Final_quote punctuation -- (from UC_UNICODE_CONSTANTS) Font_decomposition_mapping: INTEGER_32 = 1 -- Decomposition mapping for font variant -- (from UC_UNICODE_CONSTANTS) Format_other_category: INTEGER_32 = 27 -- Format character -- (from UC_UNICODE_CONSTANTS) Fraction_decomposition_mapping: INTEGER_32 = 15 -- Decomposition mapping for vulgar fraction form -- (from UC_UNICODE_CONSTANTS) generating_type: TYPE [detachable UC_UTF16_ROUTINES] -- Type of current object -- (type of which it is a direct instance) -- (from ANY) external "built_in" ensure -- from ANY generating_type_not_void: Result /= Void end generator: STRING_8 -- Name of current object's generating class -- (base class of the type of which it is a direct instance) -- (from ANY) external "built_in" ensure -- from ANY generator_not_void: Result /= Void generator_not_empty: not Result.is_empty end Initial_decomposition_mapping: INTEGER_32 = 3 -- Decomposition mapping for Arabic initial presentation form -- (from UC_UNICODE_CONSTANTS) Initial_quote_punctuation_category: INTEGER_32 = 16 -- Initial punctuation -- (from UC_UNICODE_CONSTANTS) Integer_: KL_INTEGER_ROUTINES -- Routines that ought to be in class INTEGER -- (from KL_IMPORTED_INTEGER_ROUTINES) once create Result ensure -- from KL_IMPORTED_INTEGER_ROUTINES instance_free: class integer_routines_not_void: Result /= Void end Isolated_decomposition_mapping: INTEGER_32 = 6 -- Decomposition mapping for Arabic isolated presentation form -- (from UC_UNICODE_CONSTANTS) Letter_number_category: INTEGER_32 = 10 -- Letter number -- (from UC_UNICODE_CONSTANTS) Line_separator_category: INTEGER_32 = 24 -- Line separator -- (from UC_UNICODE_CONSTANTS) Lowercase_letter_category: INTEGER_32 = 2 -- Lower case letter -- (from UC_UNICODE_CONSTANTS) Math_symbol_category: INTEGER_32 = 19 -- Mathematics symbol -- (from UC_UNICODE_CONSTANTS) Maximum_ascii_character: CHARACTER_8 = '%/127/' -- Largest ASCII character -- ensure -- definition: Result.code = maximum_ascii_code -- end -- (from UC_UNICODE_CONSTANTS) Maximum_ascii_character_code: INTEGER_32 = 127 -- Largest code for ASCII characters -- (2^7 - 1) -- ensure -- definition: Result = 127 -- small_enough: Result <= Platform.Maximum_byte_code -- end -- (from UC_UNICODE_CONSTANTS) Maximum_bmp_character_code: INTEGER_32 = 65535 -- Largest code for unicode characters in Basic Multi-lingual Plane (FFFF); -- ensure -- definition: Result = 65535 -- end -- (from UC_UNICODE_CONSTANTS) Maximum_unicode_character_code: INTEGER_32 = 1114111 -- Largest code for unicode characters (10FFFF); -- Includes final two non-characters. -- ensure -- definition: Result = 1114111 -- end -- (from UC_UNICODE_CONSTANTS) Maximum_unicode_surrogate_code: INTEGER_32 = 57343 -- Highest unicode surrogate code-point (0xDFFF) -- ensure -- definition: Result = 57343 -- end -- (from UC_UNICODE_CONSTANTS) Medial_decomposition_mapping: INTEGER_32 = 4 -- Decomposition mapping for Arabic medial presentation form -- (from UC_UNICODE_CONSTANTS) Minimum_ascii_character: CHARACTER_8 = '%U' -- Smallest ASCII character -- ensure -- definition: Result.code = minimum_ascii_code -- end -- (from UC_UNICODE_CONSTANTS) Minimum_ascii_character_code: INTEGER_32 = 0 -- Smallest code for ASCII characters -- ensure -- definition: Result = 0 -- end -- (from UC_UNICODE_CONSTANTS) Minimum_unicode_character_code: INTEGER_32 = 0 -- Smallest code for unicode characters -- ensure -- definition: Result = 0 -- end -- (from UC_UNICODE_CONSTANTS) Minimum_unicode_surrogate_code: INTEGER_32 = 55296 -- Lowest unicode surrogate code-point (0xD800) -- ensure -- definition: Result = 55296 -- end -- (from UC_UNICODE_CONSTANTS) Modifier_letter_category: INTEGER_32 = 4 -- Modifier letter -- (from UC_UNICODE_CONSTANTS) Modifier_symbol_category: INTEGER_32 = 21 -- Modifier symbol -- (from UC_UNICODE_CONSTANTS) Narrow_decomposition_mapping: INTEGER_32 = 12 -- Decomposition mapping for narrow (hankaku) compatibility character -- (from UC_UNICODE_CONSTANTS) No_break_decomposition_mapping: INTEGER_32 = 2 -- Decomposition mapping for no-break variant -- (from UC_UNICODE_CONSTANTS) Non_spacing_mark_category: INTEGER_32 = 6 -- Non-spacing mark -- (from UC_UNICODE_CONSTANTS) Open_punctuation_category: INTEGER_32 = 14 -- Open punctuation -- (from UC_UNICODE_CONSTANTS) Other_letter_category: INTEGER_32 = 5 -- Other letter -- (from UC_UNICODE_CONSTANTS) Other_number_category: INTEGER_32 = 11 -- Other number -- (from UC_UNICODE_CONSTANTS) Other_punctuation_category: INTEGER_32 = 18 -- Other punctuation -- (from UC_UNICODE_CONSTANTS) Other_symbol_category: INTEGER_32 = 22 -- Other symbol -- (from UC_UNICODE_CONSTANTS) Paragraph_separator_category: INTEGER_32 = 25 -- Paragraph separator -- (from UC_UNICODE_CONSTANTS) Platform: KL_PLATFORM -- Platform-dependent properties -- (from KL_SHARED_PLATFORM) once create Result ensure -- from KL_SHARED_PLATFORM instance_free: class platform_not_void: Result /= Void end Private_other_category: INTEGER_32 = 29 -- Private-use character -- (from UC_UNICODE_CONSTANTS) Small_decomposition_mapping: INTEGER_32 = 13 -- Decomposition mapping for small variant form (CNS compatibility) -- (from UC_UNICODE_CONSTANTS) Space_separator_category: INTEGER_32 = 23 -- Space separator -- (from UC_UNICODE_CONSTANTS) Spacing_combining_mark_category: INTEGER_32 = 7 -- Spacing combining mark -- (from UC_UNICODE_CONSTANTS) Square_decomposition_mapping: INTEGER_32 = 14 -- Decomposition mapping for CJK squared font variant -- (from UC_UNICODE_CONSTANTS) Subscript_decomposition_mapping: INTEGER_32 = 9 -- Decomposition mapping for subscript form -- (from UC_UNICODE_CONSTANTS) Superscript_decomposition_mapping: INTEGER_32 = 8 -- Decomposition mapping for superscript form -- (from UC_UNICODE_CONSTANTS) Surrogate_other_category: INTEGER_32 = 28 -- Surrogate character -- (from UC_UNICODE_CONSTANTS) Titlecase_letter_category: INTEGER_32 = 3 -- Title case letter -- (from UC_UNICODE_CONSTANTS) Unassigned_other_category: INTEGER_32 = 0 -- Unassigned chacaracter -- (from UC_UNICODE_CONSTANTS) Uppercase_letter_category: INTEGER_32 = 1 -- Upper case letter -- (from UC_UNICODE_CONSTANTS) Vertical_decomposition_mapping: INTEGER_32 = 10 -- Decomposition mapping for vertical layout presentation form -- (from UC_UNICODE_CONSTANTS) Wide_decomposition_mapping: INTEGER_32 = 11 -- Decomposition mapping for wide (zenkaku) compatibility character -- (from UC_UNICODE_CONSTANTS) feature -- Comparison frozen deep_equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void -- or attached to isomorphic object structures? -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.is_deep_equal (b) end ensure -- from ANY instance_free: class shallow_implies_deep: standard_equal (a, b) implies Result both_or_none_void: (a = Void) implies (Result = (b = Void)) same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b)) symmetric: Result implies deep_equal (b, a) end frozen equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void or attached -- to objects considered equal? -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.is_equal (b) end ensure -- from ANY instance_free: class definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.is_equal (b)) end frozen is_deep_equal (other: UC_UTF16_ROUTINES): BOOLEAN -- Are Current and other attached to isomorphic object structures? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY shallow_implies_deep: standard_is_equal (other) implies Result same_type: Result implies same_type (other) symmetric: Result implies other.is_deep_equal (Current) end is_equal (other: UC_UTF16_ROUTINES): BOOLEAN -- Is other attached to an object considered -- equal to current object? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY symmetric: Result implies other ~ Current consistent: standard_is_equal (other) implies Result end frozen standard_equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void or attached to -- field-by-field identical objects of the same type? -- Always uses default object comparison criterion. -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.standard_is_equal (b) end ensure -- from ANY instance_free: class definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.standard_is_equal (b)) end frozen standard_is_equal (other: UC_UTF16_ROUTINES): BOOLEAN -- Is other attached to an object of the same type -- as current object, and field-by-field identical to it? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY same_type: Result implies same_type (other) symmetric: Result implies other.standard_is_equal (Current) end feature -- Status report conforms_to (other: ANY): BOOLEAN -- Does type of current object conform to type -- of other (as per Eiffel: The Language, chapter 13)? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" end same_type (other: ANY): BOOLEAN -- Is type of current object identical to type of other? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY definition: Result = (conforms_to (other) and other.conforms_to (Current)) end valid_utf16 (a_string: STRING_8): BOOLEAN -- Are the bytes in a_string a valid UTF-16 encoding? -- 'a_string' has one byte per character. -- Default to big endian when no BOM. require a_string_not_void: a_string /= Void a_string_is_string: Any_.same_types (a_string, "") local a_most: INTEGER_32 i, cnt: INTEGER_32 do Result := (a_string.count \\ 2) = 0 if Result and a_string.count > 0 then from if is_endian_detection_character_least_first (a_string.item_code (1), a_string.item_code (2)) then i := 2 else i := 1 end cnt := a_string.count until (i > cnt) or (not Result) loop a_most := a_string.item (i).code if is_surrogate (a_most) then i := i + 2 Result := is_high_surrogate (a_most) and ((i <= cnt) and then is_low_surrogate (a_string.item (i).code)) end i := i + 2 end end ensure instance_free: class empty_is_true: a_string.count = 0 implies Result utf16_even_count: Result implies ((a_string.count \\ 2) = 0) end valid_utf16be (a_string: STRING_8): BOOLEAN -- Are the bytes in a_string valid UTF-16BE? -- 'a_string' has one byte per character. require a_string_not_void: a_string /= Void a_string_is_string: Any_.same_types (a_string, "") local a_most: INTEGER_32 i, cnt: INTEGER_32 do Result := (a_string.count \\ 2) = 0 if Result and a_string.count > 0 then from i := 1 cnt := a_string.count until (i > cnt) or (not Result) loop a_most := a_string.item (i).code if is_surrogate (a_most) then i := i + 2 Result := is_high_surrogate (a_most) and ((i <= cnt) and then is_low_surrogate (a_string.item (i).code)) end i := i + 2 end end ensure instance_free: class empty_is_true: a_string.count = 0 implies Result utf16_even_count: Result implies ((a_string.count \\ 2) = 0) end valid_utf16le (a_string: STRING_8): BOOLEAN -- Are the bytes in a_string valid UTF-16LE? -- 'a_string' has one byte per character. require a_string_not_void: a_string /= Void a_string_is_string: Any_.same_types (a_string, "") local a_most: INTEGER_32 i, cnt: INTEGER_32 do Result := (a_string.count \\ 2) = 0 if Result and a_string.count > 0 then from i := 2 until (i > cnt) or (not Result) loop a_most := a_string.item (i).code if is_surrogate (a_most) then i := i + 2 Result := is_high_surrogate (a_most) and ((i <= cnt) and then is_low_surrogate (a_string.item (i).code)) end i := i + 2 end end ensure instance_free: class empty_is_true: a_string.count = 0 implies Result utf16_even_count: Result implies ((a_string.count \\ 2) = 0) end feature -- Duplication frozen clone (other: detachable ANY): like other obsolete "Use `twin' instead. [2017-05-31]" -- Void if other is void; otherwise new object -- equal to other -- -- For non-void other, clone calls copy; -- to change copying/cloning semantics, redefine copy. -- (from ANY) do if other /= Void then Result := other.twin end ensure -- from ANY instance_free: class equal: Result ~ other end copy (other: UC_UTF16_ROUTINES) -- Update current object using fields of object attached -- to other, so as to yield equal objects. -- (from ANY) require -- from ANY other_not_void: other /= Void type_identity: same_type (other) external "built_in" ensure -- from ANY is_equal: Current ~ other end frozen deep_clone (other: detachable ANY): like other obsolete "Use `deep_twin' instead. [2017-05-31]" -- Void if other is void: otherwise, new object structure -- recursively duplicated from the one attached to other -- (from ANY) do if other /= Void then Result := other.deep_twin end ensure -- from ANY instance_free: class deep_equal: deep_equal (other, Result) end frozen deep_copy (other: UC_UTF16_ROUTINES) -- Effect equivalent to that of: -- copy (other . deep_twin) -- (from ANY) require -- from ANY other_not_void: other /= Void do copy (other.deep_twin) ensure -- from ANY deep_equal: deep_equal (Current, other) end frozen deep_twin: UC_UTF16_ROUTINES -- New object structure recursively duplicated from Current. -- (from ANY) external "built_in" ensure -- from ANY deep_twin_not_void: Result /= Void deep_equal: deep_equal (Current, Result) end frozen standard_clone (other: detachable ANY): like other obsolete "Use `standard_twin' instead. [2017-05-31]" -- Void if other is void; otherwise new object -- field-by-field identical to other. -- Always uses default copying semantics. -- (from ANY) do if other /= Void then Result := other.standard_twin end ensure -- from ANY instance_free: class equal: standard_equal (Result, other) end frozen standard_copy (other: UC_UTF16_ROUTINES) -- Copy every field of other onto corresponding field -- of current object. -- (from ANY) require -- from ANY other_not_void: other /= Void type_identity: same_type (other) external "built_in" ensure -- from ANY is_standard_equal: standard_is_equal (other) end frozen standard_twin: UC_UTF16_ROUTINES -- New object field-by-field identical to other. -- Always uses default copying semantics. -- (from ANY) external "built_in" ensure -- from ANY standard_twin_not_void: Result /= Void equal: standard_equal (Result, Current) end frozen twin: UC_UTF16_ROUTINES -- New object equal to Current -- twin calls copy; to change copying/twinning semantics, redefine copy. -- (from ANY) external "built_in" ensure -- from ANY twin_not_void: Result /= Void is_equal: Result ~ Current end feature -- Basic operations frozen as_attached: attached UC_UTF16_ROUTINES obsolete "Remove calls to this feature. [2017-05-31]" -- Attached version of Current. -- (Can be used during transitional period to convert -- non-void-safe classes to void-safe ones.) -- (from ANY) do Result := Current end frozen default: detachable UC_UTF16_ROUTINES -- Default value of object's type -- (from ANY) do end frozen default_pointer: POINTER -- Default value of type POINTER -- (Avoid the need to write p.default for -- some p of type POINTER.) -- (from ANY) do ensure -- from ANY instance_free: class end default_rescue -- Process exception for routines with no Rescue clause. -- (Default: do nothing.) -- (from ANY) do end frozen do_nothing -- Execute a null action. -- (from ANY) do ensure -- from ANY instance_free: class end feature {NONE} -- Constants Hex_100: INTEGER_32 = 256 -- 2 ^ 8 Hex_10000: INTEGER_32 = 65536 -- Base of surrogates Hex_3ff: INTEGER_32 = 1023 -- Hex 3FF Hex_400: INTEGER_32 = 1024 -- 2 ^ 10 Hex_d7c0: INTEGER_32 = 55232 -- Hex D7C0 Hex_d8: INTEGER_32 = 216 -- Hex_D800: start of so-called high-half zone or high surrogate area Hex_dc: INTEGER_32 = 220 -- Hex_DC00: start of so-called low-half zone or low surrogate area Hex_dc00: INTEGER_32 = 56320 -- Hex_DC00: start of so-called low-half zone or low surrogate area Hex_e0: INTEGER_32 = 224 -- Hex_E000: end (exclusive) of surrogate area Hex_fe: INTEGER_32 = 254 -- Endian detection character Hex_ff: INTEGER_32 = 255 -- Endian detection character feature -- Endian-ness detection Bom_be: STRING_8 -- BOM in big-endian format once Result := "þÿ" ensure instance_free: class bom_be_not_void: Result /= Void two_bytes: Result.count = 2 first_byte: Result.item_code (1) = Hex_fe second_byte: Result.item_code (2) = Hex_ff end Bom_le: STRING_8 -- BOM in little-endian format once Result := "ÿþ" ensure instance_free: class bom_le_not_void: Result /= Void two_bytes: Result.count = 2 first_byte: Result.item_code (1) = Hex_ff second_byte: Result.item_code (2) = Hex_fe end is_endian_detection_character (a_byte, other_byte: INTEGER_32): BOOLEAN -- Can these two bytes represent ZERO WIDTH NON-BREAKING SPACE? -- (It has to be unicode character 0xFEFF, because 0xFFFE is not a valid character.) require a_byte_is_byte: is_byte (a_byte) other_byte_is_byte: is_byte (other_byte) do Result := (a_byte = Hex_fe and other_byte = Hex_ff) or (a_byte = Hex_ff and other_byte = Hex_fe) ensure instance_free: class definition: Result = (a_byte.min (other_byte) = Hex_fe and a_byte.max (other_byte) = Hex_ff) end is_endian_detection_character_least_first (first, second: INTEGER_32): BOOLEAN -- Do the two bytes first and second represent the character -- 0xFEFF with first being the least significant byte? require a_byte_is_byte: is_byte (first) other_byte_is_byte: is_byte (second) do Result := first = Hex_ff and second = Hex_fe ensure instance_free: class definition: Result = (is_endian_detection_character (first, second) and (first = Hex_ff)) end is_endian_detection_character_most_first (first, second: INTEGER_32): BOOLEAN -- Do the two bytes first and second represent the character -- 0xFEFF with first being the most significant byte? require a_byte_is_byte: is_byte (first) other_byte_is_byte: is_byte (second) do Result := first = Hex_fe and second = Hex_ff ensure instance_free: class definition: Result = (is_endian_detection_character (first, second) and (first = Hex_fe)) end feature -- Output Io: STD_FILES -- Handle to standard file setup -- (from ANY) once create Result Result.set_output_default ensure -- from ANY instance_free: class io_not_void: Result /= Void end out: STRING_8 -- New string containing terse printable representation -- of current object -- (from ANY) do Result := tagged_out ensure -- from ANY out_not_void: Result /= Void end print (o: detachable ANY) -- Write terse external representation of o -- on standard output. -- (from ANY) do if o /= Void then Io.put_string (o.out) end ensure -- from ANY instance_free: class end frozen tagged_out: STRING_8 -- New string containing terse printable representation -- of current object -- (from ANY) external "built_in" ensure -- from ANY tagged_out_not_void: Result /= Void end feature -- Platform Operating_environment: OPERATING_ENVIRONMENT -- Objects available from the operating system -- (from ANY) once create Result ensure -- from ANY instance_free: class operating_environment_not_void: Result /= Void end feature {NONE} -- Retrieval frozen internal_correct_mismatch -- Called from runtime to perform a proper dynamic dispatch on correct_mismatch -- from MISMATCH_CORRECTOR. -- (from ANY) local l_msg: STRING_8 l_exc: EXCEPTIONS do if attached {MISMATCH_CORRECTOR} Current as l_corrector then l_corrector.correct_mismatch else create l_msg.make_from_string ("Mismatch: ") create l_exc l_msg.append (generating_type.name) l_exc.raise_retrieval_exception (l_msg) end end feature -- Surrogate is_byte (a: INTEGER_32): BOOLEAN -- Is a a byte? do Result := a >= 0 and a < Hex_100 ensure instance_free: class definition: Result = (a >= 0 and a < Hex_100) end is_high_surrogate (a_most: INTEGER_32): BOOLEAN -- Is this a high surrogate byte? require byte: is_byte (a_most) do Result := a_most >= Hex_d8 and a_most < Hex_dc ensure instance_free: class end is_low_surrogate (a_most: INTEGER_32): BOOLEAN -- Is this a low surrogate byte? require byte: is_byte (a_most) do Result := a_most >= Hex_dc and a_most < Hex_e0 ensure instance_free: class end is_surrogate (a_most: INTEGER_32): BOOLEAN -- Is this a high surrogate byte? require byte: is_byte (a_most) do Result := a_most >= Hex_d8 and a_most < Hex_e0 ensure instance_free: class end least_10_bits (msb, lsb: INTEGER_32): INTEGER_32 -- UTF16 least 10 bytes of a byte pair require msb_byte: is_byte (msb) lsb_byte: is_byte (lsb) surrogate: is_surrogate (msb) do Result := ((msb \\ 4) * Hex_100) + lsb ensure instance_free: class ten_bits: Result >= 0 and Result < Hex_400 end supplementary_to_high_surrogate (a_code: INTEGER_32): INTEGER_32 -- High surrogate for a_code require code_high_enough: a_code > Maximum_bmp_character_code code_low_enough: a_code <= Maximum_unicode_character_code do Result := Integer_.bit_shift_right (a_code, 10) + Hex_d7c0 ensure instance_free: class high_surrogate: Result >= 256 * Hex_d8 not_too_big: Result < 256 * Hex_dc end supplementary_to_low_surrogate (a_code: INTEGER_32): INTEGER_32 -- Low surrogate for a_code require code_high_enough: a_code > Maximum_bmp_character_code code_low_enough: a_code <= Maximum_unicode_character_code do Result := Integer_.bit_or (Integer_.bit_and (a_code, Hex_3ff), Hex_dc00) ensure instance_free: class low_surrogate: Result >= 256 * Hex_dc not_too_big: Result < 256 * Hex_e0 end surrogate (a_high_10: INTEGER_32; a_low_10: INTEGER_32): INTEGER_32 -- Supplementary code point from high and low values require high_10: a_high_10 >= 0 and a_high_10 < 1024 low_10: a_low_10 >= 0 and a_low_10 < 1024 do Result := Hex_10000 + ((a_high_10 * Hex_400) + a_low_10) ensure instance_free: class more_than_16bits: Result >= Hex_10000 end surrogate_from_bytes (a_high_most, a_high_least, a_low_most, a_low_least: INTEGER_32): INTEGER_32 -- Supplementary code point from bytes require surrogate_high: is_high_surrogate (a_high_most) high_least_byte: is_byte (a_high_least) surrogate_low: is_low_surrogate (a_low_most) low_least_byte: is_byte (a_low_least) do Result := surrogate (least_10_bits (a_high_most, a_high_least), least_10_bits (a_low_most, a_low_least)) ensure instance_free: class more_than_16bits: Result >= Hex_10000 end invariant -- from ANY reflexive_equality: standard_is_equal (Current) reflexive_conformance: conforms_to (Current) end -- class UC_UTF16_ROUTINES
Generated by ISE EiffelStudio