Загрузка данных


#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <vector>
#include <string>
#include <cstring>
#include <iconv.h>

// Функция для конвертации строки из UTF-8 в CP866 (только для Linux/POSIX)
std::vector<char> convert_utf8_to_cp866(const std::string& input) {
    iconv_t cd = iconv_open("CP866", "UTF-8");
    if (cd == (iconv_t)-1) {
        std::cerr << "Ошибка инициализации iconv (CP866)" << std::endl;
        return {};
    }

    size_t in_bytes = input.size();
    size_t out_bytes = in_bytes * 2; // Запас под результат
    std::vector<char> output(out_bytes);

    char* in_buf = const_cast<char*>(input.c_str());
    char* out_buf = output.data();

    if (iconv(cd, &in_buf, &in_bytes, &out_buf, &out_bytes) == (size_t)-1) {
        std::cerr << "Ошибка конвертации кодировки" << std::endl;
        iconv_close(cd);
        return {};
    }

    // Вычисляем реальный размер полученных данных
    size_t final_size = output.size() - out_bytes;
    output.resize(final_size);

    iconv_close(cd);
    return output;
}

int main() {
    const char* printer_path = "/dev/usb/lp0";

    // 1. Формируем управляющие команды PCL 5e
    std::string uel = "\x1b%-12345X";                        // Универсальный конец задания
    std::string enter_pcl = "@PJL ENTER LANGUAGE = PCL\r\n"; // Вход в PCL
    std::string reset = "\x1bE";                             // Сброс принтера
    std::string paper_a4 = "\x1b&l26A";                      // Формат бумаги A4
    std::string cyrillic_866 = "\x1b(17R";                   // Таблица символов PC-866
    std::string font_courier = "\x1b(s3B";                   // Встроенный шрифт Courier
    std::string form_feed = "\x0c";                          // Команда выталкивания листа

    // 2. Русский текст для печати
    std::string text_to_print = 
        "Привет от C++!\r\n"
        "Прямая запись PCL 5e в /dev/usb/lp0 работает.\r\n"
        "Тест символов: 1234567890 !@#$%\r\n";

    // Конвертируем текст в кодировку CP866
    std::vector<char> text_bytes = convert_utf8_to_cp866(text_to_print);
    if (text_bytes.empty()) {
        return 1;
    }

    // 3. Собираем финальный бинарный буфер данных
    std::vector<char> payload;
    
    auto append_str = [&payload](const std::string& s) {
        payload.insert(payload.end(), s.begin(), s.end());
    };

    append_str(uel);
    append_str(enter_pcl);
    append_str(reset);
    append_str(paper_a4);
    append_str(cyrillic_866);
    append_str(font_courier);
    
    // Вставляем бинарные байты текста в CP866
    payload.insert(payload.end(), text_bytes.begin(), text_bytes.end());
    
    append_str(form_feed);
    append_str(uel);

    // 4. Открываем порт принтера на запись
    int printer_fd = open(printer_path, O_WRONLY);
    if (printer_fd == -1) {
        std::cerr << "Ошибка: Не удалось открыть " << printer_path << std::endl;
        std::cerr << "Проверьте подключение или запустите программу через sudo." << std::endl;
        return 1;
    }

    // 5. Отправляем буфер в принтер
    ssize_t bytes_written = write(printer_fd, payload.data(), payload.size());
    if (bytes_written == -1) {
        std::cerr << "Ошибка записи в устройство принтера." << std::endl;
    } else {
        std::cout << "Успешно отправлено " << bytes_written << " байт в " << printer_path << std::endl;
    }

    // Закрываем дескриптор файла
    close(printer_fd);
    return 0;
}