کتابخانه‌ی استاندارد · پایه

متن text

تبدیل رشته به UTF-16 و برعکس، برای کار با ویندوز و کتابخانه‌هایی که این قالب را می‌خواهند.

واردسازی متن

نام آرگومان‌ها شناسه‌ی خود کد است و معادل فارسی ندارد؛ گونه‌ها، کلیدواژه‌ها و نام بسته‌ها با معادل فارسی نوشته می‌شوند.

رشته‌های سلام UTF-8 هستند، اما برخی سیستم‌ها، به‌ویژه ویندوز و بعضی کتابخانه‌های C، متن را در قالب UTF-16 می‌خواهند. در UTF-16 هر حرف معمولی یک «واحد» ۱۶ بیتی است و حرف‌های کمیاب‌تر مثل شکلک‌ها دو واحد.

بسته‌ی متن این تبدیل را در هر دو جهت انجام می‌دهد و طول رشته را همان‌طور می‌شمارد که سیستم‌های UTF-16 می‌شمارند. باقی کارهای متنی، مثل جست‌وجو، جدا کردن و تغییر بزرگی حرف، در رشته است؛ برای دسته‌ی نویسه‌ها، یکسان‌سازی و خوشه‌های نویسه به یونیکد سر بزنید.

چند نکته که باید در نظر داشت:

  • حافظه‌ای که به یوتف شانزده برمی‌گرداند مال شماست. پایانش یک واحد صفر است و باید با حافظه.آزادسازی آزاد شود.
  • واحد یوتف شانزده مرز آرایه را بررسی نمی‌کند. سر واحد صفر بایستید؛ خواندن بعد از آن، هر چه را در حافظه پشتش باشد می‌خواند.
  • ورودی اعتبارسنجی نمی‌شود. UTF-8 خراب تا جایی که بشود تبدیل می‌شود، و جانشین تنها در آرایه‌ی UTF-16 همان‌طور در نتیجه کپی می‌شود؛ یعنی رشته‌ای که UTF-8 درستی نیست.

بررسی سقف طول به همان شیوه‌ای که جاوااسکریپت می‌شمارد

مرورگر، یک API نوشته‌شده با جاوااسکریپت، جاوا یا سی‌شارپ، و بسیاری از پایگاه‌های داده طول رشته را با واحدهای UTF-16 اندازه می‌گیرند. اگر سرور سلام شما سقف طول را بر حسب بایت یا حرف بسنجد، ممکن است با فرمی که متن را فرستاده هم‌نظر نباشد: متنی که مرورگر با سقف ۱۲ پذیرفته برای شما ۲۲ بایت است، و پیامی که مرورگر رد کرده ممکن است به چشم سلام کوتاه بیاید. طول یوتف شانزده درست مثل آن‌ها می‌شمارد.

text-guide-limit.salam
واردسازی متن
واردسازی قالب بندی

تابع جا می‌شود(پیام: رشته، سقف: صحیح): رشته:
    واحدها := متن.طول یوتف شانزده(پیام)
    اگر واحدها <= سقف:
        برگشت "جا می‌شود"
    پایان
    برگشت "به اندازه‌ی " + (واحدها - سقف) + " واحد بلند است"
پایان

تابع ریشه:
    سقف := ۱۲
    سرچاپ قالب بندی.پرکردن راست("پیام"، ۱۶)، "بایت حرف واحد"
    هر پ در ["سلام دوستان!"، "سلام دنیای زیبا"، "Café au lait"، "جشن تولد 🎉🎉🎉"]:
        سرچاپ قالب بندی.پرکردن راست(پ، ۱۶)، پ.طول()، پ.شمارنویسه()، متن.طول یوتف شانزده(پ)، جا می‌شود(پ، سقف)
    پایان
پایان
خروجیپیام بایت حرف واحد سلام دوستان! 22 12 12 جا می‌شود سلام دنیای زیبا 28 15 15 به اندازه‌ی 3 واحد بلند است Café au lait 13 12 12 جا می‌شود جشن تولد 🎉🎉🎉 28 12 15 به اندازه‌ی 3 واحد بلند است

