mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Add C API to QPDFLogger
This commit is contained in:
parent
daef4e8fb8
commit
8130d50e3b
@ -1,5 +1,11 @@
|
||||
2022-06-18 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Add examples that show how to capture QPDFJob's output by
|
||||
configuring the default logger (qpdfjob-save-attachment.cc,
|
||||
qpdfjob-c-save-attachment.c). Fixes #691.
|
||||
|
||||
* Add C API for QPDFLogger -- see qpdflogger-c.h
|
||||
|
||||
* Add additional qpdfjob C API functions take a handle.
|
||||
|
||||
* Add qpdf_exit_code_e to Constants.h so that exit codes from
|
||||
|
@ -130,9 +130,9 @@ class QPDFLogger
|
||||
void setError(std::shared_ptr<Pipeline>);
|
||||
// See notes above about the save pipeline
|
||||
QPDF_DLL
|
||||
void setSave(std::shared_ptr<Pipeline>);
|
||||
void setSave(std::shared_ptr<Pipeline>, bool only_if_not_set);
|
||||
QPDF_DLL
|
||||
void saveToStandardOutput();
|
||||
void saveToStandardOutput(bool only_if_not_set);
|
||||
|
||||
// Shortcut for logic to reset output to new output/error streams.
|
||||
// out_stream is used for info, err_stream is used for error, and
|
||||
|
100
include/qpdf/qpdflogger-c.h
Normal file
100
include/qpdf/qpdflogger-c.h
Normal file
@ -0,0 +1,100 @@
|
||||
/* Copyright (c) 2005-2022 Jay Berkenbilt
|
||||
*
|
||||
* This file is part of qpdf.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Versions of qpdf prior to version 7 were released under the terms
|
||||
* of version 2.0 of the Artistic License. At your option, you may
|
||||
* continue to consider qpdf to be licensed under those terms. Please
|
||||
* see the manual for additional information.
|
||||
*/
|
||||
|
||||
#ifndef QPDFLOGGER_H
|
||||
#define QPDFLOGGER_H
|
||||
|
||||
/*
|
||||
* This file provides a C API for QPDFLogger. See QPDFLogger.hh for
|
||||
* information about the logger.
|
||||
*/
|
||||
|
||||
#include <qpdf/DLL.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* To operate on a logger, you need a handle to it. call
|
||||
* qpdflogger_default_logger to get a handle for the default
|
||||
* logger. The qpdf and qpdfjob functions may offer ways to get
|
||||
* other logger handles. When you're done with the logger handler,
|
||||
* call qpdflogger_cleanup. This does not destroy the underlying
|
||||
* log object. It just cleans up the handle to it.
|
||||
*/
|
||||
|
||||
typedef struct _qpdflogger_handle* qpdflogger_handle;
|
||||
QPDF_DLL
|
||||
qpdflogger_handle qpdflogger_default_logger();
|
||||
|
||||
QPDF_DLL
|
||||
void qpdflogger_cleanup(qpdflogger_handle* l);
|
||||
|
||||
enum qpdf_log_dest_e {
|
||||
qpdf_log_dest_default = 0,
|
||||
qpdf_log_dest_stdout = 1,
|
||||
qpdf_log_dest_stderr = 2,
|
||||
qpdf_log_dest_discard = 3,
|
||||
qpdf_log_dest_custom = 4,
|
||||
};
|
||||
|
||||
typedef void (*qpdf_log_fn_t)(char const* data, size_t len, void* udata);
|
||||
|
||||
QPDF_DLL
|
||||
void qpdflogger_set_info(
|
||||
qpdflogger_handle l,
|
||||
enum qpdf_log_dest_e dest,
|
||||
qpdf_log_fn_t fn,
|
||||
void* udata);
|
||||
QPDF_DLL
|
||||
void qpdflogger_set_warn(
|
||||
qpdflogger_handle l,
|
||||
enum qpdf_log_dest_e dest,
|
||||
qpdf_log_fn_t fn,
|
||||
void* udata);
|
||||
QPDF_DLL
|
||||
void qpdflogger_set_error(
|
||||
qpdflogger_handle l,
|
||||
enum qpdf_log_dest_e dest,
|
||||
qpdf_log_fn_t fn,
|
||||
void* udata);
|
||||
|
||||
/* A non-zero value for only_if_not_set means that the save
|
||||
* pipeline will only be changed if it is not already set.
|
||||
*/
|
||||
QPDF_DLL
|
||||
void qpdflogger_set_save(
|
||||
qpdflogger_handle l,
|
||||
enum qpdf_log_dest_e dest,
|
||||
qpdf_log_fn_t fn,
|
||||
void* udata,
|
||||
int only_if_not_set);
|
||||
QPDF_DLL
|
||||
void qpdflogger_save_to_standard_output(
|
||||
qpdflogger_handle l, int only_if_not_set);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // QPDFLOGGER_H
|
@ -110,7 +110,8 @@ set(libqpdf_SOURCES
|
||||
SF_FlateLzwDecode.cc
|
||||
SparseOHArray.cc
|
||||
qpdf-c.cc
|
||||
qpdfjob-c.cc)
|
||||
qpdfjob-c.cc
|
||||
qpdflogger-c.cc)
|
||||
|
||||
include(FindPkgConfig)
|
||||
include(CheckTypeSize)
|
||||
|
@ -710,7 +710,7 @@ QPDFJob::checkConfiguration()
|
||||
save_to_stdout = true;
|
||||
}
|
||||
if (save_to_stdout) {
|
||||
this->m->log->saveToStandardOutput();
|
||||
this->m->log->saveToStandardOutput(true);
|
||||
}
|
||||
if ((!m->split_pages) &&
|
||||
QUtil::same_file(m->infilename.get(), m->outfilename.get())) {
|
||||
@ -925,7 +925,7 @@ QPDFJob::doShowObj(QPDF& pdf)
|
||||
} else {
|
||||
// If anything has been written to standard output,
|
||||
// this will fail.
|
||||
this->m->log->saveToStandardOutput();
|
||||
this->m->log->saveToStandardOutput(true);
|
||||
obj.pipeStreamData(
|
||||
this->m->log->getSave().get(),
|
||||
(filter && m->normalize) ? qpdf_ef_normalize : 0,
|
||||
@ -1031,7 +1031,7 @@ QPDFJob::doShowAttachment(QPDF& pdf)
|
||||
auto efs = fs->getEmbeddedFileStream();
|
||||
// saveToStandardOutput has already been called, but it's harmless
|
||||
// to call it again, so do as defensive coding.
|
||||
this->m->log->saveToStandardOutput();
|
||||
this->m->log->saveToStandardOutput(true);
|
||||
efs.pipeStreamData(this->m->log->getSave().get(), 0, qpdf_dl_all);
|
||||
}
|
||||
|
||||
@ -3289,7 +3289,7 @@ QPDFJob::writeOutfile(QPDF& pdf)
|
||||
} else {
|
||||
// saveToStandardOutput has already been called, but
|
||||
// calling it again is defensive and harmless.
|
||||
this->m->log->saveToStandardOutput();
|
||||
this->m->log->saveToStandardOutput(true);
|
||||
w.setOutputPipeline(this->m->log->getSave().get());
|
||||
}
|
||||
setWriterOptions(pdf, w);
|
||||
|
@ -181,8 +181,11 @@ QPDFLogger::setError(std::shared_ptr<Pipeline> p)
|
||||
}
|
||||
|
||||
void
|
||||
QPDFLogger::setSave(std::shared_ptr<Pipeline> p)
|
||||
QPDFLogger::setSave(std::shared_ptr<Pipeline> p, bool only_if_not_set)
|
||||
{
|
||||
if (only_if_not_set && (this->m->p_save != nullptr)) {
|
||||
return;
|
||||
}
|
||||
if (this->m->p_save == p) {
|
||||
return;
|
||||
}
|
||||
@ -202,9 +205,9 @@ QPDFLogger::setSave(std::shared_ptr<Pipeline> p)
|
||||
}
|
||||
|
||||
void
|
||||
QPDFLogger::saveToStandardOutput()
|
||||
QPDFLogger::saveToStandardOutput(bool only_if_not_set)
|
||||
{
|
||||
setSave(standardOutput());
|
||||
setSave(standardOutput(), only_if_not_set);
|
||||
}
|
||||
|
||||
void
|
||||
|
163
libqpdf/qpdflogger-c.cc
Normal file
163
libqpdf/qpdflogger-c.cc
Normal file
@ -0,0 +1,163 @@
|
||||
#include <qpdf/qpdflogger-c.h>
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
#include <qpdf/QIntC.hh>
|
||||
#include <qpdf/QPDFLogger.hh>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
struct _qpdflogger_handle
|
||||
{
|
||||
_qpdflogger_handle(std::shared_ptr<QPDFLogger> l);
|
||||
~_qpdflogger_handle() = default;
|
||||
|
||||
std::shared_ptr<QPDFLogger> l;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
class FunctionPipeline: public Pipeline
|
||||
{
|
||||
public:
|
||||
FunctionPipeline(char const* identifier, qpdf_log_fn_t fn, void* udata);
|
||||
virtual ~FunctionPipeline() = default;
|
||||
|
||||
virtual void write(unsigned char const* buf, size_t len) override;
|
||||
virtual void finish() override;
|
||||
|
||||
private:
|
||||
qpdf_log_fn_t fn;
|
||||
void* udata;
|
||||
};
|
||||
}; // namespace
|
||||
|
||||
FunctionPipeline::FunctionPipeline(
|
||||
char const* identifier, qpdf_log_fn_t fn, void* udata) :
|
||||
Pipeline(identifier, nullptr),
|
||||
fn(fn),
|
||||
udata(udata)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
FunctionPipeline::write(unsigned char const* buf, size_t len)
|
||||
{
|
||||
fn(reinterpret_cast<char const*>(buf), QIntC::to_ulong(len), udata);
|
||||
}
|
||||
|
||||
void
|
||||
FunctionPipeline::finish()
|
||||
{
|
||||
// Nothing needed
|
||||
}
|
||||
|
||||
_qpdflogger_handle::_qpdflogger_handle(std::shared_ptr<QPDFLogger> l) :
|
||||
l(l)
|
||||
{
|
||||
}
|
||||
|
||||
qpdflogger_handle
|
||||
qpdflogger_default_logger()
|
||||
{
|
||||
return new _qpdflogger_handle(QPDFLogger::defaultLogger());
|
||||
}
|
||||
|
||||
void
|
||||
qpdflogger_cleanup(qpdflogger_handle* l)
|
||||
{
|
||||
delete *l;
|
||||
*l = nullptr;
|
||||
}
|
||||
|
||||
static void
|
||||
set_log_dest(
|
||||
QPDFLogger* l,
|
||||
std::function<void(std::shared_ptr<Pipeline>)> method,
|
||||
qpdf_log_dest_e dest,
|
||||
char const* identifier,
|
||||
qpdf_log_fn_t fn,
|
||||
void* udata)
|
||||
{
|
||||
switch (dest) {
|
||||
case qpdf_log_dest_default:
|
||||
method(nullptr);
|
||||
break;
|
||||
case qpdf_log_dest_stdout:
|
||||
method(l->standardOutput());
|
||||
break;
|
||||
case qpdf_log_dest_stderr:
|
||||
method(l->standardError());
|
||||
break;
|
||||
case qpdf_log_dest_discard:
|
||||
method(l->discard());
|
||||
break;
|
||||
case qpdf_log_dest_custom:
|
||||
method(std::make_shared<FunctionPipeline>(identifier, fn, udata));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_log_dest(
|
||||
QPDFLogger* l,
|
||||
void (QPDFLogger::*method)(std::shared_ptr<Pipeline>),
|
||||
qpdf_log_dest_e dest,
|
||||
char const* identifier,
|
||||
qpdf_log_fn_t fn,
|
||||
void* udata)
|
||||
{
|
||||
set_log_dest(
|
||||
l,
|
||||
std::bind(std::mem_fn(method), l, std::placeholders::_1),
|
||||
dest,
|
||||
identifier,
|
||||
fn,
|
||||
udata);
|
||||
}
|
||||
|
||||
void
|
||||
qpdflogger_set_info(
|
||||
qpdflogger_handle l, qpdf_log_dest_e dest, qpdf_log_fn_t fn, void* udata)
|
||||
{
|
||||
set_log_dest(
|
||||
l->l.get(), &QPDFLogger::setInfo, dest, "info logger", fn, udata);
|
||||
}
|
||||
|
||||
void
|
||||
qpdflogger_set_warn(
|
||||
qpdflogger_handle l, qpdf_log_dest_e dest, qpdf_log_fn_t fn, void* udata)
|
||||
{
|
||||
set_log_dest(
|
||||
l->l.get(), &QPDFLogger::setWarn, dest, "warn logger", fn, udata);
|
||||
}
|
||||
|
||||
void
|
||||
qpdflogger_set_error(
|
||||
qpdflogger_handle l, qpdf_log_dest_e dest, qpdf_log_fn_t fn, void* udata)
|
||||
{
|
||||
set_log_dest(
|
||||
l->l.get(), &QPDFLogger::setError, dest, "error logger", fn, udata);
|
||||
}
|
||||
|
||||
void
|
||||
qpdflogger_set_save(
|
||||
qpdflogger_handle l,
|
||||
qpdf_log_dest_e dest,
|
||||
qpdf_log_fn_t fn,
|
||||
void* udata,
|
||||
int only_if_not_set)
|
||||
{
|
||||
auto method = std::bind(
|
||||
std::mem_fn(&QPDFLogger::setSave),
|
||||
l->l.get(),
|
||||
std::placeholders::_1,
|
||||
only_if_not_set);
|
||||
set_log_dest(l->l.get(), method, dest, "save logger", fn, udata);
|
||||
}
|
||||
|
||||
void
|
||||
qpdflogger_save_to_standard_output(qpdflogger_handle l, int only_if_not_set)
|
||||
{
|
||||
qpdflogger_set_save(
|
||||
l, qpdf_log_dest_stdout, nullptr, nullptr, only_if_not_set);
|
||||
}
|
@ -33,10 +33,18 @@ set(TEST_PROGRAMS
|
||||
runlength
|
||||
sha2
|
||||
sparse_array)
|
||||
set(TEST_C_PROGRAMS
|
||||
logger_c)
|
||||
|
||||
foreach(PROG ${TEST_PROGRAMS})
|
||||
add_executable(${PROG} ${PROG}.cc)
|
||||
target_link_libraries(${PROG} libqpdf_object)
|
||||
endforeach()
|
||||
foreach(PROG ${TEST_C_PROGRAMS})
|
||||
add_executable(${PROG} ${PROG}.c)
|
||||
target_link_libraries(${PROG} libqpdf_object)
|
||||
set_property(TARGET ${PROG} PROPERTY LINKER_LANGUAGE CXX)
|
||||
endforeach()
|
||||
|
||||
# Since libtests link with the object library and don't use the DLL,
|
||||
# we don't need to (and shouldn't) add the libqpdf target directory to
|
||||
|
@ -22,7 +22,7 @@ test1()
|
||||
*(logger->getInfo()) << "getSave exception: " << e.what() << "\n";
|
||||
}
|
||||
try {
|
||||
logger->saveToStandardOutput();
|
||||
logger->saveToStandardOutput(true);
|
||||
assert(false);
|
||||
} catch (std::logic_error& e) {
|
||||
*(logger->getInfo())
|
||||
@ -40,12 +40,12 @@ test2()
|
||||
// First call saveToStandardOutput. Then use info, which then to
|
||||
// go stderr.
|
||||
QPDFLogger l;
|
||||
l.saveToStandardOutput();
|
||||
l.saveToStandardOutput(true);
|
||||
l.info(std::string("info to stderr\n"));
|
||||
*(l.getSave()) << "save to stdout\n";
|
||||
l.setInfo(nullptr);
|
||||
l.info("info still to stderr\n");
|
||||
l.setSave(nullptr);
|
||||
l.setSave(nullptr, false);
|
||||
l.setInfo(nullptr);
|
||||
l.info("info back to stdout\n");
|
||||
}
|
||||
|
108
libtests/logger_c.c
Normal file
108
libtests/logger_c.c
Normal file
@ -0,0 +1,108 @@
|
||||
#include <qpdf/assert_test.h>
|
||||
|
||||
#include <qpdf/qpdflogger-c.h>
|
||||
|
||||
#include <qpdf/Constants.h>
|
||||
#include <qpdf/qpdfjob-c.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void
|
||||
fn(char const* data, size_t len, void* udata)
|
||||
{
|
||||
FILE* f = (FILE*)udata;
|
||||
fwrite(data, 1, len, f);
|
||||
}
|
||||
|
||||
static void
|
||||
do_run(char const* json, int exp_status)
|
||||
{
|
||||
int status = qpdfjob_run_from_json(json);
|
||||
assert(status == exp_status);
|
||||
}
|
||||
|
||||
static FILE*
|
||||
do_fopen(char const* filename)
|
||||
{
|
||||
FILE* f = NULL;
|
||||
#ifdef _MSC_VER
|
||||
if (fopen_s(&f, filename, "wb") != 0) {
|
||||
f = NULL;
|
||||
}
|
||||
#else
|
||||
f = fopen(filename, "wb");
|
||||
#endif
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "unable to open %s\n", filename);
|
||||
exit(2);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
FILE* info = do_fopen("info");
|
||||
FILE* warn = do_fopen("warn");
|
||||
FILE* error = do_fopen("error");
|
||||
FILE* save = do_fopen("save");
|
||||
FILE* save2 = do_fopen("save2");
|
||||
qpdflogger_handle l = qpdflogger_default_logger();
|
||||
|
||||
qpdflogger_set_info(l, qpdf_log_dest_custom, fn, (void*)info);
|
||||
qpdflogger_set_warn(l, qpdf_log_dest_custom, fn, (void*)warn);
|
||||
qpdflogger_set_error(l, qpdf_log_dest_custom, fn, (void*)error);
|
||||
qpdflogger_set_save(l, qpdf_log_dest_custom, fn, (void*)save, 0);
|
||||
|
||||
do_run(
|
||||
"{\"inputFile\": \"normal.pdf\", \"showNpages\": \"\"}",
|
||||
qpdf_exit_success);
|
||||
do_run(
|
||||
"{\"inputFile\": \"warning.pdf\", \"showNpages\": \"\"}",
|
||||
qpdf_exit_warning);
|
||||
do_run(
|
||||
"{\"inputFile\": \"missing.pdf\", \"showNpages\": \"\"}",
|
||||
qpdf_exit_error);
|
||||
do_run(
|
||||
"{\"inputFile\": \"normal.pdf\","
|
||||
" \"staticId\": \"\","
|
||||
" \"outputFile\": \"-\"}",
|
||||
qpdf_exit_success);
|
||||
|
||||
fclose(info);
|
||||
fclose(warn);
|
||||
fclose(error);
|
||||
fclose(save);
|
||||
|
||||
qpdflogger_set_info(l, qpdf_log_dest_stderr, NULL, NULL);
|
||||
qpdflogger_set_warn(l, qpdf_log_dest_stdout, NULL, NULL);
|
||||
qpdflogger_set_error(l, qpdf_log_dest_default, NULL, NULL);
|
||||
qpdflogger_set_save(l, qpdf_log_dest_custom, fn, (void*)save2, 0);
|
||||
|
||||
do_run(
|
||||
"{\"inputFile\": \"2pages.pdf\", \"showNpages\": \"\"}",
|
||||
qpdf_exit_success);
|
||||
do_run(
|
||||
"{\"inputFile\": \"warning.pdf\", \"showNpages\": \"\"}",
|
||||
qpdf_exit_warning);
|
||||
do_run(
|
||||
|
||||
"{\"inputFile\": \"missing.pdf\", \"showNpages\": \"\"}",
|
||||
qpdf_exit_error);
|
||||
do_run(
|
||||
"{\"inputFile\": \"attach.pdf\","
|
||||
" \"showAttachment\": \"a\"}",
|
||||
qpdf_exit_success);
|
||||
|
||||
/* This won't change save since it's already set */
|
||||
qpdflogger_save_to_standard_output(l, 1);
|
||||
do_run(
|
||||
"{\"inputFile\": \"attach.pdf\","
|
||||
" \"showAttachment\": \"a\"}",
|
||||
qpdf_exit_success);
|
||||
|
||||
qpdflogger_cleanup(&l);
|
||||
|
||||
return 0;
|
||||
}
|
@ -24,10 +24,22 @@ $td->runtest("check stderr",
|
||||
{$td->FILE => "exp-stderr"},
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
|
||||
$td->runtest("logger C API",
|
||||
{$td->COMMAND => "logger_c >stdout 2>stderr"},
|
||||
{$td->STRING => "", $td->EXIT_STATUS => 0},
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
foreach my $f (qw(stdout stderr info warn error save save2))
|
||||
{
|
||||
$td->runtest("check $f (C)",
|
||||
{$td->FILE => "$f"},
|
||||
{$td->FILE => "c-exp-$f"},
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
}
|
||||
|
||||
cleanup();
|
||||
$td->report(3);
|
||||
$td->report(11);
|
||||
|
||||
sub cleanup
|
||||
{
|
||||
unlink "stdout", "stderr";
|
||||
unlink "stdout", "stderr", "info", "warn", "error", "save", "save2";
|
||||
}
|
||||
|
BIN
libtests/qtest/logger/2pages.pdf
Normal file
BIN
libtests/qtest/logger/2pages.pdf
Normal file
Binary file not shown.
BIN
libtests/qtest/logger/attach.pdf
Normal file
BIN
libtests/qtest/logger/attach.pdf
Normal file
Binary file not shown.
1
libtests/qtest/logger/c-exp-error
Normal file
1
libtests/qtest/logger/c-exp-error
Normal file
@ -0,0 +1 @@
|
||||
qpdfjob json: open missing.pdf: No such file or directory
|
2
libtests/qtest/logger/c-exp-info
Normal file
2
libtests/qtest/logger/c-exp-info
Normal file
@ -0,0 +1,2 @@
|
||||
1
|
||||
1
|
BIN
libtests/qtest/logger/c-exp-save
Normal file
BIN
libtests/qtest/logger/c-exp-save
Normal file
Binary file not shown.
2
libtests/qtest/logger/c-exp-save2
Normal file
2
libtests/qtest/logger/c-exp-save2
Normal file
@ -0,0 +1,2 @@
|
||||
quack
|
||||
quack
|
3
libtests/qtest/logger/c-exp-stderr
Normal file
3
libtests/qtest/logger/c-exp-stderr
Normal file
@ -0,0 +1,3 @@
|
||||
2
|
||||
1
|
||||
qpdfjob json: open missing.pdf: No such file or directory
|
4
libtests/qtest/logger/c-exp-stdout
Normal file
4
libtests/qtest/logger/c-exp-stdout
Normal file
@ -0,0 +1,4 @@
|
||||
WARNING: warning.pdf: file is damaged
|
||||
WARNING: warning.pdf (offset 1556): xref not found
|
||||
WARNING: warning.pdf: Attempting to reconstruct cross-reference table
|
||||
qpdfjob json: operation succeeded with warnings
|
4
libtests/qtest/logger/c-exp-warn
Normal file
4
libtests/qtest/logger/c-exp-warn
Normal file
@ -0,0 +1,4 @@
|
||||
WARNING: warning.pdf: file is damaged
|
||||
WARNING: warning.pdf (offset 1556): xref not found
|
||||
WARNING: warning.pdf: Attempting to reconstruct cross-reference table
|
||||
qpdfjob json: operation succeeded with warnings
|
79
libtests/qtest/logger/normal.pdf
Normal file
79
libtests/qtest/logger/normal.pdf
Normal file
@ -0,0 +1,79 @@
|
||||
%PDF-1.3
|
||||
1 0 obj
|
||||
<<
|
||||
/Type /Catalog
|
||||
/Pages 2 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<<
|
||||
/Type /Pages
|
||||
/Kids [
|
||||
3 0 R
|
||||
]
|
||||
/Count 1
|
||||
>>
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
<<
|
||||
/Type /Page
|
||||
/Parent 2 0 R
|
||||
/MediaBox [0 0 612 792]
|
||||
/Contents 4 0 R
|
||||
/Resources <<
|
||||
/ProcSet 5 0 R
|
||||
/Font <<
|
||||
/F1 6 0 R
|
||||
>>
|
||||
>>
|
||||
>>
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<<
|
||||
/Length 44
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
/F1 24 Tf
|
||||
72 720 Td
|
||||
(Potato) Tj
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
[
|
||||
/PDF
|
||||
/Text
|
||||
]
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<<
|
||||
/Type /Font
|
||||
/Subtype /Type1
|
||||
/Name /F1
|
||||
/BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000009 00000 n
|
||||
0000000063 00000 n
|
||||
0000000135 00000 n
|
||||
0000000307 00000 n
|
||||
0000000403 00000 n
|
||||
0000000438 00000 n
|
||||
trailer <<
|
||||
/Size 7
|
||||
/Root 1 0 R
|
||||
>>
|
||||
startxref
|
||||
556
|
||||
%%EOF
|
79
libtests/qtest/logger/warning.pdf
Normal file
79
libtests/qtest/logger/warning.pdf
Normal file
@ -0,0 +1,79 @@
|
||||
%PDF-1.3
|
||||
1 0 obj
|
||||
<<
|
||||
/Type /Catalog
|
||||
/Pages 2 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<<
|
||||
/Type /Pages
|
||||
/Kids [
|
||||
3 0 R
|
||||
]
|
||||
/Count 1
|
||||
>>
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
<<
|
||||
/Type /Page
|
||||
/Parent 2 0 R
|
||||
/MediaBox [0 0 612 792]
|
||||
/Contents 4 0 R
|
||||
/Resources <<
|
||||
/ProcSet 5 0 R
|
||||
/Font <<
|
||||
/F1 6 0 R
|
||||
>>
|
||||
>>
|
||||
>>
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<<
|
||||
/Length 44
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
/F1 24 Tf
|
||||
72 720 Td
|
||||
(Potato) Tj
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
[
|
||||
/PDF
|
||||
/Text
|
||||
]
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<<
|
||||
/Type /Font
|
||||
/Subtype /Type1
|
||||
/Name /F1
|
||||
/BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000009 00000 n
|
||||
0000000063 00000 n
|
||||
0000000135 00000 n
|
||||
0000000307 00000 n
|
||||
0000000403 00000 n
|
||||
0000000438 00000 n
|
||||
trailer <<
|
||||
/Size 7
|
||||
/Root 1 0 R
|
||||
>>
|
||||
startxref
|
||||
1556
|
||||
%%EOF
|
@ -158,6 +158,8 @@ For a detailed list of changes, please see the file
|
||||
output and errors that slipped through the cracks with
|
||||
``setOutputStreams``.
|
||||
|
||||
- A C API is available in :file:`include/qpdf/qpdflogger-c.h`.
|
||||
|
||||
- New methods ``insertItemAndGet``, ``appendItemAndGet``,
|
||||
``eraseItemAndGet``, ``replaceKeyAndGet``, and
|
||||
``removeKeyAndGet`` return the newly added or removed object.
|
||||
|
Loading…
Reference in New Issue
Block a user