Ошибка «Дополнительное содержимое в конце документа» при использовании libxml2 для чтения из дескриптора файла, созданного с помощью shm_open - PullRequest
2 голосов
/ 24 января 2012

Я пытаюсь написать модульный тест, который проверяет некоторый код XML-анализа.Модульный тест создает дескриптор файла в XML-документе в памяти с помощью shm_open, а затем передает его в xmlTextReaderForFd ().Но я получаю ошибку «Дополнительное содержимое в конце документа» в последующем xmlTextReaderRead ().Код синтаксического анализа прекрасно работает с файловым дескриптором, созданным из фактического файла (я провел побайтное сравнение с созданным shm_open, и он точно такой же набор байтов.) Почему libxml2 захлебывается созданным файловым дескрипторомс shm_open?

Вот мой код:

void unitTest() {
  int fd = shm_open("/temporary", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  char *pText = "<?xml version=\"1.0\"?><foo></foo>";
  write(fd, pText, strlen(pText) + 1);
  lseek(fd, 0, SEEK_SET);

  xmlTextReaderPtr pReader = xmlReaderForFd(
    fd,            // file descriptor
    "/temporary",  // base uri
    NULL,          // encoding
    0);            // options

  int result = xmlTextReaderRead(pReader);
  // result is -1
  // Get this error at console:
  //   /temporary:1: parser error : Extra content at the end of the document
  //   <?xml version="1.0"?><foo></foo>
  //                                   ^
}

Ответы [ 2 ]

2 голосов
/ 24 января 2012

Я разобрался в проблеме. Я записывал терминатор NULL, и это то, что заставляло libxml2 задыхаться (хотя я мог бы поклясться, что уже пробовал это без терминатора NULL, черт!) Исправленный код должен быть просто:

 write(fd, pText, strlen(pText));
0 голосов
/ 05 апреля 2015

Также убедитесь, что вы читаете файл как двоичный файл, а не как текст.«Текст» удаляет CR / LF, уменьшает размер файла и оставляет детрит в конце буфера.

Пример (VS 2010):

struct _stat32 stat;
char *buf;
FILE *f = fopen("123.XML", "rb");    // right
//f = fopen("123.XML", "rt");    // WRONG!
_fstat(fileno(f), &stat);
buf = (char *)malloc(stat.st_size);
int ret = fread(buf, stat.st_size, 1, f);
assert(ret == 1);
// etc.
...