Правильное экранирование очень больших строк

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

const char libData[784674] PROGMEM = "the entire 700 KB library goes here";

А затем доставить его по запросу с сервера.on('./echarts.min.js ', handleLibRequest) или что-то в этом роде.

Теперь моя проблема в том, что в этом 700КБ текста есть символы "и ", разбросанные по всему периметру. C ++ 11 способ R("hard escapable """'" string") не работает в моей среде. Как бы это сделать, чтобы включить этот файл в мой код?

Есть ли какой-то способ использовать препроцессор для этого? Или, может быть, онлайн-инструмент, который преобразует "str" в ["s", "t", "r"]?

, 👍0

Обсуждение

обслуживание статических файлов из файловой системы, @Juraj

Как бы я добавил эти статические файлы в файловую систему? Без необходимости использовать какой-либо код c ++, где я столкнулся бы с теми же проблемами, упомянутыми в моем вопросе?, @Cowboy_Patrick

с помощью плагина IDE для загрузки esp8266 FS. https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html, @Juraj


4 ответа


Лучший ответ:

1

Это просто: вставьте всю страницу между "()" в строке ниже

const char live_html[] PROGMEM = R"rawliteral(your date here)rawliteral";
,

1

Вы можете написать простую программу, которая экранирует все оскорбительные символы и использует их вывод в вашем const char libData[]; список escape-последовательностей см. Здесь;

Вы можете обслуживать библиотеку непосредственно из (псевдо) файловой системы на ESP8266, не копируя ее "вручную" в переменную; вы просто копируете файл в файловую систему;

Вы можете Base64-закодировать библиотеку и вручную скопировать результат в const char libData[], а затем Base64-декодировать перед отправкой;

Что мне нравится делать, если нет файловой системы, но достаточно памяти:

  • Gzip библиотеки;
  • Base64 - кодировать файл .gz;
  • Скопируйте результат в кодировке Base-64 вручную в const char libData[].

Несмотря на кодировку Base64, gzipping делает конечный результат меньше оригинала, что помогает с использованием памяти и скоростью передачи, и у него не будет никаких "проблем с цитатами".

Когда необходимо обслужить libData, Base64-декодирует его и отправляет полученные (gzipped) данные клиенту; все известные мне браузеры примут это, если вы добавите заголовок Content-Encoding: gzip.

Пример кода на необработанном клиенте без библиотеки веб-сервера: unsigned int sendBase64Page() (обратите внимание на тип содержимого).

,

Это все равно что скопировать его в переменную, но, на мой взгляд, излишне сложно. Но спасибо за идею., @Cowboy_Patrick


0

Я только что написал себе python-скрипт, который создает массив символов с числами, представляющими символы. Может быть, это поможет кому-то еще:

import sys

def arrayify(sourceFile, targetFile):
    with open(sourceFile, 'rb') as sf:
        contents = sf.read()

        charArray = ""

        for char in contents:
            charArray += str(char) + ","

        # end array

        with open(targetFile, 'w') as tf:
            tf.write(charArray)


if __name__ == "__main__":
    sourceFile = sys.argv[1]
    targetFile = sys.argv[2]

    arrayify(sourceFile, targetFile)
,

1

Вы можете использовать "objcopy" для создания объектного файла из содержимого файла, если вы объявите его двоичным.

objcopy -I binary echarts.min.js -O <your-bfd-format> echarts.min.js.o

Чтобы узнать, какой формат BFD вам нужен, запустите objdump -t <любой объектный файл> и посмотрите на его вывод.

Результирующий объектный файл содержит объект, названный в честь входного файла в разделе .data. В таблице символов есть 3 символа:

  • _binary_echarts_min_js_start
  • _binary_echarts_min_js_end
  • _binary_echarts_min_js_size

Символ "start" обозначает начало содержимого файла, а символ "end" - адрес после последнего байта. Символ "size" трудно использовать в C или C ++, потому что это абсолютное значение.

Обычно я просто использую "начало" и "конец" следующим образом:

extern const char _binary_x_bin_start[];
extern const char _binary_x_bin_end[];
,

Вместо objcopy вы можете использовать ld -r -b binary echarts.min.js -o echarts.min.js.o Таким образом, вам не нужно знать формат BFD, если вы используете ld двоичный файл, соответствующий целевой архитектуре., @Edgar Bonet