mirror of
https://github.com/qpdf/qpdf.git
synced 2024-11-11 07:30:57 +00:00
Add optional parameter separator to QPDFObjGen::unparse
Also, revert inlining of unparse and operator << from commit 4c6640c
in
order to avoid exposing QUtil.
This commit is contained in:
parent
6f1041afb8
commit
eeb6162f76
@ -23,7 +23,6 @@
|
|||||||
#define QPDFOBJGEN_HH
|
#define QPDFOBJGEN_HH
|
||||||
|
|
||||||
#include <qpdf/DLL.h>
|
#include <qpdf/DLL.h>
|
||||||
#include <qpdf/QUtil.hh>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// This class represents an object ID and generation pair. It is
|
// This class represents an object ID and generation pair. It is
|
||||||
@ -69,18 +68,9 @@ class QPDFObjGen
|
|||||||
return gen;
|
return gen;
|
||||||
}
|
}
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
std::string
|
std::string unparse(char separator = ',') const;
|
||||||
unparse() const
|
|
||||||
{
|
|
||||||
return QUtil::int_to_string(obj) + "," + QUtil::int_to_string(gen);
|
|
||||||
}
|
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
friend std::ostream&
|
friend std::ostream& operator<<(std::ostream& os, const QPDFObjGen& og);
|
||||||
operator<<(std::ostream& os, const QPDFObjGen& og)
|
|
||||||
{
|
|
||||||
os << og.obj << "," << og.gen;
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This class does not use the Members pattern to avoid a memory
|
// This class does not use the Members pattern to avoid a memory
|
||||||
|
@ -1584,7 +1584,6 @@ class QPDFObjectHandle
|
|||||||
bool stop_at_streams);
|
bool stop_at_streams);
|
||||||
void shallowCopyInternal(QPDFObjectHandle& oh, bool first_level_only);
|
void shallowCopyInternal(QPDFObjectHandle& oh, bool first_level_only);
|
||||||
void releaseResolved();
|
void releaseResolved();
|
||||||
std::string getObjGenAsStr() const;
|
|
||||||
static void setObjectDescriptionFromInput(
|
static void setObjectDescriptionFromInput(
|
||||||
QPDFObjectHandle,
|
QPDFObjectHandle,
|
||||||
QPDF*,
|
QPDF*,
|
||||||
|
@ -74,6 +74,7 @@ set(libqpdf_SOURCES
|
|||||||
QPDFNumberTreeObjectHelper.cc
|
QPDFNumberTreeObjectHelper.cc
|
||||||
QPDFObject.cc
|
QPDFObject.cc
|
||||||
QPDFObjectHandle.cc
|
QPDFObjectHandle.cc
|
||||||
|
QPDFObjGen.cc
|
||||||
QPDFOutlineDocumentHelper.cc
|
QPDFOutlineDocumentHelper.cc
|
||||||
QPDFOutlineObjectHelper.cc
|
QPDFOutlineObjectHelper.cc
|
||||||
QPDFPageDocumentHelper.cc
|
QPDFPageDocumentHelper.cc
|
||||||
|
@ -1493,9 +1493,8 @@ QPDF::setLastObjectDescription(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (objid > 0) {
|
if (objid > 0) {
|
||||||
this->m->last_object_description += "object " +
|
this->m->last_object_description +=
|
||||||
QUtil::int_to_string(objid) + " " +
|
"object " + QPDFObjGen(objid, generation).unparse(' ');
|
||||||
QUtil::int_to_string(generation);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1862,8 +1861,8 @@ QPDF::readObjectAtOffset(
|
|||||||
this->m->file->getName(),
|
this->m->file->getName(),
|
||||||
this->m->last_object_description,
|
this->m->last_object_description,
|
||||||
offset,
|
offset,
|
||||||
(std::string("expected ") + QUtil::int_to_string(exp_objid) +
|
(std::string("expected ") +
|
||||||
" " + QUtil::int_to_string(exp_generation) + " obj"));
|
QPDFObjGen(exp_objid, exp_generation).unparse(' ') + " obj"));
|
||||||
if (try_recovery) {
|
if (try_recovery) {
|
||||||
// Will be retried below
|
// Will be retried below
|
||||||
throw e;
|
throw e;
|
||||||
@ -1898,8 +1897,8 @@ QPDF::readObjectAtOffset(
|
|||||||
"",
|
"",
|
||||||
0,
|
0,
|
||||||
std::string(
|
std::string(
|
||||||
"object " + QUtil::int_to_string(exp_objid) + " " +
|
"object " +
|
||||||
QUtil::int_to_string(exp_generation) +
|
QPDFObjGen(exp_objid, exp_generation).unparse(' ') +
|
||||||
" not found in file after regenerating"
|
" not found in file after regenerating"
|
||||||
" cross reference table"));
|
" cross reference table"));
|
||||||
return QPDFObjectHandle::newNull();
|
return QPDFObjectHandle::newNull();
|
||||||
@ -2002,8 +2001,7 @@ QPDF::resolve(int objid, int generation)
|
|||||||
qpdf_e_damaged_pdf,
|
qpdf_e_damaged_pdf,
|
||||||
"",
|
"",
|
||||||
this->m->file->getLastOffset(),
|
this->m->file->getLastOffset(),
|
||||||
("loop detected resolving object " + QUtil::int_to_string(objid) +
|
("loop detected resolving object " + og.unparse(' ')));
|
||||||
" " + QUtil::int_to_string(generation)));
|
|
||||||
return QPDF_Null::create();
|
return QPDF_Null::create();
|
||||||
}
|
}
|
||||||
ResolveRecorder rr(this, og);
|
ResolveRecorder rr(this, og);
|
||||||
@ -2039,8 +2037,7 @@ QPDF::resolve(int objid, int generation)
|
|||||||
this->m->file->getName(),
|
this->m->file->getName(),
|
||||||
"",
|
"",
|
||||||
0,
|
0,
|
||||||
("object " + QUtil::int_to_string(objid) + "/" +
|
("object " + og.unparse('/') +
|
||||||
QUtil::int_to_string(generation) +
|
|
||||||
" has unexpected xref entry type"));
|
" has unexpected xref entry type"));
|
||||||
}
|
}
|
||||||
} catch (QPDFExc& e) {
|
} catch (QPDFExc& e) {
|
||||||
@ -2050,8 +2047,7 @@ QPDF::resolve(int objid, int generation)
|
|||||||
qpdf_e_damaged_pdf,
|
qpdf_e_damaged_pdf,
|
||||||
"",
|
"",
|
||||||
0,
|
0,
|
||||||
("object " + QUtil::int_to_string(objid) + "/" +
|
("object " + og.unparse('/') +
|
||||||
QUtil::int_to_string(generation) +
|
|
||||||
": error reading object: " + e.what()));
|
": error reading object: " + e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2065,10 +2061,7 @@ QPDF::resolve(int objid, int generation)
|
|||||||
|
|
||||||
std::shared_ptr<QPDFObject> result(this->m->obj_cache[og].object);
|
std::shared_ptr<QPDFObject> result(this->m->obj_cache[og].object);
|
||||||
if (!result->hasDescription()) {
|
if (!result->hasDescription()) {
|
||||||
result->setDescription(
|
result->setDescription(this, ("object " + og.unparse(' ')));
|
||||||
this,
|
|
||||||
("object " + QUtil::int_to_string(objid) + " " +
|
|
||||||
QUtil::int_to_string(generation)));
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -2809,8 +2802,8 @@ QPDF::pipeStreamData(
|
|||||||
"",
|
"",
|
||||||
file->getLastOffset(),
|
file->getLastOffset(),
|
||||||
("error decoding stream data for object " +
|
("error decoding stream data for object " +
|
||||||
QUtil::int_to_string(objid) + " " +
|
QPDFObjGen(objid, generation).unparse(' ') + ": " +
|
||||||
QUtil::int_to_string(generation) + ": " + e.what())));
|
e.what())));
|
||||||
if (will_retry) {
|
if (will_retry) {
|
||||||
qpdf_for_warning.warn(
|
qpdf_for_warning.warn(
|
||||||
// line-break
|
// line-break
|
||||||
|
@ -991,8 +991,8 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
|
|||||||
} else {
|
} else {
|
||||||
parent.warnIfPossible(
|
parent.warnIfPossible(
|
||||||
"while traversing field " +
|
"while traversing field " +
|
||||||
obj.getObjGen().unparse() + ", found parent (" +
|
obj.getObjGen().unparse(',') + ", found parent (" +
|
||||||
parent_og.unparse() +
|
parent_og.unparse(',') +
|
||||||
") that had not been seen, indicating likely"
|
") that had not been seen, indicating likely"
|
||||||
" invalid field structure");
|
" invalid field structure");
|
||||||
}
|
}
|
||||||
|
@ -947,7 +947,7 @@ QPDFJob::doShowObj(QPDF& pdf)
|
|||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"unable to get object " + obj.getObjGen().unparse());
|
"unable to get object " + obj.getObjGen().unparse(','));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -995,7 +995,8 @@ QPDFJob::doListAttachments(QPDF& pdf)
|
|||||||
auto efoh = i.second;
|
auto efoh = i.second;
|
||||||
*this->m->log->getInfo()
|
*this->m->log->getInfo()
|
||||||
<< key << " -> "
|
<< key << " -> "
|
||||||
<< efoh->getEmbeddedFileStream().getObjGen().unparse() << "\n";
|
<< efoh->getEmbeddedFileStream().getObjGen().unparse(',')
|
||||||
|
<< "\n";
|
||||||
doIfVerbose([&](Pipeline& v, std::string const& prefix) {
|
doIfVerbose([&](Pipeline& v, std::string const& prefix) {
|
||||||
auto desc = efoh->getDescription();
|
auto desc = efoh->getDescription();
|
||||||
if (!desc.empty()) {
|
if (!desc.empty()) {
|
||||||
@ -1010,7 +1011,7 @@ QPDFJob::doListAttachments(QPDF& pdf)
|
|||||||
for (auto i2: efoh->getEmbeddedFileStreams().ditems()) {
|
for (auto i2: efoh->getEmbeddedFileStreams().ditems()) {
|
||||||
auto efs = QPDFEFStreamObjectHelper(i2.second);
|
auto efs = QPDFEFStreamObjectHelper(i2.second);
|
||||||
v << " " << i2.first << " -> "
|
v << " " << i2.first << " -> "
|
||||||
<< efs.getObjectHandle().getObjGen().unparse() << "\n";
|
<< efs.getObjectHandle().getObjGen().unparse(',') << "\n";
|
||||||
v << " creation date: " << efs.getCreationDate()
|
v << " creation date: " << efs.getCreationDate()
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< " modification date: " << efs.getModDate() << "\n"
|
<< " modification date: " << efs.getModDate() << "\n"
|
||||||
|
17
libqpdf/QPDFObjGen.cc
Normal file
17
libqpdf/QPDFObjGen.cc
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include <qpdf/QPDFObjGen.hh>
|
||||||
|
|
||||||
|
#include <qpdf/QUtil.hh>
|
||||||
|
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream& os, const QPDFObjGen& og)
|
||||||
|
{
|
||||||
|
os << og.obj << "," << og.gen;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
QPDFObjGen::unparse(char separator) const
|
||||||
|
{
|
||||||
|
return QUtil::int_to_string(this->obj) + separator +
|
||||||
|
QUtil::int_to_string(this->gen);
|
||||||
|
}
|
@ -103,9 +103,8 @@ void
|
|||||||
CoalesceProvider::provideStreamData(int, int, Pipeline* p)
|
CoalesceProvider::provideStreamData(int, int, Pipeline* p)
|
||||||
{
|
{
|
||||||
QTC::TC("qpdf", "QPDFObjectHandle coalesce provide stream data");
|
QTC::TC("qpdf", "QPDFObjectHandle coalesce provide stream data");
|
||||||
std::string description = "page object " +
|
std::string description =
|
||||||
QUtil::int_to_string(containing_page.getObjectID()) + " " +
|
"page object " + containing_page.getObjGen().unparse(' ');
|
||||||
QUtil::int_to_string(containing_page.getGeneration());
|
|
||||||
std::string all_description;
|
std::string all_description;
|
||||||
old_contents.pipeContentStreams(p, description, all_description);
|
old_contents.pipeContentStreams(p, description, all_description);
|
||||||
}
|
}
|
||||||
@ -1485,13 +1484,6 @@ QPDFObjectHandle::getObjGen() const
|
|||||||
return QPDFObjGen(this->objid, this->generation);
|
return QPDFObjGen(this->objid, this->generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
|
||||||
QPDFObjectHandle::getObjGenAsStr() const
|
|
||||||
{
|
|
||||||
return QUtil::int_to_string(this->objid) + " " +
|
|
||||||
QUtil::int_to_string(this->generation);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
QPDFObjectHandle::getObjectID() const
|
QPDFObjectHandle::getObjectID() const
|
||||||
{
|
{
|
||||||
@ -1556,7 +1548,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray(
|
|||||||
} else {
|
} else {
|
||||||
all_description += ",";
|
all_description += ",";
|
||||||
}
|
}
|
||||||
all_description += " stream " + item.getObjGenAsStr();
|
all_description += " stream " + item.getObjGen().unparse(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -1565,7 +1557,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray(
|
|||||||
std::vector<QPDFObjectHandle>
|
std::vector<QPDFObjectHandle>
|
||||||
QPDFObjectHandle::getPageContents()
|
QPDFObjectHandle::getPageContents()
|
||||||
{
|
{
|
||||||
std::string description = "page object " + getObjGenAsStr();
|
std::string description = "page object " + getObjGen().unparse(' ');
|
||||||
std::string all_description;
|
std::string all_description;
|
||||||
return this->getKey("/Contents")
|
return this->getKey("/Contents")
|
||||||
.arrayOrStreamToStreamArray(description, all_description);
|
.arrayOrStreamToStreamArray(description, all_description);
|
||||||
@ -1674,7 +1666,7 @@ QPDFObjectHandle::unparse()
|
|||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
if (this->isIndirect()) {
|
if (this->isIndirect()) {
|
||||||
result = getObjGenAsStr() + " R";
|
result = getObjGen().unparse(' ') + " R";
|
||||||
} else {
|
} else {
|
||||||
result = unparseResolved();
|
result = unparseResolved();
|
||||||
}
|
}
|
||||||
@ -1789,7 +1781,7 @@ QPDFObjectHandle::parse(
|
|||||||
void
|
void
|
||||||
QPDFObjectHandle::pipePageContents(Pipeline* p)
|
QPDFObjectHandle::pipePageContents(Pipeline* p)
|
||||||
{
|
{
|
||||||
std::string description = "page object " + getObjGenAsStr();
|
std::string description = "page object " + getObjGen().unparse(' ');
|
||||||
std::string all_description;
|
std::string all_description;
|
||||||
this->getKey("/Contents")
|
this->getKey("/Contents")
|
||||||
.pipeContentStreams(p, description, all_description);
|
.pipeContentStreams(p, description, all_description);
|
||||||
@ -1813,7 +1805,7 @@ QPDFObjectHandle::pipeContentStreams(
|
|||||||
throw QPDFExc(
|
throw QPDFExc(
|
||||||
qpdf_e_damaged_pdf,
|
qpdf_e_damaged_pdf,
|
||||||
"content stream",
|
"content stream",
|
||||||
"content stream object " + stream.getObjGenAsStr(),
|
"content stream object " + stream.getObjGen().unparse(' '),
|
||||||
0,
|
0,
|
||||||
"errors while decoding content stream");
|
"errors while decoding content stream");
|
||||||
}
|
}
|
||||||
@ -1829,7 +1821,7 @@ QPDFObjectHandle::pipeContentStreams(
|
|||||||
void
|
void
|
||||||
QPDFObjectHandle::parsePageContents(ParserCallbacks* callbacks)
|
QPDFObjectHandle::parsePageContents(ParserCallbacks* callbacks)
|
||||||
{
|
{
|
||||||
std::string description = "page object " + getObjGenAsStr();
|
std::string description = "page object " + getObjGen().unparse(' ');
|
||||||
this->getKey("/Contents")
|
this->getKey("/Contents")
|
||||||
.parseContentStream_internal(description, callbacks);
|
.parseContentStream_internal(description, callbacks);
|
||||||
}
|
}
|
||||||
@ -1837,14 +1829,15 @@ QPDFObjectHandle::parsePageContents(ParserCallbacks* callbacks)
|
|||||||
void
|
void
|
||||||
QPDFObjectHandle::parseAsContents(ParserCallbacks* callbacks)
|
QPDFObjectHandle::parseAsContents(ParserCallbacks* callbacks)
|
||||||
{
|
{
|
||||||
std::string description = "object " + getObjGenAsStr();
|
std::string description = "object " + getObjGen().unparse(' ');
|
||||||
this->parseContentStream_internal(description, callbacks);
|
this->parseContentStream_internal(description, callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QPDFObjectHandle::filterPageContents(TokenFilter* filter, Pipeline* next)
|
QPDFObjectHandle::filterPageContents(TokenFilter* filter, Pipeline* next)
|
||||||
{
|
{
|
||||||
auto description = "token filter for page object " + getObjGenAsStr();
|
auto description =
|
||||||
|
"token filter for page object " + getObjGen().unparse(' ');
|
||||||
Pl_QPDFTokenizer token_pipeline(description.c_str(), filter, next);
|
Pl_QPDFTokenizer token_pipeline(description.c_str(), filter, next);
|
||||||
this->pipePageContents(&token_pipeline);
|
this->pipePageContents(&token_pipeline);
|
||||||
}
|
}
|
||||||
@ -1852,7 +1845,7 @@ QPDFObjectHandle::filterPageContents(TokenFilter* filter, Pipeline* next)
|
|||||||
void
|
void
|
||||||
QPDFObjectHandle::filterAsContents(TokenFilter* filter, Pipeline* next)
|
QPDFObjectHandle::filterAsContents(TokenFilter* filter, Pipeline* next)
|
||||||
{
|
{
|
||||||
auto description = "token filter for object " + getObjGenAsStr();
|
auto description = "token filter for object " + getObjGen().unparse(' ');
|
||||||
Pl_QPDFTokenizer token_pipeline(description.c_str(), filter, next);
|
Pl_QPDFTokenizer token_pipeline(description.c_str(), filter, next);
|
||||||
this->pipeStreamData(&token_pipeline, 0, qpdf_dl_specialized);
|
this->pipeStreamData(&token_pipeline, 0, qpdf_dl_specialized);
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,8 @@ void
|
|||||||
ContentProvider::provideStreamData(int, int, Pipeline* p)
|
ContentProvider::provideStreamData(int, int, Pipeline* p)
|
||||||
{
|
{
|
||||||
Pl_Concatenate concat("concatenate", p);
|
Pl_Concatenate concat("concatenate", p);
|
||||||
std::string description = "contents from page object " +
|
std::string description =
|
||||||
QUtil::int_to_string(from_page.getObjectID()) + " " +
|
"contents from page object " + from_page.getObjGen().unparse(' ');
|
||||||
QUtil::int_to_string(from_page.getGeneration());
|
|
||||||
std::string all_description;
|
std::string all_description;
|
||||||
from_page.getKey("/Contents")
|
from_page.getKey("/Contents")
|
||||||
.pipeContentStreams(&concat, description, all_description);
|
.pipeContentStreams(&concat, description, all_description);
|
||||||
|
@ -1990,9 +1990,8 @@ QPDFWriter::writeObject(QPDFObjectHandle object, int object_stream_index)
|
|||||||
if (object_stream_index == -1) {
|
if (object_stream_index == -1) {
|
||||||
if (this->m->qdf_mode && (!this->m->suppress_original_object_ids)) {
|
if (this->m->qdf_mode && (!this->m->suppress_original_object_ids)) {
|
||||||
writeString(
|
writeString(
|
||||||
"%% Original object ID: " +
|
"%% Original object ID: " + object.getObjGen().unparse(' ') +
|
||||||
QUtil::int_to_string(object.getObjectID()) + " " +
|
"\n");
|
||||||
QUtil::int_to_string(object.getGeneration()) + "\n");
|
|
||||||
}
|
}
|
||||||
openObject(new_id);
|
openObject(new_id);
|
||||||
setDataKey(new_id);
|
setDataKey(new_id);
|
||||||
|
@ -130,8 +130,7 @@ QPDF_Stream::QPDF_Stream(
|
|||||||
setDescription(
|
setDescription(
|
||||||
this->qpdf,
|
this->qpdf,
|
||||||
this->qpdf->getFilename() + ", stream object " +
|
this->qpdf->getFilename() + ", stream object " +
|
||||||
QUtil::int_to_string(this->objid) + " " +
|
QPDFObjGen(objid, generation).unparse(' '));
|
||||||
QUtil::int_to_string(this->generation));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<QPDFObject>
|
std::shared_ptr<QPDFObject>
|
||||||
@ -196,8 +195,7 @@ std::string
|
|||||||
QPDF_Stream::unparse()
|
QPDF_Stream::unparse()
|
||||||
{
|
{
|
||||||
// Unparse stream objects as indirect references
|
// Unparse stream objects as indirect references
|
||||||
return QUtil::int_to_string(this->objid) + " " +
|
return QPDFObjGen(objid, generation).unparse(' ') + " R";
|
||||||
QUtil::int_to_string(this->generation) + " R";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON
|
JSON
|
||||||
@ -643,8 +641,7 @@ QPDF_Stream::pipeStreamData(
|
|||||||
// part of a library user, not by invalid input data.
|
// part of a library user, not by invalid input data.
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"stream data provider for " +
|
"stream data provider for " +
|
||||||
QUtil::int_to_string(this->objid) + " " +
|
QPDFObjGen(objid, generation).unparse(' ') + " provided " +
|
||||||
QUtil::int_to_string(this->generation) + " provided " +
|
|
||||||
QUtil::int_to_string(actual_length) +
|
QUtil::int_to_string(actual_length) +
|
||||||
" bytes instead of expected " +
|
" bytes instead of expected " +
|
||||||
QUtil::int_to_string(desired_length) + " bytes");
|
QUtil::int_to_string(desired_length) + " bytes");
|
||||||
|
@ -1176,8 +1176,7 @@ QPDF::decryptString(std::string& str, int objid, int generation)
|
|||||||
this->m->last_object_description,
|
this->m->last_object_description,
|
||||||
this->m->file->getLastOffset(),
|
this->m->file->getLastOffset(),
|
||||||
"error decrypting string for object " +
|
"error decrypting string for object " +
|
||||||
QUtil::int_to_string(objid) + " " +
|
QPDFObjGen(objid, generation).unparse() + ": " + e.what());
|
||||||
QUtil::int_to_string(generation) + ": " + e.what());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user