class EL_MEASUREABLE_ZSTRING
Measureable aspects of ZSTRING
note
description: "Measureable aspects of ${ZSTRING}"
author: "Finnian Reilly"
copyright: "Copyright (c) 2001-2022 Finnian Reilly"
contact: "finnian at eiffel hyphen loop dot com"
license: "MIT license (See: en.wikipedia.org/wiki/MIT_License)"
date: "2024-04-01 7:58:33 GMT (Monday 1st April 2024)"
revision: "28"
deferred class
EL_MEASUREABLE_ZSTRING
inherit
EL_ZSTRING_IMPLEMENTATION
feature -- Measurement
leading_occurrences (uc: CHARACTER_32): INTEGER
-- Returns count of continous occurrences of `uc' or white space starting from the begining
local
i, i_upper, block_index: INTEGER; encoded_c: CHARACTER
iter: EL_COMPACT_SUBSTRINGS_32_ITERATION
do
inspect uc.code
when 0 .. Max_ascii_code then
encoded_c := uc.to_character_8
else
encoded_c := Codec.encoded_character (uc)
end
i_upper := count - 1
if attached area as l_area then
if encoded_c = Substitute and then attached unencoded_area as area_32 and then area_32.count > 0 then
from i := 0 until i > i_upper loop
inspect l_area [i]
when Substitute then
Result := Result + (iter.item ($block_index, area_32, i + 1) = uc).to_integer
else
i := i_upper -- break out of loop
end
i := i + 1
end
else
from i := 0 until i > i_upper loop
-- `Unencoded_character' is space
if l_area [i] = encoded_c then
Result := Result + 1
else
i := i_upper -- break out of loop
end
i := i + 1
end
end
end
end
leading_white_space: INTEGER
do
Result := internal_leading_white_space (area, count)
end
occurrences (uc: CHARACTER_32): INTEGER
local
c: like area.item
do
inspect uc.code
when 0 .. Max_ascii_code then
c := uc.to_character_8
else
c := Codec.encoded_character (uc)
end
if c = Substitute then
Result := unencoded_occurrences (uc)
else
Result := String_8.occurrences (Current, c)
end
end
substitution_marker_count: INTEGER
-- count of unescaped template substitution markers '%S' AKA '#'
local
index, escaped_count, i: INTEGER
do
if attached substitution_marker_index_list.area as marker_area then
from until i = marker_area.count loop
index := marker_area [i]
if index - 1 > 0 and then item_8 (index - 1) = '%%' then
escaped_count := escaped_count + 1
end
i := i + 1
end
Result := marker_area.count - escaped_count
end
end
trailing_occurrences (uc: CHARACTER_32): INTEGER
-- Returns count of continous occurrences of `uc' or white space starting from the end
local
i, block_index: INTEGER; encoded_c: CHARACTER
iter: EL_COMPACT_SUBSTRINGS_32_ITERATION
do
inspect uc.code
when 0 .. Max_ascii_code then
encoded_c := uc.to_character_8
else
encoded_c := Codec.encoded_character (uc)
end
if attached area as l_area then
if encoded_c = Substitute then
if attached unencoded_area as area_32 and then area_32.count > 0 then
from i := count - 1 until i < 0 loop
inspect l_area [i]
when Substitute then
Result := Result + (iter.item ($block_index, area_32, i + 1) = uc).to_integer
else
i := 0 -- break out of loop
end
i := i - 1
end
end
else
from i := count - 1 until i < 0 loop
-- `Unencoded_character' is space
if l_area [i] = encoded_c then
Result := Result + 1
else
i := 0 -- break out of loop
end
i := i - 1
end
end
end
end
trailing_white_space: INTEGER
do
Result := internal_trailing_white_space (area)
end
utf_8_byte_count: INTEGER
do
Result := Codec.utf_8_byte_count (area, count) + unencoded_utf_8_byte_count
end
feature {NONE} -- Implementation
internal_leading_white_space (a_area: like area; a_count: INTEGER): INTEGER
local
c32: EL_CHARACTER_32_ROUTINES; iter: EL_COMPACT_SUBSTRINGS_32_ITERATION
block_index, i: INTEGER; c_i: CHARACTER
do
-- `Substitute' is space
if attached unencoded_area as area_32 and then area_32.count > 0 then
from i := 0 until i = a_count loop
c_i := a_area [i]
inspect c_i
when Substitute then
if c32.is_space (iter.item ($block_index, area_32, i + 1)) then
Result := Result + 1
else
i := a_count - 1 -- break out of loop
end
else
if c_i.is_space then
Result := Result + 1
else
i := a_count - 1 -- break out of loop
end
end
i := i + 1
end
else
from i := 0 until i = a_count loop
c_i := a_area [i]
if c_i.is_space then
Result := Result + 1
else
i := a_count - 1 -- break out of loop
end
i := i + 1
end
end
ensure then
substring_agrees: substring (1, Result).is_space_filled
end
internal_trailing_white_space (a_area: like area): INTEGER
local
c32: EL_CHARACTER_32_ROUTINES; iter: EL_COMPACT_SUBSTRINGS_32_ITERATION
block_index, i: INTEGER; c_i: CHARACTER
do
-- `Substitute' is space
if attached unencoded_area as area_32 and then area_32.count > 0 then
from i := count - 1 until i < 0 loop
c_i := a_area [i]
inspect c_i
when Substitute then
if c32.is_space (iter.item ($block_index, area_32, i + 1)) then
Result := Result + 1
else
i := 0 -- break out of loop
end
else
if c_i.is_space then
Result := Result + 1
else
i := 0 -- break out of loop
end
end
i := i - 1
end
else
from i := count - 1 until i < 0 loop
if a_area [i].is_space then
Result := Result + 1
else
i := 0 -- break out of loop
end
i := i - 1
end
end
end
end