<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: Unicode and happy user experiences</title>
	<atom:link href="http://blog.palantirtech.com/2007/03/06/unicode-and-happy-user-experiences/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.palantirtech.com/2007/03/06/unicode-and-happy-user-experiences/</link>
	<description>Just another WordPress weblog</description>
	<pubDate>Fri, 21 Nov 2008 12:30:05 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.1</generator>
		<item>
		<title>By: John Carrino</title>
		<link>http://blog.palantirtech.com/2007/03/06/unicode-and-happy-user-experiences/#comment-22</link>
		<dc:creator>John Carrino</dc:creator>
		<pubDate>Tue, 01 May 2007 00:22:39 +0000</pubDate>
		<guid isPermaLink="false">http://blog.palantirtech.com/2007/03/06/unicode-and-happy-user-experiences/#comment-22</guid>
		<description>
Change i to mean 1 past the end of the string and change the inner loop to be

&#160;&#160;i&#160;=&#160;string.offsetByCodePoints(i,&#160;-1);
&#160;&#160;shaveBytes&#160;-=&#160;computeByteLength(string.codePointAt(i),&#160;encoding);

A small assumption is each encoding has all chars at byte boundaries.  In other words, ComputeByteLength for a string input is just the sum of ComputeByteLength for all contained codepoints.

Assuming that computeByteLength can accept an int instead of a char, you get this.

public&#160;static&#160;String&#160;limitStringByBytes(String&#160;string,&#160;int&#160;maxBytes,&#160;String&#160;encoding)&#160;{
&#160;&#160;&#160;if(string&#160;==&#160;null)
&#160;&#160;&#160;&#160;&#160;&#160;return&#160;&#34;&#34;;
&#160;&#160;&#160;int&#160;i&#160;=&#160;string.length();
&#160;&#160;&#160;int&#160;shaveBytes&#160;=&#160;computeByteLength(string,encoding)&#160;-&#160;maxBytes;
&#160;&#160;&#160;while&#160;(&#160;shaveBytes&#160;&#62;&#160;0&#160;&#38;&#38;&#160;i&#160;&#62;&#160;0&#160;)&#160;{
&#160;&#160;&#160;&#160;&#160;&#160;i&#160;=&#160;string.offsetByCodePoints(i,&#160;-1);
&#160;&#160;&#160;&#160;&#160;&#160;shaveBytes&#160;-=&#160;computeByteLength(string.codePointAt(i),&#160;encoding);
&#160;&#160;&#160;}
&#160;&#160;&#160;if(&#160;i&#160;&#60;=&#160;0&#160;)
&#160;&#160;&#160;&#160;&#160;&#160;return&#160;&#34;&#34;;
&#160;&#160;&#160;else
&#160;&#160;&#160;&#160;&#160;&#160;return&#160;string.substring(0,&#160;i);
}



</description>
		<content:encoded><![CDATA[<p>Change i to mean 1 past the end of the string and change the inner loop to be</p>
<p>&nbsp;&nbsp;i&nbsp;=&nbsp;string.offsetByCodePoints(i,&nbsp;-1);<br />
&nbsp;&nbsp;shaveBytes&nbsp;-=&nbsp;computeByteLength(string.codePointAt(i),&nbsp;encoding);</p>
<p>A small assumption is each encoding has all chars at byte boundaries.  In other words, ComputeByteLength for a string input is just the sum of ComputeByteLength for all contained codepoints.</p>
<p>Assuming that computeByteLength can accept an int instead of a char, you get this.</p>
<p>public&nbsp;static&nbsp;String&nbsp;limitStringByBytes(String&nbsp;string,&nbsp;int&nbsp;maxBytes,&nbsp;String&nbsp;encoding)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;if(string&nbsp;==&nbsp;null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&quot;&quot;;<br />
&nbsp;&nbsp;&nbsp;int&nbsp;i&nbsp;=&nbsp;string.length();<br />
&nbsp;&nbsp;&nbsp;int&nbsp;shaveBytes&nbsp;=&nbsp;computeByteLength(string,encoding)&nbsp;-&nbsp;maxBytes;<br />
&nbsp;&nbsp;&nbsp;while&nbsp;(&nbsp;shaveBytes&nbsp;&gt;&nbsp;0&nbsp;&amp;&amp;&nbsp;i&nbsp;&gt;&nbsp;0&nbsp;)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;=&nbsp;string.offsetByCodePoints(i,&nbsp;-1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shaveBytes&nbsp;-=&nbsp;computeByteLength(string.codePointAt(i),&nbsp;encoding);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;if(&nbsp;i&nbsp;&lt;=&nbsp;0&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&quot;&quot;;<br />
&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;string.substring(0,&nbsp;i);<br />
}</p>
]]></content:encoded>
	</item>
</channel>
</rss>