سه عدد هر خط طول بر حسب بایت (طول)، تعداد حرف (شمارنویسه) و طول UTF-16 است. هر حرف فارسی دو بایت ولی یک واحد است، پس برای متن فارسی عدد بایت تقریباً دو برابر می‌شود. حرف تکیه‌دار یک بایت اضافه می‌کند ولی واحد نه. هر شکلک یک حرف اما دو واحد است، پس پیام آخر با این‌که ۱۲ حرف بیشتر ندارد، از سقف ۱۲ رد می‌شود.

کوتاه کردن متن تا سقف UTF-16

وقتی طرف مقابل با واحدهای UTF-16 می‌شمارد، پیش‌نمایش، اعلان یا پیامک را هم باید با همان واحد برید. بریدن بر حسب بایت ممکن است یک حرف فارسی را نصف کند و بریدن بر حسب واحد ممکن است یک شکلک را از وسط جفت جانشینش دو تکه کند که به شکل یک مربع یا علامت سؤال دیده می‌شود. اگر حرف‌ها را با رشته.نویسه ها کامل‌کامل پیمایش کنید و واحدهای هر کدام را جمع بزنید، از هر دو مشکل در امان می‌مانید.

text-guide-truncate.salam
واردسازی رشته
واردسازی متن

تابع کوتاه کن(پیام: رشته، سقف: صحیح): رشته:
    اگر متن.طول یوتف شانزده(پیام) <= سقف:
        برگشت پیام
    پایان
    ناپایا خروجی := ""
    ناپایا مصرف شده := ۱
    نویسه‌ها := رشته.نویسه ها(پیام)
    دیرکن نویسه‌ها.آزادکن()
    هر ن در نویسه‌ها:
        واحدها := متن.طول یوتف شانزده(ن)
        اگر مصرف شده + واحدها > سقف:
            بشکن
        پایان
        خروجی += ن
        مصرف شده += واحدها
    پایان
    برگشت خروجی + "…"
پایان

تابع ریشه:
    سقف := ۱۶
    هر پ در ["سفارش ارسال شد"، "سفارش شماره‌ی ۴۴۷۱ شما ارسال شد"، "خبر خوب 🎉🎉🎉🎉🎉"]:
        کوتاه := کوتاه کن(پ، سقف)
        سرچاپ کوتاه، "(" + متن.طول یوتف شانزده(کوتاه) + " واحد)"
    پایان
پایان
خروجیسفارش ارسال شد (14 واحد) سفارش شماره‌ی ۴… (16 واحد) خبر خوب 🎉🎉🎉… (15 واحد)

یک واحد برای … آخر کنار گذاشته می‌شود تا نتیجه هیچ‌وقت از سقف بیشتر نشود. خط شکلک‌دار یک واحد زودتر از ۱۶ می‌ایستد، چون شکلک بعدی دو واحد می‌خواهد و فقط یکی مانده. نمادی که خواننده یکی می‌بیند ولی از چند نویسه ساخته شده، مثل پرچم یا شکلک خانواده، هنوز ممکن است از وسط بریده شود؛ برای آن، به جای رشته.نویسه ها روی رشته.خوشه ها پیمایش کنید.

پیمایش واحدهای UTF-16 و جفت‌های جانشین

به یوتف شانزده آرایه‌ای از واحدهای ۱۶ بیتی می‌سازد که با صفر تمام می‌شود؛ همان شکلی که تابع‌های ویندوز با W در نامشان و بسیاری از کتابخانه‌های C می‌خواهند. حرف‌های بالاتر از U+FFFF، مثل بیشتر شکلک‌ها، دو واحد می‌گیرند: یک جانشین بالا بین ۵۵۲۹۶ و ۵۶۳۱۹ و پس از آن یک جانشین پایین بین ۵۶۳۲۰ و ۵۷۳۴۳. نمونه‌ی زیر واحدها را یکی‌یکی می‌خواند و هر جفت را دوباره به نقطه‌ی کدش تبدیل می‌کند.

text-guide-pairs.salam
واردسازی متن
واردسازی حافظه

