Petroglif

Управление строковыми ресурсами

Не знаю стоит ли рассказывать о том, почему константные текстовые строки должны храниться отдельно от исходного кода. На всякий случай приведу дежурные аргументы:

  • Централизованное управление текстовыми ресурсами облегчает их администрирование, исправление ошибок, устранение дубликатов.
  • Строки, хранящиеся отдельно от кода программы, проще классифицировать.
  • Ресурсы текстовых объектов значительно упрощают проблему представления текста в различных кодировках.
  • Задача интернационализации строк при использовании отдельного хранилища текста не просто упрощается, она меняется кардинально - вместо сбора строк по всем исходным файлам проекта, вы транслируете хорошо идентифицированные данные с возможностью менять оригинальное представление (напомню, что широко распространенный подход интернационализации с использованием gettext и po-файлов опирается на идентификацию текстовых сущностей посредством оригинальных строк, собранных по исходным модулям, то есть изменение или исправление оригинального текста “ломает” результаты перевода).
  • Текстовые строки применяются не только в исходных кодах, но и в иных ресурсах: описании экранных форм (диалогов), таблиц визуализации данных и т.д. Так вот, общее пространство строковых ресурсов обеспечивает унифицированных механизм доступа к этим ресурсам не только из собственно программных кодов, но из иных программных сущностей.
  • Существует еще, в некоторой степени спорный довод, что “изгнание” строк из кодовой базы повышает сложность реверс-инжениринга скомпилированных модулей, поскольку специалистам, осуществляющим такой анализ, становится сложнее искать “якорные” точки для анализа. Это - не моя специализация, потому я не стану настаивать на этой позиции.
  • Ну и самый очевидный аргумент: многие, если не большинство, систем разработки содержат инструменты для управления строковыми ресурсами.
  • В этой статье я опишу технику управления текстовыми ресурсами, применяемую в системе Papyrus. Я выше упомянул о том, что во многих системах разработки имеются инструменты управления строковыми ресурсами. Так зачем, тем не менее, я описываю какой-то иной подход? Есть несколько причин. Одна из основных: очень скромные возможности идентификации текстовых объектов в существующих решениях.С идентификации мы и начнем.

    Идентификация текстовых ресурсов

    Нам понадобятся следующие варианты идентификации строк:
  • я бы сказал, канонический метод идентификации: мнемонические символы, автоматически транслируемые в уникальные целочисленные идентификаторы. К примеру: TXT_THEIMPORTANT_STRING “Это - важная текстовая строка!” Наша система управления строковыми ресурсами должна сгенерировать программный символ TXT_THEIMPORTANT_STRING, присвоить ему уникальное (в области определения некоторого набора строк) целое значение и представить его в каком-то виде, понятном языку программирования, на котором мы разрабатываем проект. Для языка C это, скажем, будет
    
    		#define TXT_THEIMPORTANT_STRING 1076
    	
  • Кроме мнемонических обозначений, транслируемых в числовые идентификаторы, нам понадобится явная идентификация строк через целочисленные значения. Ну что-то в таком роде:
    
    			15 "Это - строка с идентификатором 15"
    		

    К чему это? Например, для представления строк, наследуемых из сторонних библиотек и компонентов. Идентификацию таких строк мы не контролируем потому автогенерация числовых кодов по мнемоникам не сработает.

  • Наконец, мы никак не сможем обойтись без идентификации по коротким мнемоническим строковым ключам. Здесь, конечно, проглядывает обидная рекурсия: зачем использовать строковые константы для определения других строковых констант? Затем, что мы хотим использовать наши строковые ресурсы не только из кодов на выбранном языке программирования, но и из иных, чаще всего, каких-то специализированных языков. Тех же языков описания ресурсов пользовательского интерфейса. Да, собственно говоря, внутри описания самих строковых ресурсов мы сможет применять такие определения. Вот, например, зададим строку таким образом:

    
    	@somestring "Какая-то строка"
    	
    А теперь в том же модуле зададим такое определение:
    
    	TXT_SOMESTRING_2 "@{somestring} 2" 
    	

    При вызове из программы строки с идентификатором, соответствующем TXT_SOMESTRING_2 мы получим результат “Какая-то строка 2”.

  • Группировка текстовых строк

    Я перечислил все методы идентификации строк, но кроме этого нам понадобится какая-нибудь группировка наборов строк. Хотелось бы отдельно определять, допустим, сообщения об ошибках и отдельно - строки для вывода в журнал. Кроме этого требования, без которого можно было бы и обойтись, есть одно специальное применение строковых групп - определение множества символов для хэш-таблиц, применяемых, например, при прямом и обратном преобразовании данных между программными комопнентами и внешними системами в формализованных тексовых форматах (xml, json, etc).

    Расширенные дескрипторы строк

    Еще одна мелочь которая будет полезна - расширенные дескрипторы строк. Несмотря на заумное наименование это - просто многословное дополнение к строке, которое можно использовать в качестве подсказки пользователю или при иной необходимости.

    Формат описания текстовых ресурсов

    Теперь, когда основные нехитрые требования и принципы нам ясны, можно приступить к формату определения строковых ресурсов. Он достаточно прост (немного похож на ini-файл).

    Во-первых, примечания. Они подчиняются правилам c++. То есть, это либо два слэша (//) и все, что за ними до конца строки, либо многострочные примечания между /* и */.Далее, группы строк. Группа начинается с конструкции [номер-группы] заканчивается либо в конце файла, либо при появлении определения новой группы. Группы идентифицируются только лишь целыми числами. Символьные идентификаторы групп невозможны. Мне немного неудобо из-за этого, но за десятилетия использования этого формата ни разу не возникло серьезной необходимости что-то здесь менять. Для групп, определяющих набор строк для хэш-таблицы введен модификатор :hash после номера группы. Например:

     

    OOO "Петроглиф"
    Copyright © 2019