تابع ریشه:
    ر := "ش€😀"
    و۱ := متن.به یوتف شانزده(ر)
    دیرکن حافظه.آزادسازی(و۱)
    ت := متن.طول یوتف شانزده(ر)
    ناپایا ش := ۰
    تا ش < ت:
        واحد := متن.واحد یوتف شانزده(و۱، ش)
        اگر واحد >= ۵۵۲۹۶ و واحد < ۵۶۳۲۰:
            پایین := متن.واحد یوتف شانزده(و۱، ش + ۱)
            کد := ۶۵۵۳۶ + (واحد - ۵۵۲۹۶) * ۱۰۲۴ + (پایین - ۵۶۳۲۰)
            سرچاپ "واحدهای"، ش، "و"، ش + ۱، "یک جفت‌اند: نقطه‌ی کد"، کد
            ش += ۲
        وگرنه:
            سرچاپ "واحد"، ش، "همان نقطه‌ی کد"، واحد، "است"
            ش++
        پایان
    پایان
    سرچاپ متن.از یوتف شانزده(و۱) == ر
پایان
خروجیواحد 0 همان نقطه‌ی کد 1588 است واحد 1 همان نقطه‌ی کد 8364 است واحدهای 2 و 3 یک جفت‌اند: نقطه‌ی کد 128512 true

آرایه روی هیپ ساخته می‌شود و مال شماست: با حافظه.آزادسازی آزادش کنید، این‌جا از راه دیرکن. از یوتف شانزده راه برعکس را می‌رود و واحدها را، جفت‌ها هم، به یک رشته‌ی معمولی سلام برمی‌گرداند؛ متنی را که یک API با UTF-16 پس داده این‌طور می‌خوانید.

پرسشابزار
ذخیره یا فرستادنش چند بایت جا می‌گیرد؟ر.طول()
چند حرف دارد؟ر.شمارنویسه() یا شمارنویسه در رشته
خواننده چند حرف می‌بیند؟رشته.شمار خوشه
طولش در جاوااسکریپت، جاوا یا ویندوز چقدر است؟متن.طول یوتف شانزده

تابع‌ها

طول یوتف شانزده Utf16Len

تابع طول یوتف شانزده(s: رشته): صحیح
تعداد واحدهای UTF-16 رشته را برمی‌گرداند. برای متن فارسی با تعداد حرف‌ها برابر است، ولی هر شکلک دو واحد حساب می‌شود.
text-Utf16Len.salam
واردسازی متن

تابع ریشه:
    م := "سلام 😀"
    سرچاپ م.طول()، م.شمارنویسه()، متن.طول یوتف شانزده(م)
    ب := متن.به یوتف شانزده(م)
    سرچاپ متن.واحد یوتف شانزده(ب، ۰)، متن.واحد یوتف شانزده(ب، ۵)
    سرچاپ متن.از یوتف شانزده(ب)
پایان
خروجی13 6 7 1587 55357 سلام 😀

به یوتف شانزده ToUtf16

تابع به یوتف شانزده(s: رشته): تهی*
رشته را به یک آرایه‌ی UTF-16 با صفر پایانی تبدیل می‌کند و نشانی‌اش را برمی‌گرداند. آزاد کردن آرایه با حافظه.آزادسازی به عهده‌ی شماست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: text-Utf16Len.salam

واحد یوتف شانزده Utf16UnitAt

تابع واحد یوتف شانزده(w: تهی*، i: صحیح): صحیح
واحد شماره‌ی i را از یک آرایه‌ی UTF-16 می‌خواند. عددی از ۰ تا ۶۵۵۳۵ است و برای شکلک‌ها دو واحد پشت‌سرهم (جفت جانشین) می‌بینید. مرز آرایه بررسی نمی‌شود، پس سر واحد صفر بایستید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: text-Utf16Len.salam

از یوتف شانزده FromUtf16

تابع از یوتف شانزده(w: تهی*): رشته
یک آرایه‌ی UTF-16 با صفر پایانی را دوباره به رشته‌ی سلام تبدیل می‌کند و جفت‌های جانشین را به هم می‌چسباند. اشاره‌گر پوچ رشته‌ی تهی می‌دهد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: text-Utf16Len.salam