diff --git a/examples/pdf-attach-file.cc b/examples/pdf-attach-file.cc index b5a1c64a..9ae3b247 100644 --- a/examples/pdf-attach-file.cc +++ b/examples/pdf-attach-file.cc @@ -8,11 +8,10 @@ #include // -// This example attaches a file to an input file, adds a page to the -// beginning of the file that includes a file attachment annotation, -// and writes the result to an output file. It also illustrates a -// number of new API calls that were added in qpdf 10.2 as well as -// the use of the qpdf literal syntax introduced in qpdf 10.6. +// This example attaches a file to an input file, adds a page to the beginning of the file that +// includes a file attachment annotation, and writes the result to an output file. It also +// illustrates a number of new API calls that were added in qpdf 10.2 as well as the use of the qpdf +// literal syntax introduced in qpdf 10.6. // static char const* whoami = nullptr; @@ -43,8 +42,8 @@ process( QPDF q; q.processFile(infilename, password); - // Create an indirect object for the built-in Helvetica font. This - // uses the qpdf literal syntax introduced in qpdf 10.6. + // Create an indirect object for the built-in Helvetica font. This uses the qpdf literal syntax + // introduced in qpdf 10.6. auto f1 = q.makeIndirectObject( // force line-break "<<" @@ -55,9 +54,8 @@ process( " /Encoding /WinAnsiEncoding" ">>"_qpdf); - // Create a resources dictionary with fonts. This uses the new - // parse introduced in qpdf 10.2 that takes a QPDF* and allows - // indirect object references. + // Create a resources dictionary with fonts. This uses the new parse introduced in qpdf 10.2 + // that takes a QPDF* and allows indirect object references. auto resources = q.makeIndirectObject( // line-break QPDFObjectHandle::parse( @@ -97,8 +95,8 @@ process( "S\n"); auto apdict = ap.getDict(); - // The following four lines demonstrate the use of the qpdf literal syntax - // introduced in qpdf 10.6. They could have been written as: + // The following four lines demonstrate the use of the qpdf literal syntax introduced in + // qpdf 10.6. They could have been written as: // apdict.replaceKey("/Resources", QPDFObjectHandle::newDictionary()); // apdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject")); // apdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form")); diff --git a/examples/pdf-bookmarks.cc b/examples/pdf-bookmarks.cc index d40ded6a..9581a135 100644 --- a/examples/pdf-bookmarks.cc +++ b/examples/pdf-bookmarks.cc @@ -8,9 +8,9 @@ #include #include -// This program demonstrates extraction of bookmarks using the qpdf -// outlines API. Note that all the information shown by this program -// can also be obtained from a PDF file using qpdf's --json option. +// This program demonstrates extraction of bookmarks using the qpdf outlines API. Note that all the +// information shown by this program can also be obtained from a PDF file using qpdf's --json +// option. // // Ignore calls to QTC::TC - they are for qpdf CI testing only. @@ -118,11 +118,10 @@ show_bookmark_details(QPDFOutlineObjectHelper outline, std::vector numbers) void extract_bookmarks(std::vector outlines, std::vector& numbers) { - // For style == st_numbers, numbers.at(n) contains the numerical - // label for the outline, so we count up from 1. - // For style == st_lines, numbers.at(n) == 0 indicates the last - // outline at level n, and we don't otherwise care what the value - // is, so we count up to zero. + // For style == st_numbers, numbers.at(n) contains the numerical label for the outline, so we + // count up from 1. + // For style == st_lines, numbers.at(n) == 0 indicates the last outline at level n, and we don't + // otherwise care what the value is, so we count up to zero. numbers.push_back((style == st_lines) ? -QIntC::to_int(outlines.size()) : 0); for (auto& outline: outlines) { ++(numbers.back()); diff --git a/examples/pdf-c-objects.c b/examples/pdf-c-objects.c index f4b872a7..171a9b66 100644 --- a/examples/pdf-c-objects.c +++ b/examples/pdf-c-objects.c @@ -1,7 +1,4 @@ -/* - * This is an example program to demonstrate use of object handle - * functions in the C API. - */ +/* This is an example program to demonstrate use of object handle functions in the C API. */ #include #include @@ -20,8 +17,7 @@ usage() QPDF_BOOL modify_file(qpdf_data qpdf) { - /* This small example performs the following operation on the - * document catalog (a.k.a. root): + /* This small example performs the following operation on the document catalog (a.k.a. root): * - Remove PageLayout * - Remove OpenAction * - If there are outlines, set PageMode to UseOutlines; otherwise, @@ -72,8 +68,7 @@ main(int argc, char* argv[]) if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) && modify_file(qpdf) && ((qpdf_init_write(qpdf, outfile) & QPDF_ERRORS) == 0)) { - /* Use static ID for testing only. For production, a - * non-static ID is used. See also + /* Use static ID for testing only. For production, a non-static ID is used. See also * qpdf_set_deterministic_ID. */ qpdf_set_static_ID(qpdf, QPDF_TRUE); /* for testing only */ qpdf_write(qpdf); diff --git a/examples/pdf-count-strings.cc b/examples/pdf-count-strings.cc index c70e183e..2061a499 100644 --- a/examples/pdf-count-strings.cc +++ b/examples/pdf-count-strings.cc @@ -1,7 +1,7 @@ // -// This example illustrates the use of QPDFObjectHandle::TokenFilter -// with filterContents. See also pdf-filter-tokens.cc for an example -// that uses QPDFObjectHandle::TokenFilter with addContentTokenFilter. +// This example illustrates the use of QPDFObjectHandle::TokenFilter with filterContents. See also +// pdf-filter-tokens.cc for an example that uses QPDFObjectHandle::TokenFilter with +// addContentTokenFilter. // #include @@ -46,16 +46,15 @@ StringCounter::handleToken(QPDFTokenizer::Token const& token) if (token.getType() == QPDFTokenizer::tt_string) { ++this->count; } - // Preserve input verbatim by passing each token to any specified - // downstream filter. + // Preserve input verbatim by passing each token to any specified downstream filter. writeToken(token); } void StringCounter::handleEOF() { - // Write a comment at the end of the stream just to show how we - // can enhance the output if we want. + // Write a comment at the end of the stream just to show how we can enhance the output if we + // want. write("\n% strings found: "); write(std::to_string(this->count)); } @@ -82,10 +81,9 @@ main(int argc, char* argv[]) int pageno = 0; for (auto& page: QPDFPageDocumentHelper(pdf).getAllPages()) { ++pageno; - // Pass the contents of a page through our string counter. - // If it's an even page, capture the output. This - // illustrates that you may capture any output generated - // by the filter, or you may ignore it. + // Pass the contents of a page through our string counter. If it's an even page, capture + // the output. This illustrates that you may capture any output generated by the filter, + // or you may ignore it. StringCounter counter; if (pageno % 2) { // Ignore output for odd pages. diff --git a/examples/pdf-create.cc b/examples/pdf-create.cc index e0fa93b1..c793b5f8 100644 --- a/examples/pdf-create.cc +++ b/examples/pdf-create.cc @@ -1,7 +1,6 @@ // -// This is an example of creating a PDF file from scratch. It -// illustrates use of several QPDF operations for creating objects and -// streams. It also serves as an illustration of how to use +// This is an example of creating a PDF file from scratch. It illustrates use of several QPDF +// operations for creating objects and streams. It also serves as an illustration of how to use // StreamDataProvider with different types of filters. // @@ -20,8 +19,8 @@ static char const* whoami = nullptr; -// This is a simple StreamDataProvider that writes image data for an -// orange square of the given width and height. +// This is a simple StreamDataProvider that writes image data for an orange square of the given +// width and height. class ImageProvider: public QPDFObjectHandle::StreamDataProvider { public: @@ -130,8 +129,7 @@ usage() static QPDFObjectHandle createPageContents(QPDF& pdf, std::string const& text) { - // Create a stream that displays our image and the given text in - // our font. + // Create a stream that displays our image and the given text in our font. std::string contents = "BT /F1 24 Tf 72 320 Td (" + text + ") Tj ET\n" "q 244 0 0 144 184 100 cm /Im1 Do Q\n"; @@ -159,11 +157,9 @@ add_page( { QPDF& pdf(dh.getQPDF()); - // Create a stream to encode our image. QPDFWriter will fill in - // the length and will respect our filters based on stream data - // mode. Since we are not specifying, QPDFWriter will compress - // with /FlateDecode if we don't provide any other form of - // compression. + // Create a stream to encode our image. QPDFWriter will fill in the length and will respect our + // filters based on stream data mode. Since we are not specifying, QPDFWriter will compress with + // /FlateDecode if we don't provide any other form of compression. auto* p = new ImageProvider(color_space, filter); std::shared_ptr provider(p); size_t width = p->getWidth(); @@ -219,20 +215,17 @@ check( std::vector const& color_spaces, std::vector const& filters) { - // Each stream is compressed the way it is supposed to be. We will - // add additional tests in qpdf.test to exercise QPDFWriter more - // fully. In this case, we want to make sure that we actually have - // RunLengthDecode and DCTDecode where we are supposed to and - // FlateDecode where we provided no filters. + // Each stream is compressed the way it is supposed to be. We will add additional tests in + // qpdf.test to exercise QPDFWriter more fully. In this case, we want to make sure that we + // actually have RunLengthDecode and DCTDecode where we are supposed to and FlateDecode where we + // provided no filters. - // Each image is correct. For non-lossy image compression, the - // uncompressed image data should exactly match what ImageProvider - // provided. For the DCTDecode data, allow for some fuzz to handle - // jpeg compression as well as its variance on different systems. + // Each image is correct. For non-lossy image compression, the uncompressed image data should + // exactly match what ImageProvider provided. For the DCTDecode data, allow for some fuzz to + // handle jpeg compression as well as its variance on different systems. - // These tests should use QPDFObjectHandle's stream data retrieval - // methods, but don't try to fully exercise them here. That is - // done elsewhere. + // These tests should use QPDFObjectHandle's stream data retrieval methods, but don't try to + // fully exercise them here. That is done elsewhere. size_t n_color_spaces = color_spaces.size(); size_t n_filters = filters.size(); @@ -254,8 +247,8 @@ check( // Check filter and color space. std::string desired_color_space = color_spaces[(pageno - 1) / n_color_spaces]; std::string desired_filter = filters[(pageno - 1) % n_filters]; - // In the default mode, QPDFWriter will compress with - // /FlateDecode if no filters are provided. + // In the default mode, QPDFWriter will compress with /FlateDecode if no filters are + // provided. if (desired_filter == "null") { desired_filter = "/FlateDecode"; } @@ -288,11 +281,9 @@ check( std::cout << "page " << pageno << ": image data length mismatch" << std::endl; this_errors = errors = true; } else { - // Compare bytes. For JPEG, allow a certain number of - // the bytes to be off desired by more than a given - // tolerance. Any of the samples may be a little off - // because of lossy compression, and around sharp - // edges, things can be quite off. For non-lossy + // Compare bytes. For JPEG, allow a certain number of the bytes to be off desired by + // more than a given tolerance. Any of the samples may be a little off because of + // lossy compression, and around sharp edges, things can be quite off. For non-lossy // compression, do not allow any tolerance. unsigned char const* actual_bytes = actual_data->getBuffer(); unsigned char const* desired_bytes = desired_data->getBuffer(); @@ -332,8 +323,7 @@ create_pdf(char const* filename) // Start with an empty PDF that has no pages or non-required objects. pdf.emptyPDF(); - // Add an indirect object to contain a font descriptor for the - // built-in Helvetica font. + // Add an indirect object to contain a font descriptor for the built-in Helvetica font. QPDFObjectHandle font = pdf.makeIndirectObject( // line-break "<<" @@ -362,8 +352,7 @@ create_pdf(char const* filename) QPDFWriter w(pdf, filename); w.write(); - // For test suite, verify that everything is the way it is - // supposed to be. + // For test suite, verify that everything is the way it is supposed to be. check(filename, color_spaces, filters); } diff --git a/examples/pdf-custom-filter.cc b/examples/pdf-custom-filter.cc index 57eedf74..e3cdf164 100644 --- a/examples/pdf-custom-filter.cc +++ b/examples/pdf-custom-filter.cc @@ -8,43 +8,35 @@ #include #include -// This example shows you everything you need to know to implement a -// custom stream filter for encoding and decoding as well as a stream -// data provider that modifies the stream's dictionary. This example -// uses the pattern of having the stream data provider class use a -// second QPDF instance with copies of streams from the original QPDF -// so that the stream data provider can access the original stream -// data. This is implemented very efficiently inside the qpdf library as -// the second QPDF instance knows how to read the stream data from the -// original input file, so no extra copies of the original stream data -// are made. +// This example shows you everything you need to know to implement a custom stream filter for +// encoding and decoding as well as a stream data provider that modifies the stream's dictionary. +// This example uses the pattern of having the stream data provider class use a second QPDF instance +// with copies of streams from the original QPDF so that the stream data provider can access the +// original stream data. This is implemented very efficiently inside the qpdf library as the second +// QPDF instance knows how to read the stream data from the original input file, so no extra copies +// of the original stream data are made. -// This example creates an imaginary filter called /XORDecode. There -// is no such filter in PDF, so the streams created by the example -// would not be usable by any PDF reader. However, the techniques here -// would work if you were going to implement support for a filter that -// qpdf does not support natively. For example, using the techniques -// shown here, it would be possible to create an application that -// downsampled or re-encoded images or that re-compressed streams -// using a more efficient "deflate" implementation than zlib. +// This example creates an imaginary filter called /XORDecode. There is no such filter in PDF, so +// the streams created by the example would not be usable by any PDF reader. However, the techniques +// here would work if you were going to implement support for a filter that qpdf does not support +// natively. For example, using the techniques shown here, it would be possible to create an +// application that downsampled or re-encoded images or that re-compressed streams using a more +// efficient "deflate" implementation than zlib. -// Comments appear throughout the code describing each piece of code -// and its purpose. You can read the file top to bottom, or you can -// start with main() and follow the flow. +// Comments appear throughout the code describing each piece of code and its purpose. You can read +// the file top to bottom, or you can start with main() and follow the flow. -// Please also see the test suite, qtest/custom-filter.test, which -// contains additional comments describing how to observe the results -// of running this example on test files that are specifically crafted -// for it. +// Please also see the test suite, qtest/custom-filter.test, which contains additional comments +// describing how to observe the results of running this example on test files that are specifically +// crafted for it. static char const* whoami = nullptr; class Pl_XOR: public Pipeline { - // This class implements a Pipeline for the made-up XOR decoder. - // It is initialized with a single-byte "key" and just XORs each - // byte with that key. This makes it reversible, so there is no - // distinction between encoding and decoding. + // This class implements a Pipeline for the made-up XOR decoder. It is initialized with a + // single-byte "key" and just XORs each byte with that key. This makes it reversible, so there + // is no distinction between encoding and decoding. public: Pl_XOR(char const* identifier, Pipeline* next, unsigned char key); @@ -79,17 +71,14 @@ Pl_XOR::finish() class SF_XORDecode: public QPDFStreamFilter { - // This class implements a QPDFStreamFilter that knows how to - // validate and interpret decode parameters (/DecodeParms) for the - // made-up /XORDecode stream filter. Since this is not a real - // stream filter, no actual PDF reader would know how to interpret - // it. This is just to illustrate how to create a stream filter. - // In main(), we call QPDF::registerStreamFilter to tell the - // library about the filter. See comments in QPDFStreamFilter.hh - // for details on how to implement the methods. For purposes of - // example, we are calling this a "specialized" compression - // filter, which just means QPDF assumes that it should not - // "uncompress" the stream by default. + // This class implements a QPDFStreamFilter that knows how to validate and interpret decode + // parameters (/DecodeParms) for the made-up /XORDecode stream filter. Since this is not a real + // stream filter, no actual PDF reader would know how to interpret it. This is just to + // illustrate how to create a stream filter. In main(), we call QPDF::registerStreamFilter to + // tell the library about the filter. See comments in QPDFStreamFilter.hh for details on how to + // implement the methods. For purposes of example, we are calling this a "specialized" + // compression filter, which just means QPDF assumes that it should not "uncompress" the stream + // by default. public: ~SF_XORDecode() override = default; bool setDecodeParms(QPDFObjectHandle decode_parms) override; @@ -98,33 +87,28 @@ class SF_XORDecode: public QPDFStreamFilter private: unsigned char key; - // It is the responsibility of the QPDFStreamFilter implementation - // to ensure that the pipeline returned by getDecodePipeline() is - // deleted when the class is deleted. The easiest way to do this - // is to stash the pipeline in a std::shared_ptr, which enables us - // to use the default destructor implementation. + // It is the responsibility of the QPDFStreamFilter implementation to ensure that the pipeline + // returned by getDecodePipeline() is deleted when the class is deleted. The easiest way to do + // this is to stash the pipeline in a std::shared_ptr, which enables us to use the default + // destructor implementation. std::shared_ptr pipeline; }; bool SF_XORDecode::setDecodeParms(QPDFObjectHandle decode_parms) { - // For purposes of example, we store the key in a separate stream. - // We could just as well store the key directly in /DecodeParms, - // but this example uses a stream to illustrate how one might do - // that. For example, if implementing /JBIG2Decode, one would need - // to handle the /JBIG2Globals key, which points to a stream. See - // comments in SF_XORDecode::registerStream for additional notes - // on this. + // For purposes of example, we store the key in a separate stream. We could just as well store + // the key directly in /DecodeParms, but this example uses a stream to illustrate how one might + // do that. For example, if implementing /JBIG2Decode, one would need to handle the + // /JBIG2Globals key, which points to a stream. See comments in SF_XORDecode::registerStream for + // additional notes on this. try { - // Expect /DecodeParms to be a dictionary with a /KeyStream - // key that points to a one-byte stream whose single byte is - // the key. If we are successful at retrieving the key, return - // true, indicating that we are able to process with the given - // decode parameters. Under any other circumstances, return - // false. For other examples of QPDFStreamFilter - // implementations, look at the classes whose names start with - // SF_ in the qpdf library implementation. + // Expect /DecodeParms to be a dictionary with a /KeyStream key that points to a one-byte + // stream whose single byte is the key. If we are successful at retrieving the key, return + // true, indicating that we are able to process with the given decode parameters. Under any + // other circumstances, return false. For other examples of QPDFStreamFilter + // implementations, look at the classes whose names start with SF_ in the qpdf library + // implementation. auto buf = decode_parms.getKey("/KeyStream").getStreamData(); if (buf->getSize() != 1) { return false; @@ -140,14 +124,12 @@ SF_XORDecode::setDecodeParms(QPDFObjectHandle decode_parms) Pipeline* SF_XORDecode::getDecodePipeline(Pipeline* next) { - // Return a pipeline that the qpdf library should pass the stream - // data through. The pipeline should receive encoded data and pass - // decoded data to "next". getDecodePipeline() can always count on - // setDecodeParms() having been called first. The setDecodeParms() - // method should store any parameters needed by the pipeline. To - // ensure that the pipeline we return disappears when the class - // disappears, stash it in a std::shared_ptr and retrieve - // the raw pointer from there. + // Return a pipeline that the qpdf library should pass the stream data through. The pipeline + // should receive encoded data and pass decoded data to "next". getDecodePipeline() can always + // count on setDecodeParms() having been called first. The setDecodeParms() method should store + // any parameters needed by the pipeline. To ensure that the pipeline we return disappears when + // the class disappears, stash it in a std::shared_ptr and retrieve the raw pointer from + // there. this->pipeline = std::make_shared("xor", next, this->key); return this->pipeline.get(); } @@ -155,46 +137,37 @@ SF_XORDecode::getDecodePipeline(Pipeline* next) bool SF_XORDecode::isSpecializedCompression() { - // The default implementation of QPDFStreamFilter would return - // false, so if you want a specialized or lossy compression - // filter, override one of the methods as described in + // The default implementation of QPDFStreamFilter would return false, so if you want a + // specialized or lossy compression filter, override one of the methods as described in // QPDFStreamFilter.hh. return true; } class StreamReplacer: public QPDFObjectHandle::StreamDataProvider { - // This class implements a StreamDataProvider that, under specific - // conditions, replaces the stream data with data encoded with the - // made-up /XORDecode filter. + // This class implements a StreamDataProvider that, under specific conditions, replaces the + // stream data with data encoded with the made-up /XORDecode filter. // The flow for this class is as follows: // - // * The main application iterates through streams that should be - // replaced and calls registerStream. registerStream in turn - // calls maybeReplace passing nullptr to pipeline and the - // address of a valid QPDFObjectHandle to dict_updates. The - // stream passed in for this call is the stream for the original - // QPDF object. It has not yet been altered, so we have access - // to its original dictionary and data. As described in the - // method, the method when called in this way makes a - // determination as to whether the stream should be replaced. If - // so, registerStream makes whatever changes are required. We - // have to do this now because we can't modify the stream during - // the writing process. + // * The main application iterates through streams that should be replaced and calls + // registerStream. registerStream in turn calls maybeReplace passing nullptr to pipeline and + // the address of a valid QPDFObjectHandle to dict_updates. The stream passed in for this call + // is the stream for the original QPDF object. It has not yet been altered, so we have access + // to its original dictionary and data. As described in the method, the method when called in + // this way makes a determination as to whether the stream should be replaced. If so, + // registerStream makes whatever changes are required. We have to do this now because we can't + // modify the stream during the writing process. // - // * provideStreamData(), which is called by QPDFWriter during the - // write process, actually writes the modified stream data. It - // calls maybeReplace again, but this time it passes a valid - // pipeline and passes nullptr to dict_updates. In this mode, - // the stream dictionary has already been altered, and the - // original stream data is no longer directly accessible. Trying - // to retrieve the stream data would cause an infinite loop because - // it would just end up calling provideStreamData again. This is - // why maybeReplace uses a stashed copy of the original stream. + // * provideStreamData(), which is called by QPDFWriter during the write process, actually + // writes the modified stream data. It calls maybeReplace again, but this time it passes a + // valid pipeline and passes nullptr to dict_updates. In this mode, the stream dictionary has + // already been altered, and the original stream data is no longer directly accessible. Trying + // to retrieve the stream data would cause an infinite loop because it would just end up + // calling provideStreamData again. This is why maybeReplace uses a stashed copy of the + // original stream. - // Additional explanation can be found in the method - // implementations. + // Additional explanation can be found in the method implementations. public: StreamReplacer(QPDF* pdf); @@ -211,17 +184,16 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider Pipeline* pipeline, QPDFObjectHandle* dict_updates); - // Hang onto a reference to the QPDF object containing the streams - // we are replacing. We need this to create a new stream. + // Hang onto a reference to the QPDF object containing the streams we are replacing. We need + // this to create a new stream. QPDF* pdf; - // Map the object/generation in original file to the copied stream - // in "other". We use this to retrieve the original data. + // Map the object/generation in original file to the copied stream in "other". We use this to + // retrieve the original data. std::map copied_streams; - // Each stream gets is own "key" for the XOR filter. We use a - // single instance of StreamReplacer for all streams, so stash all - // the keys here. + // Each stream gets is own "key" for the XOR filter. We use a single instance of StreamReplacer + // for all streams, so stash all the keys here. std::map keys; }; @@ -237,49 +209,38 @@ StreamReplacer::maybeReplace( Pipeline* pipeline, QPDFObjectHandle* dict_updates) { - // As described in the class comments, this method is called - // twice. Before writing has started pipeline is nullptr, and - // dict_updates is provided. In this mode, we figure out whether - // we should replace the stream and, if so, take care of the - // necessary setup. When we are actually ready to supply the data, - // this method is called again with pipeline populated and - // dict_updates as a nullptr. In this mode, we are not allowed to - // change anything, since writing is already in progress. We - // must simply provide the stream data. + // As described in the class comments, this method is called twice. Before writing has started + // pipeline is nullptr, and dict_updates is provided. In this mode, we figure out whether we + // should replace the stream and, if so, take care of the necessary setup. When we are actually + // ready to supply the data, this method is called again with pipeline populated and + // dict_updates as a nullptr. In this mode, we are not allowed to change anything, since writing + // is already in progress. We must simply provide the stream data. - // The return value indicates whether or not we should replace the - // stream. If the first call returns false, there will be no - // second call. If the second call returns false, something went - // wrong since the method should always make the same decision for - // a given stream. + // The return value indicates whether or not we should replace the stream. If the first call + // returns false, there will be no second call. If the second call returns false, something went + // wrong since the method should always make the same decision for a given stream. - // For this example, all the determination logic could have - // appeared inside the if (dict_updates) block rather than being - // duplicated, but in some cases, there may be a reason to - // duplicate things. For example, if you wanted to write code that - // re-encoded an image if the new encoding was more efficient, - // you'd have to actually try it out. Then you would either have - // to cache the result somewhere or just repeat the calculations, - // depending on space/time constraints, etc. + // For this example, all the determination logic could have appeared inside the if + // (dict_updates) block rather than being duplicated, but in some cases, there may be a reason + // to duplicate things. For example, if you wanted to write code that re-encoded an image if the + // new encoding was more efficient, you'd have to actually try it out. Then you would either + // have to cache the result somewhere or just repeat the calculations, depending on space/time + // constraints, etc. - // In our contrived example, we are replacing the data for all - // streams that have /DoXOR = true in the stream dictionary. If - // this were a more realistic application, our criteria would be - // more sensible. For example, an image downsampler might choose - // to replace a stream that represented an image with a high pixel - // density. + // In our contrived example, we are replacing the data for all streams that have /DoXOR = true + // in the stream dictionary. If this were a more realistic application, our criteria would be + // more sensible. For example, an image downsampler might choose to replace a stream that + // represented an image with a high pixel density. auto dict = stream.getDict(); auto mark = dict.getKey("/DoXOR"); if (!(mark.isBool() && mark.getBoolValue())) { return false; } - // We can't replace the stream data if we can't get the original - // stream data for any reason. A more realistic application may - // actually look at the data here as well, or it may be able to - // make all its decisions from the stream dictionary. However, - // it's a good idea to make sure we can retrieve the filtered data - // if we are going to need it later. + // We can't replace the stream data if we can't get the original stream data for any reason. A + // more realistic application may actually look at the data here as well, or it may be able to + // make all its decisions from the stream dictionary. However, it's a good idea to make sure we + // can retrieve the filtered data if we are going to need it later. std::shared_ptr out; try { out = stream.getStreamData(); @@ -288,19 +249,15 @@ StreamReplacer::maybeReplace( } if (dict_updates) { - // It's not safe to make any modifications to any objects - // during the writing process since the updated objects may - // have already been written. In this mode, when dict_updates - // is provided, we have not started writing. Store the - // modifications we intend to make to the stream dictionary - // here. We're just storing /OrigLength for purposes of - // example. Again, a realistic application would make other - // changes. For example, an image resampler might change the - // dimensions or other properties of the image. + // It's not safe to make any modifications to any objects during the writing process since + // the updated objects may have already been written. In this mode, when dict_updates is + // provided, we have not started writing. Store the modifications we intend to make to the + // stream dictionary here. We're just storing /OrigLength for purposes of example. Again, a + // realistic application would make other changes. For example, an image resampler might + // change the dimensions or other properties of the image. dict_updates->replaceKey( "/OrigLength", QPDFObjectHandle::newInteger(QIntC::to_longlong(out->getSize()))); - // We are also storing the "key" that we will access when - // writing the data. + // We are also storing the "key" that we will access when writing the data. this->keys[og] = QIntC::to_uchar((og.getObj() * QIntC::to_int(out->getSize())) & 0xff); } @@ -319,21 +276,18 @@ StreamReplacer::registerStream( { QPDFObjGen og(stream.getObjGen()); - // We don't need to process a stream more than once. In this - // example, we are just iterating through objects, but if we were - // doing something like iterating through images on pages, we + // We don't need to process a stream more than once. In this example, we are just iterating + // through objects, but if we were doing something like iterating through images on pages, we // might realistically encounter the same stream more than once. if (this->copied_streams.count(og) > 0) { return; } - // Store something in copied_streams so that we don't - // double-process even in the negative case. This gets replaced - // later if needed. + // Store something in copied_streams so that we don't double-process even in the negative case. + // This gets replaced later if needed. this->copied_streams[og] = QPDFObjectHandle::newNull(); - // Call maybeReplace with dict_updates. In this mode, it - // determines whether we should replace the stream data and, if - // so, supplies dictionary updates we should make. + // Call maybeReplace with dict_updates. In this mode, it determines whether we should replace + // the stream data and, if so, supplies dictionary updates we should make. bool should_replace = false; QPDFObjectHandle dict_updates = QPDFObjectHandle::newDictionary(); try { @@ -343,9 +297,8 @@ StreamReplacer::registerStream( } if (should_replace) { - // Copy the stream so we can get to the original data from the - // stream data provider. This doesn't actually copy any data, - // but the copy retains the original stream data after the + // Copy the stream so we can get to the original data from the stream data provider. This + // doesn't actually copy any data, but the copy retains the original stream data after the // original one is modified. this->copied_streams[og] = stream.copyStream(); // Update the stream dictionary with any changes. @@ -353,20 +306,17 @@ StreamReplacer::registerStream( for (auto const& k: dict_updates.getKeys()) { dict.replaceKey(k, dict_updates.getKey(k)); } - // Create the key stream that will be referenced from - // /DecodeParms. We have to do this now since you can't modify - // or create objects during write. + // Create the key stream that will be referenced from /DecodeParms. We have to do this now + // since you can't modify or create objects during write. char p[1] = {static_cast(this->keys[og])}; std::string p_str(p, 1); QPDFObjectHandle dp_stream = this->pdf->newStream(p_str); - // Create /DecodeParms as expected by our fictitious - // /XORDecode filter. + // Create /DecodeParms as expected by our fictitious /XORDecode filter. QPDFObjectHandle decode_parms = QPDFObjectHandle::newDictionary({{"/KeyStream", dp_stream}}); stream.replaceStreamData(self, QPDFObjectHandle::newName("/XORDecode"), decode_parms); - // Further, if /ProtectXOR = true, we disable filtering on write - // so that QPDFWriter will not decode the stream even though we - // have registered a stream filter for /XORDecode. + // Further, if /ProtectXOR = true, we disable filtering on write so that QPDFWriter will not + // decode the stream even though we have registered a stream filter for /XORDecode. auto protect = dict.getKey("/ProtectXOR"); if (protect.isBool() && protect.getBoolValue()) { stream.setFilterOnWrite(false); @@ -378,14 +328,12 @@ void StreamReplacer::provideStreamData(QPDFObjGen const& og, Pipeline* pipeline) { QPDFObjectHandle orig = this->copied_streams[og]; - // call maybeReplace again, this time with the pipeline and no - // dict_updates. In this mode, maybeReplace doesn't make any - // changes. We have to hand it the original stream data, which we + // call maybeReplace again, this time with the pipeline and no dict_updates. In this mode, + // maybeReplace doesn't make any changes. We have to hand it the original stream data, which we // get from copied_streams. if (!maybeReplace(og, orig, pipeline, nullptr)) { - // Since this only gets called for streams we already - // determined we are replacing, a false return would indicate - // a logic error. + // Since this only gets called for streams we already determined we are replacing, a false + // return would indicate a logic error. throw std::logic_error("should_replace return false in provideStreamData"); } } @@ -396,17 +344,15 @@ process(char const* infilename, char const* outfilename, bool decode_specialized QPDF qpdf; qpdf.processFile(infilename); - // Create a single StreamReplacer instance. The interface requires - // a std::shared_ptr in various places, so allocate a StreamReplacer - // and stash it in a std::shared_ptr. + // Create a single StreamReplacer instance. The interface requires a std::shared_ptr in various + // places, so allocate a StreamReplacer and stash it in a std::shared_ptr. auto* replacer = new StreamReplacer(&qpdf); std::shared_ptr p(replacer); for (auto& o: qpdf.getAllObjects()) { if (o.isStream()) { - // Call registerStream for every stream. Only ones that - // registerStream decides to replace will actually be - // replaced. + // Call registerStream for every stream. Only ones that registerStream decides to + // replace will actually be replaced. replacer->registerStream(o, p); } } @@ -454,9 +400,8 @@ main(int argc, char* argv[]) } try { - // Register our fictitious filter. This enables QPDFWriter to - // decode our streams. This is not a real filter, so no real - // PDF reading application would be able to interpret it. This + // Register our fictitious filter. This enables QPDFWriter to decode our streams. This is + // not a real filter, so no real PDF reading application would be able to interpret it. This // is just for illustrative purposes. QPDF::registerStreamFilter("/XORDecode", [] { return std::make_shared(); }); // Do the actual processing. diff --git a/examples/pdf-double-page-size.cc b/examples/pdf-double-page-size.cc index 6e1b4f8b..289c4d17 100644 --- a/examples/pdf-double-page-size.cc +++ b/examples/pdf-double-page-size.cc @@ -14,18 +14,16 @@ void usage() { std::cerr << "Usage: " << whoami << " infile.pdf outfile.pdf [in-password]" << std::endl - << "Double size of all pages in infile.pdf;" - << " write output to outfile.pdf" << std::endl; + << "Double size of all pages in infile.pdf; write output to outfile.pdf" << std::endl; exit(2); } -// If there is a box of name box_name, replace it with a new box whose -// elements are double the values of the original box. +// If there is a box of name box_name, replace it with a new box whose elements are double the +// values of the original box. static void doubleBoxSize(QPDFPageObjectHelper& page, char const* box_name) { - // We need to use getAttribute rather than getKey as some boxes could - // be inherited. + // We need to use getAttribute rather than getKey as some boxes could be inherited. auto box = page.getAttribute(box_name, true); if (box.isNull()) { return; diff --git a/examples/pdf-filter-tokens.cc b/examples/pdf-filter-tokens.cc index 68d6e149..4a06bcd2 100644 --- a/examples/pdf-filter-tokens.cc +++ b/examples/pdf-filter-tokens.cc @@ -1,7 +1,6 @@ // -// This example illustrates the use of QPDFObjectHandle::TokenFilter -// with addContentTokenFilter. Please see comments inline for details. -// See also pdf-count-strings.cc for a use of +// This example illustrates the use of QPDFObjectHandle::TokenFilter with addContentTokenFilter. +// Please see comments inline for details. See also pdf-count-strings.cc for a use of // QPDFObjectHandle::TokenFilter with filterContents. // @@ -26,9 +25,8 @@ usage() exit(2); } -// The StringReverser class is a trivial example of using a token -// filter. This class only overrides the pure virtual handleToken -// function and preserves the default handleEOF function. +// The StringReverser class is a trivial example of using a token filter. This class only overrides +// the pure virtual handleToken function and preserves the default handleEOF function. class StringReverser: public QPDFObjectHandle::TokenFilter { public: @@ -39,15 +37,12 @@ class StringReverser: public QPDFObjectHandle::TokenFilter void StringReverser::handleToken(QPDFTokenizer::Token const& token) { - // For string tokens, reverse the characters. For other tokens, - // just pass them through. Notice that we construct a new string - // token and write that, thus allowing the library to handle any - // subtleties about properly encoding unprintable characters. This - // function doesn't handle multibyte characters at all. It's not - // intended to be an example of the correct way to reverse - // strings. It's just intended to give a simple example of a - // pretty minimal filter and to show an example of writing a - // constructed token. + // For string tokens, reverse the characters. For other tokens, just pass them through. Notice + // that we construct a new string token and write that, thus allowing the library to handle any + // subtleties about properly encoding unprintable characters. This function doesn't handle + // multibyte characters at all. It's not intended to be an example of the correct way to reverse + // strings. It's just intended to give a simple example of a pretty minimal filter and to show + // an example of writing a constructed token. if (token.getType() == QPDFTokenizer::tt_string) { std::string value = token.getValue(); std::reverse(value.begin(), value.end()); @@ -57,9 +52,8 @@ StringReverser::handleToken(QPDFTokenizer::Token const& token) } } -// The ColorToGray filter finds all "rg" operators in the content -// stream and replaces them with "g" operators, thus mapping color to -// grayscale. Note that it only applies to content streams, not +// The ColorToGray filter finds all "rg" operators in the content stream and replaces them with "g" +// operators, thus mapping color to grayscale. Note that it only applies to content streams, not // images, so this will not replace color images with grayscale // images. class ColorToGray: public QPDFObjectHandle::TokenFilter @@ -99,29 +93,23 @@ ColorToGray::numericValue(QPDFTokenizer::Token const& token) void ColorToGray::handleToken(QPDFTokenizer::Token const& token) { - // Track the number of non-ignorable tokens we've seen. If we see - // an "rg" following three numbers, convert it to a grayscale - // value. Keep writing tokens to the output as we can. + // Track the number of non-ignorable tokens we've seen. If we see an "rg" following three + // numbers, convert it to a grayscale value. Keep writing tokens to the output as we can. - // There are several things to notice here. We keep two stacks: - // one of "meaningful" tokens, and one of all tokens. This way we - // can preserve whitespace or comments that we encounter in the - // stream and there preserve layout. As we receive tokens, we keep - // the last four meaningful tokens. If we see three numbers - // followed by rg, we use the three numbers to calculate a gray - // value that is perceptually similar to the color value and then - // write the "g" operator to the output, discarding any spaces or - // comments encountered embedded in the "rg" operator. + // There are several things to notice here. We keep two stacks: one of "meaningful" tokens, and + // one of all tokens. This way we can preserve whitespace or comments that we encounter in the + // stream and there preserve layout. As we receive tokens, we keep the last four meaningful + // tokens. If we see three numbers followed by rg, we use the three numbers to calculate a gray + // value that is perceptually similar to the color value and then write the "g" operator to the + // output, discarding any spaces or comments encountered embedded in the "rg" operator. - // The stack and all_stack members are updated in such a way that - // they always contain exactly the same non-ignorable tokens. The - // stack member contains the tokens that would be left if you + // The stack and all_stack members are updated in such a way that they always contain exactly + // the same non-ignorable tokens. The stack member contains the tokens that would be left if you // removed all space and comment tokens from all_stack. - // On each new token, flush out any space or comment tokens. Store - // the incoming token. If we just got an rg preceded by the right - // kinds of operands, replace the command. Flush any additional - // accumulated tokens to keep the stack only four tokens deep. + // On each new token, flush out any space or comment tokens. Store the incoming token. If we + // just got an rg preceded by the right kinds of operands, replace the command. Flush any + // additional accumulated tokens to keep the stack only four tokens deep. while ((!this->all_stack.empty()) && isIgnorable(this->all_stack.at(0).getType())) { writeToken(this->all_stack.at(0)); @@ -182,11 +170,9 @@ main(int argc, char* argv[]) QPDF pdf; pdf.processFile(infilename); for (auto& page: QPDFPageDocumentHelper(pdf).getAllPages()) { - // Attach two token filters to each page of this file. - // When the file is written, or when the pages' contents - // are retrieved in any other way, the filters will be - // applied. See comments on the filters for additional - // details. + // Attach two token filters to each page of this file. When the file is written, or when + // the pages' contents are retrieved in any other way, the filters will be applied. See + // comments on the filters for additional details. page.addContentTokenFilter( std::shared_ptr(new StringReverser)); page.addContentTokenFilter( diff --git a/examples/pdf-invert-images.cc b/examples/pdf-invert-images.cc index 5692e7b2..0ef2169e 100644 --- a/examples/pdf-invert-images.cc +++ b/examples/pdf-invert-images.cc @@ -20,15 +20,12 @@ usage() exit(2); } -// Derive a class from StreamDataProvider to provide updated stream -// data. The main purpose of using this object is to avoid having to -// allocate memory up front for the objects. We want to replace the -// stream data with a function of the original stream data. In order -// to do this without actually holding all the images in memory, we -// create copies of the streams. Copying the streams doesn't actually -// copy the data. Internally, the qpdf library is holding onto the -// location of the original stream data, which makes it possible for -// the StreamDataProvider to access it when it needs it. +// Derive a class from StreamDataProvider to provide updated stream data. The main purpose of using +// this object is to avoid having to allocate memory up front for the objects. We want to replace +// the stream data with a function of the original stream data. In order to do this without actually +// holding all the images in memory, we create copies of the streams. Copying the streams doesn't +// actually copy the data. Internally, the qpdf library is holding onto the location of the original +// stream data, which makes it possible for the StreamDataProvider to access it when it needs it. class ImageInverter: public QPDFObjectHandle::StreamDataProvider { public: @@ -46,42 +43,35 @@ void ImageInverter::registerImage( QPDFObjectHandle image, std::shared_ptr self) { - // replaceStreamData requires a pointer holder to the stream data - // provider, but there's no way for us to generate one ourselves, - // so we have to have it handed to us. Don't be tempted to have - // the class contain a std::shared_ptr to itself as a member. Doing - // this will prevent the class from ever being deleted since the - // reference count will never drop to zero (and std::shared_ptr - // doesn't have weak references). + // replaceStreamData requires a pointer holder to the stream data provider, but there's no way + // for us to generate one ourselves, so we have to have it handed to us. Don't be tempted to + // have the class contain a std::shared_ptr to itself as a member. Doing this will prevent the + // class from ever being deleted since the reference count will never drop to zero (and + // std::shared_ptr doesn't have weak references). QPDFObjGen og(image.getObjGen()); - // Store information about the images based on the object and - // generation number. Recall that a single image object may be - // used more than once, so no need to update the same stream - // multiple times. + // Store information about the images based on the object and generation number. Recall that a + // single image object may be used more than once, so no need to update the same stream multiple + // times. if (this->copied_images.count(og) > 0) { return; } this->copied_images[og] = image.copyStream(); - // Register our stream data provider for this stream. Future calls - // to getStreamData or pipeStreamData will use the new - // information. Provide null for both filter and decode - // parameters. Note that this does not mean the image data will be - // uncompressed when we write the file. By default, QPDFWriter - // will use /FlateDecode for anything that is uncompressed or - // filterable in the input QPDF object, so we don't have to deal - // with it explicitly here. We could explicitly use /DCTDecode and - // write through a DCT filter if we wanted. + // Register our stream data provider for this stream. Future calls to getStreamData or + // pipeStreamData will use the new information. Provide null for both filter and decode + // parameters. Note that this does not mean the image data will be uncompressed when we write + // the file. By default, QPDFWriter will use /FlateDecode for anything that is uncompressed or + // filterable in the input QPDF object, so we don't have to deal with it explicitly here. We + // could explicitly use /DCTDecode and write through a DCT filter if we wanted. image.replaceStreamData(self, QPDFObjectHandle::newNull(), QPDFObjectHandle::newNull()); } void ImageInverter::provideStreamData(QPDFObjGen const& og, Pipeline* pipeline) { - // Use the object and generation number supplied to look up the - // image data. Then invert the image data and write the inverted - // data to the pipeline. + // Use the object and generation number supplied to look up the image data. Then invert the + // image data and write the inverted data to the pipeline. std::shared_ptr data = this->copied_images[og].getStreamData(qpdf_dl_all); size_t size = data->getSize(); unsigned char* buf = data->getBuffer(); @@ -130,11 +120,9 @@ main(int argc, char* argv[]) QPDFObjectHandle color_space = image_dict.getKey("/ColorSpace"); QPDFObjectHandle bits_per_component = image_dict.getKey("/BitsPerComponent"); - // For our example, we can only work with images 8-bit - // grayscale images that we can fully decode. Use - // pipeStreamData with a null pipeline to determine - // whether the image is filterable. Directly inspect - // keys to determine the image type. + // For our example, we can only work with images 8-bit grayscale images that we can + // fully decode. Use pipeStreamData with a null pipeline to determine whether the + // image is filterable. Directly inspect keys to determine the image type. if (image.pipeStreamData(nullptr, qpdf_ef_compress, qpdf_dl_all) && color_space.isNameAndEquals("/DeviceGray") && bits_per_component.isInteger() && (bits_per_component.getIntValue() == 8)) { @@ -146,8 +134,7 @@ main(int argc, char* argv[]) // Write out a new file QPDFWriter w(qpdf, outfilename); if (static_id) { - // For the test suite, uncompress streams and use static - // IDs. + // For the test suite, uncompress streams and use static IDs. w.setStaticID(true); // for testing only } w.write(); diff --git a/examples/pdf-linearize.c b/examples/pdf-linearize.c index 3a7a335d..20461593 100644 --- a/examples/pdf-linearize.c +++ b/examples/pdf-linearize.c @@ -51,8 +51,7 @@ main(int argc, char* argv[]) if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) && ((qpdf_init_write(qpdf, outfile) & QPDF_ERRORS) == 0)) { - /* Use static ID for testing only. For production, a - * non-static ID is used. See also + /* Use static ID for testing only. For production, a non-static ID is used. See also * qpdf_set_deterministic_ID. */ qpdf_set_static_ID(qpdf, QPDF_TRUE); /* for testing only */ qpdf_set_linearization(qpdf, QPDF_TRUE); diff --git a/examples/pdf-name-number-tree.cc b/examples/pdf-name-number-tree.cc index a14ad126..31eaf932 100644 --- a/examples/pdf-name-number-tree.cc +++ b/examples/pdf-name-number-tree.cc @@ -29,24 +29,19 @@ main(int argc, char* argv[]) QPDF qpdf; qpdf.emptyPDF(); - // This example doesn't do anything particularly useful other than - // just illustrate how to use the APIs for name and number trees. - // It also demonstrates use of the iterators for dictionaries and - // arrays introduced at the same time with qpdf 10.2. + // This example doesn't do anything particularly useful other than just illustrate how to use + // the APIs for name and number trees. It also demonstrates use of the iterators for + // dictionaries and arrays introduced at the same time with qpdf 10.2. - // To use this example, compile it and run it. Study the output - // and compare it to what you expect. When done, look at the - // generated output file in a text editor to inspect the structure - // of the trees as left in the file. + // To use this example, compile it and run it. Study the output and compare it to what you + // expect. When done, look at the generated output file in a text editor to inspect the + // structure of the trees as left in the file. - // We're just going to create some name and number trees, hang - // them off the document catalog (root), and write an empty PDF to - // a file. The PDF will have no pages and won't be viewable, but - // you can look at it in a text editor to see the resulting - // structure of the PDF. + // We're just going to create some name and number trees, hang them off the document catalog + // (root), and write an empty PDF to a file. The PDF will have no pages and won't be viewable, + // but you can look at it in a text editor to see the resulting structure of the PDF. - // Create a dictionary off the root where we will hang our name - // and number tree. + // Create a dictionary off the root where we will hang our name and number tree. auto root = qpdf.getRoot(); auto example = QPDFObjectHandle::newDictionary(); root.replaceKey("/Example", example); @@ -75,8 +70,8 @@ main(int argc, char* argv[]) std::cout << " " << i.first << " -> " << i.second.unparse() << std::endl; } - // This is a small tree, so everything will be at the root. We can - // look at it using dictionary and array iterators. + // This is a small tree, so everything will be at the root. We can look at it using dictionary + // and array iterators. std::cout << "Keys in name tree object:" << std::endl; QPDFObjectHandle names; for (auto const& i: name_tree_oh.ditems()) { @@ -121,15 +116,12 @@ main(int argc, char* argv[]) << std::endl; std::cout << "Has K?: " << name_tree.hasName("K") << std::endl; - // Illustrate some more advanced usage using number trees. These - // calls work for name trees too. + // Illustrate some more advanced usage using number trees. These calls work for name trees too. - // The safe way to populate a tree is to call insert repeatedly as - // above, but if you know you are definitely inserting items in - // order, it is more efficient to insert them using insertAfter, - // which avoids doing a binary search through the tree for each - // insertion. Note that if you don't insert items in order using - // this method, you will create an invalid tree. + // The safe way to populate a tree is to call insert repeatedly as above, but if you know you + // are definitely inserting items in order, it is more efficient to insert them using + // insertAfter, which avoids doing a binary search through the tree for each insertion. Note + // that if you don't insert items in order using this method, you will create an invalid tree. auto number_tree = QPDFNumberTreeObjectHelper::newEmpty(qpdf); auto number_tree_oh = number_tree.getObjectHandle(); example.replaceKey("/NumberTree", number_tree_oh); @@ -149,9 +141,8 @@ main(int argc, char* argv[]) ++n; } - // When you remove an item with an iterator, the iterator - // advances. This makes it possible to filter while iterating. - // Remove all items that are multiples of 5. + // When you remove an item with an iterator, the iterator advances. This makes it possible to + // filter while iterating. Remove all items that are multiples of 5. iter2 = number_tree.begin(); while (iter2 != number_tree.end()) { if (iter2->first % 5 == 0) { diff --git a/examples/pdf-overlay-page.cc b/examples/pdf-overlay-page.cc index 6d1cd0b0..75577094 100644 --- a/examples/pdf-overlay-page.cc +++ b/examples/pdf-overlay-page.cc @@ -6,10 +6,9 @@ #include #include -// This program demonstrates use of form XObjects to overlay a page -// from one file onto all pages of another file. The qpdf program's -// --overlay and --underlay options provide a more general version of -// this capability. +// This program demonstrates use of form XObjects to overlay a page from one file onto all pages of +// another file. The qpdf program's --overlay and --underlay options provide a more general version +// of this capability. static char const* whoami = nullptr; @@ -44,24 +43,21 @@ stamp_page(char const* infile, char const* stampfile, char const* outfile) int min_suffix = 1; std::string name = resources.getUniqueResourceName("/Fx", min_suffix); - // Generate content to place the form XObject centered within - // destination page's trim box. + // Generate content to place the form XObject centered within destination page's trim box. QPDFMatrix m; std::string content = ph.placeFormXObject(stamp_fo, name, ph.getTrimBox().getArrayAsRectangle(), m); if (!content.empty()) { - // Append the content to the page's content. Surround the - // original content with q...Q to the new content from the - // page's original content. + // Append the content to the page's content. Surround the original content with q...Q to + // the new content from the page's original content. resources.mergeResources("<< /XObject << >> >>"_qpdf); resources.getKey("/XObject").replaceKey(name, stamp_fo); ph.addPageContents(inpdf.newStream("q\n"), true); ph.addPageContents(inpdf.newStream("\nQ\n" + content), false); } - // Copy the annotations and form fields from the original page - // to the new page. For more efficiency when copying multiple - // pages, we can create a QPDFAcroFormDocumentHelper and pass - // it in. See comments in QPDFPageObjectHelper.hh for details. + // Copy the annotations and form fields from the original page to the new page. For more + // efficiency when copying multiple pages, we can create a QPDFAcroFormDocumentHelper and + // pass it in. See comments in QPDFPageObjectHelper.hh for details. ph.copyAnnotations(stamp_page_1, m); } diff --git a/examples/pdf-parse-content.cc b/examples/pdf-parse-content.cc index 743986a1..b60693f0 100644 --- a/examples/pdf-parse-content.cc +++ b/examples/pdf-parse-content.cc @@ -13,8 +13,8 @@ void usage() { std::cerr << "Usage: " << whoami << " filename page-number" << std::endl - << "Prints a dump of the objects in the content streams" - << " of the given page." << std::endl + << "Prints a dump of the objects in the content streams of the given page." + << std::endl << "Pages are numbered from 1." << std::endl; exit(2); } diff --git a/examples/pdf-set-form-values.cc b/examples/pdf-set-form-values.cc index c2793142..a1a19db1 100644 --- a/examples/pdf-set-form-values.cc +++ b/examples/pdf-set-form-values.cc @@ -29,41 +29,33 @@ main(int argc, char* argv[]) char const* outfilename = argv[2]; char const* value = argv[3]; - // This is a contrived example that just goes through a file page - // by page and sets the value of any text fields it finds to a - // fixed value as given on the command line. The purpose here is - // to illustrate use of the helper classes around interactive - // forms. + // This is a contrived example that just goes through a file page by page and sets the value of + // any text fields it finds to a fixed value as given on the command line. The purpose here is + // to illustrate use of the helper classes around interactive forms. try { QPDF qpdf; qpdf.processFile(infilename); - // We will iterate through form fields by starting at the page - // level and looking at each field for each page. We could - // also called QPDFAcroFormDocumentHelper::getFormFields to - // iterate at the field level, but doing it as below - // illustrates how we can map from annotations to fields. + // We will iterate through form fields by starting at the page level and looking at each + // field for each page. We could also called QPDFAcroFormDocumentHelper::getFormFields to + // iterate at the field level, but doing it as below illustrates how we can map from + // annotations to fields. QPDFAcroFormDocumentHelper afdh(qpdf); for (auto const& page: QPDFPageDocumentHelper(qpdf).getAllPages()) { - // Get all widget annotations for each page. Widget - // annotations are the ones that contain the details of - // what's in a form field. + // Get all widget annotations for each page. Widget annotations are the ones that + // contain the details of what's in a form field. for (auto& annot: afdh.getWidgetAnnotationsForPage(page)) { - // For each annotation, find its associated field. If - // it's a text field, set its value. + // For each annotation, find its associated field. If it's a text field, set its + // value. QPDFFormFieldObjectHelper ffh = afdh.getFieldForAnnotation(annot); if (ffh.getFieldType() == "/Tx") { - // Set the value. Passing false as the second - // value prevents qpdf from setting - // /NeedAppearances to true (but will not turn it - // off if it's already on), so we call - // generateAppearance after setting the value. You - // may or may not want to do this depending on - // whether the appearance streams generated by - // qpdf are good enough for your purposes. For - // additional details, please see comments in + // Set the value. Passing false as the second value prevents qpdf from setting + // /NeedAppearances to true (but will not turn it off if it's already on), so we + // call generateAppearance after setting the value. You may or may not want to + // do this depending on whether the appearance streams generated by qpdf are + // good enough for your purposes. For additional details, please see comments in // QPDFFormFieldObjectHelper.hh for this method. ffh.setV(value, false); ffh.generateAppearance(annot); diff --git a/examples/pdf-split-pages.cc b/examples/pdf-split-pages.cc index 9890ccf4..fde4bc1b 100644 --- a/examples/pdf-split-pages.cc +++ b/examples/pdf-split-pages.cc @@ -1,7 +1,6 @@ // -// This is a stand-alone example of splitting a PDF into individual -// pages. It does essentially the same thing that qpdf --split-pages -// does. +// This is a stand-alone example of splitting a PDF into individual pages. It does essentially the +// same thing that qpdf --split-pages does. // #include @@ -32,8 +31,7 @@ process(char const* whoami, char const* infile, std::string outprefix) QPDFPageDocumentHelper(outpdf).addPage(page, false); QPDFWriter outpdfw(outpdf, outfile.c_str()); if (static_id) { - // For the test suite, uncompress streams and use static - // IDs. + // For the test suite, uncompress streams and use static IDs. outpdfw.setStaticID(true); // for testing only outpdfw.setStreamDataMode(qpdf_s_uncompress); } diff --git a/examples/qpdf-job.cc b/examples/qpdf-job.cc index c7131f77..be868a17 100644 --- a/examples/qpdf-job.cc +++ b/examples/qpdf-job.cc @@ -3,8 +3,7 @@ #include -// This program is a simple demonstration of different ways to use the -// QPDFJob API. +// This program is a simple demonstration of different ways to use the QPDFJob API. static char const* whoami = nullptr; @@ -28,10 +27,9 @@ main(int argc, char* argv[]) usage(); } - // The examples below all catch std::exception. Note that - // QPDFUsage can be caught separately to report on errors in using - // the API itself. For CLI, this is command-line usage. For JSON - // or the API, it would be errors from the equivalent invocation. + // The examples below all catch std::exception. Note that QPDFUsage can be caught separately to + // report on errors in using the API itself. For CLI, this is command-line usage. For JSON or + // the API, it would be errors from the equivalent invocation. // Note that staticId is used for testing only. diff --git a/examples/qpdfjob-c-save-attachment.c b/examples/qpdfjob-c-save-attachment.c index c461f974..30e48127 100644 --- a/examples/qpdfjob-c-save-attachment.c +++ b/examples/qpdfjob-c-save-attachment.c @@ -6,10 +6,9 @@ #include #include -// This example demonstrates how we can redirect where saved output -// goes by calling the default logger's setSave method before running -// something with QPDFJob. See qpdfjob-c-save-attachment.c for an -// implementation that uses the C API. +// This example demonstrates how we can redirect where saved output goes by calling the default +// logger's setSave method before running something with QPDFJob. See qpdfjob-c-save-attachment.c +// for an implementation that uses the C API. static int save_to_file(char const* data, size_t len, void* udata) @@ -79,9 +78,8 @@ main(int argc, char* argv[]) }; outfile = do_fopen(outfilename); - /* Use qpdflogger_set_save with a callback function to redirect - * saved data. You can use other qpdf logger functions to capture - * informational output, warnings, and errors. + /* Use qpdflogger_set_save with a callback function to redirect saved data. You can use other + * qpdf logger functions to capture informational output, warnings, and errors. */ qpdflogger_set_save(l, qpdf_log_dest_custom, save_to_file, (void*)outfile, 0); qpdflogger_cleanup(&l); diff --git a/examples/qpdfjob-c.c b/examples/qpdfjob-c.c index 452e689b..62528392 100644 --- a/examples/qpdfjob-c.c +++ b/examples/qpdfjob-c.c @@ -1,7 +1,4 @@ -/* - * This is an example program to linearize a PDF file using the C - * QPDFJob API. - */ +/* This is an example program to linearize a PDF file using the C QPDFJob API. */ #include #include @@ -48,14 +45,12 @@ main(int argc, char* argv[]) new_argv[4] = "--static-id"; /* for testing only */ new_argv[5] = NULL; - /* See qpdf-job.cc for a C++ example of using the json interface. - * To use that from C just like the argv one, call - * qpdfjob_run_from_json instead and pass the json string as a - * single char const* argument. + /* See qpdf-job.cc for a C++ example of using the json interface. To use that from C just like + * the argv one, call qpdfjob_run_from_json instead and pass the json string as a single char + * const* argument. * - * See qpdfjob-c-save-attachment.c for an example of using the - * full form of the qpdfjob interface with init and cleanup - * functions. + * See qpdfjob-c-save-attachment.c for an example of using the full form of the qpdfjob + * interface with init and cleanup functions. */ r = qpdfjob_run_from_argv(new_argv); return r; diff --git a/examples/qpdfjob-remove-annotations.cc b/examples/qpdfjob-remove-annotations.cc index b0afa2da..bc043d33 100644 --- a/examples/qpdfjob-remove-annotations.cc +++ b/examples/qpdfjob-remove-annotations.cc @@ -6,10 +6,9 @@ #include #include -// This example demonstrates how we can use the QPDFJob createQPDF and writeQPDF -// methods to add custom transformations to the output produced by QPDFJob runs. -// The example is a full copy of the qpdf program modified to allways remove all -// annotations from the final output. +// This example demonstrates how we can use the QPDFJob createQPDF and writeQPDF methods to add +// custom transformations to the output produced by QPDFJob runs. The example is a full copy of the +// qpdf program modified to allways remove all annotations from the final output. static char const* whoami = nullptr; diff --git a/examples/qpdfjob-save-attachment.cc b/examples/qpdfjob-save-attachment.cc index 045e38bf..790d808f 100644 --- a/examples/qpdfjob-save-attachment.cc +++ b/examples/qpdfjob-save-attachment.cc @@ -3,10 +3,9 @@ #include #include -// This example demonstrates how we can redirect where saved output -// goes by calling the default logger's setSave method before running -// something with QPDFJob. See qpdfjob-c-save-attachment.c for an -// implementation that uses the C API. +// This example demonstrates how we can redirect where saved output goes by calling the default +// logger's setSave method before running something with QPDFJob. See qpdfjob-c-save-attachment.c +// for an implementation that uses the C API. int main(int argc, char* argv[]) diff --git a/include/qpdf/BufferInputSource.hh b/include/qpdf/BufferInputSource.hh index 8e1ea484..2ef04a28 100644 --- a/include/qpdf/BufferInputSource.hh +++ b/include/qpdf/BufferInputSource.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDF_BUFFERINPUTSOURCE_HH #define QPDF_BUFFERINPUTSOURCE_HH @@ -28,8 +25,8 @@ class QPDF_DLL_CLASS BufferInputSource: public InputSource { public: - // If own_memory is true, BufferInputSource will delete the buffer - // when finished with it. Otherwise, the caller owns the memory. + // If own_memory is true, BufferInputSource will delete the buffer when finished with it. + // Otherwise, the caller owns the memory. QPDF_DLL BufferInputSource(std::string const& description, Buffer* buf, bool own_memory = false); QPDF_DLL diff --git a/include/qpdf/ClosedFileInputSource.hh b/include/qpdf/ClosedFileInputSource.hh index 467c8c03..9f7e4fce 100644 --- a/include/qpdf/ClosedFileInputSource.hh +++ b/include/qpdf/ClosedFileInputSource.hh @@ -2,31 +2,27 @@ // // 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 +// 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. +// 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. +// 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 QPDF_CLOSEDFILEINPUTSOURCE_HH #define QPDF_CLOSEDFILEINPUTSOURCE_HH -// This is an input source that reads from files, like -// FileInputSource, except that it opens and close the file -// surrounding every operation. This decreases efficiency, but it allows -// many more of these to exist at once than the maximum number of open -// file descriptors. This is used for merging large numbers of files. +// This is an input source that reads from files, like FileInputSource, except that it opens and +// close the file surrounding every operation. This decreases efficiency, but it allows many more of +// these to exist at once than the maximum number of open file descriptors. This is used for merging +// large numbers of files. #include #include // unused -- remove in qpdf 12 (see #785) @@ -57,10 +53,9 @@ class QPDF_DLL_CLASS ClosedFileInputSource: public InputSource QPDF_DLL virtual void unreadCh(char ch); - // The file stays open between calls to stayOpen(true) and - // stayOpen(false). You can use this to surround multiple - // operations on a single ClosedFileInputSource to reduce the - // overhead of a separate open/close on each call. + // The file stays open between calls to stayOpen(true) and stayOpen(false). You can use this to + // surround multiple operations on a single ClosedFileInputSource to reduce the overhead of a + // separate open/close on each call. QPDF_DLL void stayOpen(bool); diff --git a/include/qpdf/FileInputSource.hh b/include/qpdf/FileInputSource.hh index 52d4a2e8..71adad7b 100644 --- a/include/qpdf/FileInputSource.hh +++ b/include/qpdf/FileInputSource.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDF_FILEINPUTSOURCE_HH #define QPDF_FILEINPUTSOURCE_HH diff --git a/include/qpdf/InputSource.hh b/include/qpdf/InputSource.hh index 91a5c6e5..2bc57c57 100644 --- a/include/qpdf/InputSource.hh +++ b/include/qpdf/InputSource.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDF_INPUTSOURCE_HH #define QPDF_INPUTSOURCE_HH @@ -30,9 +27,8 @@ #include #include -// Remember to use QPDF_DLL_CLASS on anything derived from InputSource -// so it will work with dynamic_cast across the shared object -// boundary. +// Remember to use QPDF_DLL_CLASS on anything derived from InputSource so it will work with +// dynamic_cast across the shared object boundary. class QPDF_DLL_CLASS InputSource { public: @@ -61,12 +57,10 @@ class QPDF_DLL_CLASS InputSource QPDF_DLL std::string readLine(size_t max_line_length); - // Find first or last occurrence of a sequence of characters - // starting within the range defined by offset and len such that, - // when the input source is positioned at the beginning of that - // sequence, finder.check() returns true. If len is 0, the search - // proceeds until EOF. If a qualifying pattern is found, these - // methods return true and leave the input source positioned + // Find first or last occurrence of a sequence of characters starting within the range defined + // by offset and len such that, when the input source is positioned at the beginning of that + // sequence, finder.check() returns true. If len is 0, the search proceeds until EOF. If a + // qualifying pattern is found, these methods return true and leave the input source positioned // wherever check() left it at the end of the matching pattern. QPDF_DLL bool findFirst(char const* start_chars, qpdf_offset_t offset, size_t len, Finder& finder); @@ -80,11 +74,9 @@ class QPDF_DLL_CLASS InputSource virtual void rewind() = 0; virtual size_t read(char* buffer, size_t length) = 0; - // Note: you can only unread the character you just read. The - // specific character is ignored by some implementations, and the - // implementation doesn't check this. Use of unreadCh is - // semantically equivalent to seek(-1, SEEK_CUR) but is much more - // efficient. + // Note: you can only unread the character you just read. The specific character is ignored by + // some implementations, and the implementation doesn't check this. Use of unreadCh is + // semantically equivalent to seek(-1, SEEK_CUR) but is much more efficient. virtual void unreadCh(char ch) = 0; // The following methods are for use by QPDFTokenizer @@ -149,9 +141,8 @@ InputSource::fastTell() inline bool InputSource::fastRead(char& ch) { - // Before calling fastRead, fastTell must be called to prepare the buffer. - // Once reading is complete, fastUnread must be called to set the correct - // file position. + // Before calling fastRead, fastTell must be called to prepare the buffer. Once reading is + // complete, fastUnread must be called to set the correct file position. if (this->buf_idx < this->buf_len) { ch = this->buffer[this->buf_idx]; ++(this->buf_idx); diff --git a/include/qpdf/PDFVersion.hh b/include/qpdf/PDFVersion.hh index 03d78899..1b2c45de 100644 --- a/include/qpdf/PDFVersion.hh +++ b/include/qpdf/PDFVersion.hh @@ -2,26 +2,22 @@ // // 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 +// 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. +// 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. +// 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. -// This class implements a simple writer for saving QPDF objects to -// new PDF files. See comments through the header file for additional -// details. +// This class implements a simple writer for saving QPDF objects to new PDF files. See comments +// through the header file for additional details. #ifndef PDFVERSION_HH #define PDFVERSION_HH @@ -32,10 +28,9 @@ class PDFVersion { public: - // Represent a PDF version. PDF versions are typically - // major.minor, but PDF 1.7 has several extension levels as the - // ISO 32000 spec was in progress. This class helps with - // comparison of versions. + // Represent a PDF version. PDF versions are typically major.minor, but PDF 1.7 has several + // extension levels as the ISO 32000 spec was in progress. This class helps with comparison of + // versions. QPDF_DLL PDFVersion(); QPDF_DLL @@ -49,13 +44,12 @@ class PDFVersion QPDF_DLL bool operator==(PDFVersion const& rhs) const; - // Replace this version with the other one if the other one is - // greater. + // Replace this version with the other one if the other one is greater. QPDF_DLL void updateIfGreater(PDFVersion const& other); - // Initialize a string and integer suitable for passing to - // QPDFWriter::setMinimumPDFVersion or QPDFWriter::forcePDFVersion. + // Initialize a string and integer suitable for passing to QPDFWriter::setMinimumPDFVersion or + // QPDFWriter::forcePDFVersion. QPDF_DLL void getVersion(std::string& version, int& extension_level) const; diff --git a/include/qpdf/Pipeline.hh b/include/qpdf/Pipeline.hh index 9b5bc483..bd5a7826 100644 --- a/include/qpdf/Pipeline.hh +++ b/include/qpdf/Pipeline.hh @@ -26,8 +26,7 @@ // // The client is required to call finish() before destroying a Pipeline in order to avoid loss of // data. A Pipeline class should not throw an exception in the destructor if this hasn't been done -// though since doing so causes too much trouble when deleting -// pipelines during error conditions. +// though since doing so causes too much trouble when deleting pipelines during error conditions. // // Some pipelines are reusable (i.e., you can call write() after calling finish() and can call // finish() multiple times) while others are not. It is up to the caller to use a pipeline diff --git a/include/qpdf/Pl_Buffer.hh b/include/qpdf/Pl_Buffer.hh index b244a9f5..39ef0746 100644 --- a/include/qpdf/Pl_Buffer.hh +++ b/include/qpdf/Pl_Buffer.hh @@ -47,8 +47,8 @@ class QPDF_DLL_CLASS Pl_Buffer: public Pipeline void finish() override; // Each call to getBuffer() resets this object -- see notes above. - // The caller is responsible for deleting the returned Buffer - // object. See also getBufferSharedPointer() and getMallocBuffer(). + // The caller is responsible for deleting the returned Buffer object. See also + // getBufferSharedPointer() and getMallocBuffer(). QPDF_DLL Buffer* getBuffer(); diff --git a/include/qpdf/Pl_Concatenate.hh b/include/qpdf/Pl_Concatenate.hh index 6ddb61c9..444a7482 100644 --- a/include/qpdf/Pl_Concatenate.hh +++ b/include/qpdf/Pl_Concatenate.hh @@ -2,31 +2,27 @@ // // 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 +// 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. +// 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. +// 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 PL_CONCATENATE_HH #define PL_CONCATENATE_HH -// This pipeline will drop all regular finished calls rather than -// passing them onto next. To finish downstream streams, call -// manualFinish. This makes it possible to pipe multiple streams -// (e.g. with QPDFObjectHandle::pipeStreamData) to a downstream like -// Pl_Flate that can't handle multiple calls to finish(). +// This pipeline will drop all regular finished calls rather than passing them onto next. To finish +// downstream streams, call manualFinish. This makes it possible to pipe multiple streams (e.g. +// with QPDFObjectHandle::pipeStreamData) to a downstream like Pl_Flate that can't handle multiple +// calls to finish(). #include @@ -44,8 +40,7 @@ class QPDF_DLL_CLASS Pl_Concatenate: public Pipeline QPDF_DLL virtual void finish(); - // At the very end, call manualFinish to actually finish the rest of - // the pipeline. + // At the very end, call manualFinish to actually finish the rest of the pipeline. QPDF_DLL void manualFinish(); diff --git a/include/qpdf/Pl_Count.hh b/include/qpdf/Pl_Count.hh index 2367aae9..51338607 100644 --- a/include/qpdf/Pl_Count.hh +++ b/include/qpdf/Pl_Count.hh @@ -2,28 +2,24 @@ // // 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 +// 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. +// 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. +// 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 PL_COUNT_HH #define PL_COUNT_HH -// This pipeline is reusable; i.e., it is safe to call write() after -// calling finish(). +// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). #include #include @@ -42,8 +38,8 @@ class QPDF_DLL_CLASS Pl_Count: public Pipeline // Returns the number of bytes written QPDF_DLL qpdf_offset_t getCount() const; - // Returns the last character written, or '\0' if no characters - // have been written (in which case getCount() returns 0) + // Returns the last character written, or '\0' if no characters have been written (in which case + // getCount() returns 0) QPDF_DLL unsigned char getLastChar() const; @@ -60,8 +56,7 @@ class QPDF_DLL_CLASS Pl_Count: public Pipeline Members(); Members(Members const&) = delete; - // Must be qpdf_offset_t, not size_t, to handle writing more than - // size_t can handle. + // Must be qpdf_offset_t, not size_t, to handle writing more than size_t can handle. qpdf_offset_t count; unsigned char last_char; }; diff --git a/include/qpdf/Pl_DCT.hh b/include/qpdf/Pl_DCT.hh index 9352091f..e4f6345f 100644 --- a/include/qpdf/Pl_DCT.hh +++ b/include/qpdf/Pl_DCT.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 PL_DCT_HH #define PL_DCT_HH @@ -27,8 +24,7 @@ #include #include -// jpeglib.h must be included after cstddef or else it messes up the -// definition of size_t. +// jpeglib.h must be included after cstddef or else it messes up the definition of size_t. #include class QPDF_DLL_CLASS Pl_DCT: public Pipeline diff --git a/include/qpdf/Pl_Discard.hh b/include/qpdf/Pl_Discard.hh index 1754fcab..b2733a66 100644 --- a/include/qpdf/Pl_Discard.hh +++ b/include/qpdf/Pl_Discard.hh @@ -2,31 +2,26 @@ // // 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 +// 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. +// 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. +// 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 PL_DISCARD_HH #define PL_DISCARD_HH -// This pipeline discards its output. It is an end-of-line pipeline -// (with no next). +// This pipeline discards its output. It is an end-of-line pipeline (with no next). -// This pipeline is reusable; i.e., it is safe to call write() after -// calling finish(). +// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). #include diff --git a/include/qpdf/Pl_Function.hh b/include/qpdf/Pl_Function.hh index e31d497d..c9d5550d 100644 --- a/include/qpdf/Pl_Function.hh +++ b/include/qpdf/Pl_Function.hh @@ -2,38 +2,33 @@ // // 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 +// 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. +// 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. +// 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 PL_FUNCTION_HH #define PL_FUNCTION_HH -// This pipeline calls an arbitrary function with whatever data is -// passed to it. This pipeline can be reused. +// This pipeline calls an arbitrary function with whatever data is passed to it. This pipeline can +// be reused. // -// For this pipeline, "next" may be null. If a next pointer is -// provided, this pipeline will also pass the data through to it and -// will forward finish() to it. +// For this pipeline, "next" may be null. If a next pointer is provided, this pipeline will also +// pass the data through to it and will forward finish() to it. // -// It is okay to not call finish() on this pipeline if it has no -// "next". +// It is okay to not call finish() on this pipeline if it has no "next". // -// It is okay to keep calling write() after a previous write throws an -// exception as long as the delegated function allows it. +// It is okay to keep calling write() after a previous write throws an exception as long as the +// delegated function allows it. #include @@ -48,10 +43,9 @@ class QPDF_DLL_CLASS Pl_Function: public Pipeline QPDF_DLL Pl_Function(char const* identifier, Pipeline* next, writer_t fn); - // The supplied C-style function is called every time write is - // called. The udata option is passed into the function with each - // call. If the function returns a non-zero value, a runtime error - // is thrown. + // The supplied C-style function is called every time write is called. The udata option is + // passed into the function with each call. If the function returns a non-zero value, a runtime + // error is thrown. typedef int (*writer_c_t)(unsigned char const*, size_t, void*); QPDF_DLL Pl_Function(char const* identifier, Pipeline* next, writer_c_t fn, void* udata); diff --git a/include/qpdf/Pl_OStream.hh b/include/qpdf/Pl_OStream.hh index 7bb3410d..3ea21c93 100644 --- a/include/qpdf/Pl_OStream.hh +++ b/include/qpdf/Pl_OStream.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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. // End-of-line pipeline that simply writes its data to a stdio FILE* object. @@ -35,8 +32,7 @@ class QPDF_DLL_CLASS Pl_OStream: public Pipeline { public: - // os is externally maintained; this class just writes to and - // flushes it. It does not close it. + // os is externally maintained; this class just writes to and flushes it. It does not close it. QPDF_DLL Pl_OStream(char const* identifier, std::ostream& os); QPDF_DLL diff --git a/include/qpdf/Pl_QPDFTokenizer.hh b/include/qpdf/Pl_QPDFTokenizer.hh index 37e87b4d..5bc6cb87 100644 --- a/include/qpdf/Pl_QPDFTokenizer.hh +++ b/include/qpdf/Pl_QPDFTokenizer.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 PL_QPDFTOKENIZER_HH #define PL_QPDFTOKENIZER_HH @@ -31,22 +28,19 @@ #include -// Tokenize the incoming text using QPDFTokenizer and pass the tokens -// in turn to a QPDFObjectHandle::TokenFilter object. All bytes of -// incoming content will be included in exactly one token and passed -// downstream. +// Tokenize the incoming text using QPDFTokenizer and pass the tokens in turn to a +// QPDFObjectHandle::TokenFilter object. All bytes of incoming content will be included in exactly +// one token and passed downstream. -// This is a very low-level interface for working with token filters. -// Most code will want to use QPDFObjectHandle::filterPageContents or -// QPDFObjectHandle::addTokenFilter. See QPDFObjectHandle.hh for -// details. +// This is a very low-level interface for working with token filters. Most code will want to use +// QPDFObjectHandle::filterPageContents or QPDFObjectHandle::addTokenFilter. See QPDFObjectHandle.hh +// for details. class QPDF_DLL_CLASS Pl_QPDFTokenizer: public Pipeline { public: - // Whatever pipeline is provided as "next" will be set as the - // pipeline that the token filter writes to. If next is not - // provided, any output written by the filter will be discarded. + // Whatever pipeline is provided as "next" will be set as the pipeline that the token filter + // writes to. If next is not provided, any output written by the filter will be discarded. QPDF_DLL Pl_QPDFTokenizer( char const* identifier, QPDFObjectHandle::TokenFilter* filter, Pipeline* next = nullptr); diff --git a/include/qpdf/Pl_RunLength.hh b/include/qpdf/Pl_RunLength.hh index 94f9ef57..86782535 100644 --- a/include/qpdf/Pl_RunLength.hh +++ b/include/qpdf/Pl_RunLength.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 PL_RUNLENGTH_HH #define PL_RUNLENGTH_HH diff --git a/include/qpdf/Pl_StdioFile.hh b/include/qpdf/Pl_StdioFile.hh index d175d3c3..90190d2b 100644 --- a/include/qpdf/Pl_StdioFile.hh +++ b/include/qpdf/Pl_StdioFile.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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. // End-of-line pipeline that simply writes its data to a stdio FILE* object. @@ -35,8 +32,7 @@ class QPDF_DLL_CLASS Pl_StdioFile: public Pipeline { public: - // f is externally maintained; this class just writes to and - // flushes it. It does not close it. + // f is externally maintained; this class just writes to and flushes it. It does not close it. QPDF_DLL Pl_StdioFile(char const* identifier, FILE* f); QPDF_DLL diff --git a/include/qpdf/Pl_String.hh b/include/qpdf/Pl_String.hh index cd4ec0f4..8f712fbf 100644 --- a/include/qpdf/Pl_String.hh +++ b/include/qpdf/Pl_String.hh @@ -2,39 +2,34 @@ // // 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 +// 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. +// 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. +// 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 PL_STRING_HH #define PL_STRING_HH -// This pipeline accumulates the data passed to it into a std::string, -// a reference to which is passed in at construction. Each subsequent -// use of this pipeline appends to the data accumulated so far. +// This pipeline accumulates the data passed to it into a std::string, a reference to which is +// passed in at construction. Each subsequent use of this pipeline appends to the data accumulated +// so far. // -// For this pipeline, "next" may be null. If a next pointer is -// provided, this pipeline will also pass the data through to it and -// will forward finish() to it. +// For this pipeline, "next" may be null. If a next pointer is provided, this pipeline will also +// pass the data through to it and will forward finish() to it. // -// It is okay to not call finish() on this pipeline if it has no -// "next". This makes it easy to stick this in front of another -// pipeline to capture data that is written to the other pipeline -// without interfering with when finish is called on the other -// pipeline and without having to put a Pl_Concatenate after it. +// It is okay to not call finish() on this pipeline if it has no "next". This makes it easy to stick +// this in front of another pipeline to capture data that is written to the other pipeline without +// interfering with when finish is called on the other pipeline and without having to put a +// Pl_Concatenate after it. #include diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index 707899cd..152421ad 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -68,7 +68,7 @@ class QPDF // read until they are needed. A QPDF object may be associated with only one file in its // lifetime. This method must be called before any methods that potentially ask for information // about the PDF file are called. Prior to calling this, the only methods that are allowed are - // those that set parameters. If the input file is not encrypted,either a null password or an + // those that set parameters. If the input file is not encrypted, either a null password or an // empty password can be used. If the file is encrypted, either the user password or the owner // password may be supplied. The method setPasswordIsHexKey may be called prior to calling this // method or any of the other process methods to force the password to be interpreted as a raw diff --git a/include/qpdf/QPDFAnnotationObjectHelper.hh b/include/qpdf/QPDFAnnotationObjectHelper.hh index b3d57092..9da0fd39 100644 --- a/include/qpdf/QPDFAnnotationObjectHelper.hh +++ b/include/qpdf/QPDFAnnotationObjectHelper.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFANNOTATIONOBJECTHELPER_HH #define QPDFANNOTATIONOBJECTHELPER_HH @@ -35,19 +32,16 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper QPDF_DLL virtual ~QPDFAnnotationObjectHelper() = default; - // This class provides helper methods for annotations. More - // functionality will likely be added in the future. + // This class provides helper methods for annotations. More functionality will likely be added + // in the future. - // Some functionality for annotations is also implemented in - // QPDFAcroFormDocumentHelper and QPDFFormFieldObjectHelper. In - // some cases, functions defined there work for other annotations - // besides widget annotations, but they are implemented with form - // fields so that they can properly handle form fields when - // needed. + // Some functionality for annotations is also implemented in QPDFAcroFormDocumentHelper and + // QPDFFormFieldObjectHelper. In some cases, functions defined there work for other annotations + // besides widget annotations, but they are implemented with form fields so that they can + // properly handle form fields when needed. - // Return the subtype of the annotation as a string (e.g. - // "/Widget"). Returns the empty string if the subtype (which is - // required by the spec) is missing. + // Return the subtype of the annotation as a string (e.g. "/Widget"). Returns the empty string + // if the subtype (which is required by the spec) is missing. QPDF_DLL std::string getSubtype(); @@ -57,39 +51,32 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper QPDF_DLL QPDFObjectHandle getAppearanceDictionary(); - // Return the appearance state as given in "/AS", or the empty - // string if none is given. + // Return the appearance state as given in "/AS", or the empty string if none is given. QPDF_DLL std::string getAppearanceState(); - // Return flags from "/F". The value is a logical or of - // pdf_annotation_flag_e as defined in qpdf/Constants.h. + // Return flags from "/F". The value is a logical or of pdf_annotation_flag_e as defined in + // qpdf/Constants.h. QPDF_DLL int getFlags(); - // Return a specific stream. "which" may be one of "/N", "/R", or - // "/D" to indicate the normal, rollover, or down appearance - // stream. (Any value may be passed to "which"; if an appearance - // stream of that name exists, it will be returned.) If the value - // associated with "which" in the appearance dictionary is a - // subdictionary, an appearance state may be specified to select - // which appearance stream is desired. If not specified, the - // appearance state in "/AS" will used. + // Return a specific stream. "which" may be one of "/N", "/R", or "/D" to indicate the normal, + // rollover, or down appearance stream. (Any value may be passed to "which"; if an appearance + // stream of that name exists, it will be returned.) If the value associated with "which" in the + // appearance dictionary is a subdictionary, an appearance state may be specified to select + // which appearance stream is desired. If not specified, the appearance state in "/AS" will + // used. QPDF_DLL QPDFObjectHandle getAppearanceStream(std::string const& which, std::string const& state = ""); - // Generate text suitable for addition to the containing page's - // content stream that draws this annotation's appearance stream - // as a form XObject. The value "name" is the resource name that - // will be used to refer to the form xobject. The value "rotate" - // should be set to the page's /Rotate value or 0 if none. The - // values of required_flags and forbidden_flags are constructed by - // logically "or"ing annotation flags of type - // pdf_annotation_flag_e defined in qpdf/Constants.h. Content will - // be returned only if all required_flags are set and no - // forbidden_flags are set. For example, including an_no_view in - // forbidden_flags could be useful for creating an on-screen view, - // and including an_print to required_flags could be useful if + // Generate text suitable for addition to the containing page's content stream that draws this + // annotation's appearance stream as a form XObject. The value "name" is the resource name that + // will be used to refer to the form xobject. The value "rotate" should be set to the page's + // /Rotate value or 0 if none. The values of required_flags and forbidden_flags are constructed + // by logically "or"ing annotation flags of type pdf_annotation_flag_e defined in + // qpdf/Constants.h. Content will be returned only if all required_flags are set and no + // forbidden_flags are set. For example, including an_no_view in forbidden_flags could be useful + // for creating an on-screen view, and including an_print to required_flags could be useful if // preparing to print. QPDF_DLL std::string getPageContentForAppearance( diff --git a/include/qpdf/QPDFCryptoProvider.hh b/include/qpdf/QPDFCryptoProvider.hh index 46a9379d..f1f7801c 100644 --- a/include/qpdf/QPDFCryptoProvider.hh +++ b/include/qpdf/QPDFCryptoProvider.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFCRYPTOPROVIDER_HH #define QPDFCRYPTOPROVIDER_HH @@ -30,35 +27,30 @@ #include #include -// This class is part of qpdf's pluggable crypto provider support. -// Most users won't need to know or care about this class, but you can -// use it if you want to supply your own crypto implementation. See -// also comments in QPDFCryptoImpl.hh. +// This class is part of qpdf's pluggable crypto provider support. Most users won't need to know or +// care about this class, but you can use it if you want to supply your own crypto implementation. +// See also comments in QPDFCryptoImpl.hh. class QPDFCryptoProvider { public: - // Methods for getting and registering crypto implementations. - // These methods are not thread-safe. + // Methods for getting and registering crypto implementations. These methods are not + // thread-safe. - // Return an instance of a crypto provider using the default - // implementation. + // Return an instance of a crypto provider using the default implementation. QPDF_DLL static std::shared_ptr getImpl(); - // Return an instance of the crypto provider registered using the - // given name. + // Return an instance of the crypto provider registered using the given name. QPDF_DLL static std::shared_ptr getImpl(std::string const& name); - // Register the given type (T) as a crypto implementation. T must - // be derived from QPDFCryptoImpl and must have a constructor that - // takes no arguments. + // Register the given type (T) as a crypto implementation. T must be derived from QPDFCryptoImpl + // and must have a constructor that takes no arguments. template QPDF_DLL static void registerImpl(std::string const& name); - // Set the crypto provider registered with the given name as the - // default crypto implementation. + // Set the crypto provider registered with the given name as the default crypto implementation. QPDF_DLL static void setDefaultProvider(std::string const& name); diff --git a/include/qpdf/QPDFDocumentHelper.hh b/include/qpdf/QPDFDocumentHelper.hh index dcdecf01..bb614843 100644 --- a/include/qpdf/QPDFDocumentHelper.hh +++ b/include/qpdf/QPDFDocumentHelper.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFDOCUMENTHELPER_HH #define QPDFDOCUMENTHELPER_HH @@ -25,16 +22,13 @@ #include #include -// This is a base class for QPDF Document Helper classes. Document -// helpers are classes that provide a convenient, higher-level API for -// accessing document-level structures with a PDF file. Document -// helpers are always initialized with a reference to a QPDF object, -// and the object can always be retrieved. The intention is that you -// may freely intermix use of document helpers with the underlying -// QPDF object unless there is a specific comment in a specific helper -// method that says otherwise. The pattern of using helper objects was -// introduced to allow creation of higher level helper functions -// without polluting the public interface of QPDF. +// This is a base class for QPDF Document Helper classes. Document helpers are classes that provide +// a convenient, higher-level API for accessing document-level structures with a PDF file. Document +// helpers are always initialized with a reference to a QPDF object, and the object can always be +// retrieved. The intention is that you may freely intermix use of document helpers with the +// underlying QPDF object unless there is a specific comment in a specific helper method that says +// otherwise. The pattern of using helper objects was introduced to allow creation of higher level +// helper functions without polluting the public interface of QPDF. class QPDF_DLL_CLASS QPDFDocumentHelper { diff --git a/include/qpdf/QPDFEFStreamObjectHelper.hh b/include/qpdf/QPDFEFStreamObjectHelper.hh index b164dbe3..ab26b2c1 100644 --- a/include/qpdf/QPDFEFStreamObjectHelper.hh +++ b/include/qpdf/QPDFEFStreamObjectHelper.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFEFSTREAMOBJECTHELPER_HH #define QPDFEFSTREAMOBJECTHELPER_HH @@ -29,9 +26,8 @@ #include #include -// This class provides a higher level interface around Embedded File -// Streams, which are discussed in section 7.11.4 of the ISO-32000 PDF -// specification. +// This class provides a higher level interface around Embedded File Streams, which are discussed in +// section 7.11.4 of the ISO-32000 PDF specification. class QPDFEFStreamObjectHelper: public QPDFObjectHelper { @@ -41,11 +37,10 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper QPDF_DLL virtual ~QPDFEFStreamObjectHelper() = default; - // Date parameters are strings that conform to the PDF spec for - // date/time strings, which is "D:yyyymmddhhmmss" where is - // either "Z" for UTC or "-hh'mm'" or "+hh'mm'" for timezone - // offset. Examples: "D:20210207161528-05'00'", - // "D:20210207211528Z". See QUtil::qpdf_time_to_pdf_time. + // Date parameters are strings that conform to the PDF spec for date/time strings, which is + // "D:yyyymmddhhmmss" where is either "Z" for UTC or "-hh'mm'" or "+hh'mm'" for timezone + // offset. Examples: "D:20210207161528-05'00'", "D:20210207211528Z". See + // QUtil::qpdf_time_to_pdf_time. QPDF_DLL std::string getCreationDate(); @@ -57,32 +52,27 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper // Subtype is a mime type such as "text/plain" QPDF_DLL std::string getSubtype(); - // Return the checksum as stored in the object as a binary string. - // This does not check consistency with the data. If not present, - // return an empty string. The PDF spec specifies this as an MD5 - // checksum and notes that it is not to be used for security - // purposes since MD5 is known not to be secure. + // Return the checksum as stored in the object as a binary string. This does not check + // consistency with the data. If not present, return an empty string. The PDF spec specifies + // this as an MD5 checksum and notes that it is not to be used for security purposes since MD5 + // is known not to be secure. QPDF_DLL std::string getChecksum(); - // Setters return a reference to this object so that they can be - // used as fluent interfaces, e.g. + // Setters return a reference to this object so that they can be used as fluent interfaces, e.g. // efsoh.setCreationDate(x).setModDate(y); - // Create a new embedded file stream with the given stream data, - // which can be provided in any of several ways. To get the new - // object back, call getObjectHandle() on the returned object. The - // checksum and size are computed automatically and stored. Other - // parameters may be supplied using setters defined below. + // Create a new embedded file stream with the given stream data, which can be provided in any of + // several ways. To get the new object back, call getObjectHandle() on the returned object. The + // checksum and size are computed automatically and stored. Other parameters may be supplied + // using setters defined below. QPDF_DLL static QPDFEFStreamObjectHelper createEFStream(QPDF& qpdf, std::shared_ptr data); QPDF_DLL static QPDFEFStreamObjectHelper createEFStream(QPDF& qpdf, std::string const& data); - // The provider function must write the data to the given - // pipeline. The function may be called multiple times by the qpdf - // library. You can pass QUtil::file_provider(filename) as the - // provider to have the qpdf library provide the contents of - // filename as a binary. + // The provider function must write the data to the given pipeline. The function may be called + // multiple times by the qpdf library. You can pass QUtil::file_provider(filename) as the + // provider to have the qpdf library provide the contents of filename as a binary. QPDF_DLL static QPDFEFStreamObjectHelper createEFStream(QPDF& qpdf, std::function provider); @@ -93,8 +83,7 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper QPDF_DLL QPDFEFStreamObjectHelper& setModDate(std::string const&); - // Set subtype as a mime-type, e.g. "text/plain" or - // "application/pdf". + // Set subtype as a mime-type, e.g. "text/plain" or "application/pdf". QPDF_DLL QPDFEFStreamObjectHelper& setSubtype(std::string const&); diff --git a/include/qpdf/QPDFEmbeddedFileDocumentHelper.hh b/include/qpdf/QPDFEmbeddedFileDocumentHelper.hh index 5ee608bd..4727feef 100644 --- a/include/qpdf/QPDFEmbeddedFileDocumentHelper.hh +++ b/include/qpdf/QPDFEmbeddedFileDocumentHelper.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFEMBEDDEDFILEDOCUMENTHELPER_HH #define QPDFEMBEDDEDFILEDOCUMENTHELPER_HH @@ -32,9 +29,9 @@ #include #include -// This class provides a higher level interface around document-level -// file attachments, also known as embedded files. These are discussed -// in sections 7.7.4 and 7.11 of the ISO-32000 PDF specification. +// This class provides a higher level interface around document-level file attachments, also known +// as embedded files. These are discussed in sections 7.7.4 and 7.11 of the ISO-32000 PDF +// specification. class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper { @@ -50,8 +47,8 @@ class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper QPDF_DLL std::map> getEmbeddedFiles(); - // If an embedded file with the given name exists, return a - // (shared) pointer to it. Otherwise, return nullptr. + // If an embedded file with the given name exists, return a (shared) pointer to it. Otherwise, + // return nullptr. QPDF_DLL std::shared_ptr getEmbeddedFile(std::string const& name); @@ -59,14 +56,11 @@ class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper QPDF_DLL void replaceEmbeddedFile(std::string const& name, QPDFFileSpecObjectHelper const&); - // Remove an embedded file if present. Return value is true if the - // file was present and was removed. This method not only removes - // the embedded file from the embedded files name tree but also - // nulls out the file specification dictionary. This means that - // any references to this file from file attachment annotations - // will also stop working. This is the best way to make the - // attachment actually disappear from the file and not just from - // the list of attachments. + // Remove an embedded file if present. Return value is true if the file was present and was + // removed. This method not only removes the embedded file from the embedded files name tree but + // also nulls out the file specification dictionary. This means that any references to this file + // from file attachment annotations will also stop working. This is the best way to make the + // attachment actually disappear from the file and not just from the list of attachments. QPDF_DLL bool removeEmbeddedFile(std::string const& name); diff --git a/include/qpdf/QPDFFileSpecObjectHelper.hh b/include/qpdf/QPDFFileSpecObjectHelper.hh index 040399bc..9b6474df 100644 --- a/include/qpdf/QPDFFileSpecObjectHelper.hh +++ b/include/qpdf/QPDFFileSpecObjectHelper.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFFILESPECOBJECTHELPER_HH #define QPDFFILESPECOBJECTHELPER_HH @@ -29,9 +26,8 @@ #include #include -// This class provides a higher level interface around File -// Specification dictionaries, which are discussed in section 7.11 of -// the ISO-32000 PDF specification. +// This class provides a higher level interface around File Specification dictionaries, which are +// discussed in section 7.11 of the ISO-32000 PDF specification. class QPDFFileSpecObjectHelper: public QPDFObjectHelper { @@ -44,45 +40,38 @@ class QPDFFileSpecObjectHelper: public QPDFObjectHelper QPDF_DLL std::string getDescription(); - // Get the main filename for this file specification. In priority - // order, check /UF, /F, /Unix, /DOS, /Mac. + // Get the main filename for this file specification. In priority order, check /UF, /F, /Unix, + // /DOS, /Mac. QPDF_DLL std::string getFilename(); - // Return any of /UF, /F, /Unix, /DOS, /Mac filename keys that may - // be present in the object. + // Return any of /UF, /F, /Unix, /DOS, /Mac filename keys that may be present in the object. QPDF_DLL std::map getFilenames(); - // Get the requested embedded file stream for this file - // specification. If key is empty, In priority order, check /UF, - // /F, /Unix, /DOS, /Mac. Returns a null object if not found. If - // this is an actual embedded file stream, its data is the content - // of the attachment. You can also use - // QPDFEFStreamObjectHelper for higher level access to - // the parameters. + // Get the requested embedded file stream for this file specification. If key is empty, In + // priority order, check /UF, /F, /Unix, /DOS, /Mac. Returns a null object if not found. If this + // is an actual embedded file stream, its data is the content of the attachment. You can also + // use QPDFEFStreamObjectHelper for higher level access to the parameters. QPDF_DLL QPDFObjectHandle getEmbeddedFileStream(std::string const& key = ""); - // Return the /EF key of the file spec, which is a map from file - // name key to embedded file stream. + // Return the /EF key of the file spec, which is a map from file name key to embedded file + // stream. QPDF_DLL QPDFObjectHandle getEmbeddedFileStreams(); - // Setters return a reference to this object so that they can be - // used as fluent interfaces, e.g. + // Setters return a reference to this object so that they can be used as fluent interfaces, e.g. // fsoh.setDescription(x).setFilename(y); - // Create a new filespec as an indirect object with the given - // filename, and attach the contents of the specified file as data - // in an embedded file stream. + // Create a new filespec as an indirect object with the given filename, and attach the contents + // of the specified file as data in an embedded file stream. QPDF_DLL static QPDFFileSpecObjectHelper createFileSpec(QPDF& qpdf, std::string const& filename, std::string const& fullpath); - // Create a new filespec as an indirect object with the given - // unicode filename and embedded file stream. The file name will - // be used as both /UF and /F. If you need to override, call + // Create a new filespec as an indirect object with the given unicode filename and embedded file + // stream. The file name will be used as both /UF and /F. If you need to override, call // setFilename. QPDF_DLL static QPDFFileSpecObjectHelper @@ -90,11 +79,9 @@ class QPDFFileSpecObjectHelper: public QPDFObjectHelper QPDF_DLL QPDFFileSpecObjectHelper& setDescription(std::string const&); - // setFilename sets /UF to unicode_name. If compat_name is empty, - // it is also set to unicode_name. unicode_name should be a UTF-8 - // encoded string. compat_name is converted to a string - // QPDFObjectHandle literally, preserving whatever encoding it - // might happen to have. + // setFilename sets /UF to unicode_name. If compat_name is empty, it is also set to + // unicode_name. unicode_name should be a UTF-8 encoded string. compat_name is converted to a + // string QPDFObjectHandle literally, preserving whatever encoding it might happen to have. QPDF_DLL QPDFFileSpecObjectHelper& setFilename(std::string const& unicode_name, std::string const& compat_name = ""); diff --git a/include/qpdf/QPDFLogger.hh b/include/qpdf/QPDFLogger.hh index 2b7c7a9b..0b77d57a 100644 --- a/include/qpdf/QPDFLogger.hh +++ b/include/qpdf/QPDFLogger.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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_HH #define QPDFLOGGER_HH @@ -33,18 +30,14 @@ class QPDFLogger QPDF_DLL static std::shared_ptr create(); - // Return the default logger. In general, you should use the - // default logger. You can also create your own loggers and use - // them QPDF and QPDFJob objects, but there are few reasons to do - // so. One reason may if you are using multiple QPDF or QPDFJob - // objects in different threads and want to capture output and - // errors to different streams. (Note that a single QPDF or - // QPDFJob can't be safely used from multiple threads, but it is - // safe to use separate QPDF and QPDFJob objects on separate - // threads.) Another possible reason would be if you are writing - // an application that uses the qpdf library directly and qpdf is - // also used by a downstream library or if you are using qpdf from - // a library and don't want to interfere with potential uses of + // Return the default logger. In general, you should use the default logger. You can also create + // your own loggers and use them QPDF and QPDFJob objects, but there are few reasons to do so. + // One reason may if you are using multiple QPDF or QPDFJob objects in different threads and + // want to capture output and errors to different streams. (Note that a single QPDF or QPDFJob + // can't be safely used from multiple threads, but it is safe to use separate QPDF and QPDFJob + // objects on separate threads.) Another possible reason would be if you are writing an + // application that uses the qpdf library directly and qpdf is also used by a downstream library + // or if you are using qpdf from a library and don't want to interfere with potential uses of // qpdf by other libraries or applications. QPDF_DLL static std::shared_ptr defaultLogger(); @@ -56,50 +49,40 @@ class QPDFLogger // error -- standard error // save -- undefined unless set // - // "info" is used for diagnostic messages, verbose messages, and - // progress messages. "warn" is used for warnings. "error" is used - // for errors. "save" is used for saving output -- see below. + // "info" is used for diagnostic messages, verbose messages, and progress messages. "warn" is + // used for warnings. "error" is used for errors. "save" is used for saving output -- see below. // - // On deletion, finish() is called for the standard output and - // standard error pipelines, which flushes output. If you supply - // any custom pipelines, you must call finish() on them yourself. - // Note that calling finish is not needed for string, stdio, or - // ostream pipelines. + // On deletion, finish() is called for the standard output and standard error pipelines, which + // flushes output. If you supply any custom pipelines, you must call finish() on them yourself. + // Note that calling finish is not needed for string, stdio, or ostream pipelines. // // NOTES ABOUT THE SAVE PIPELINE // - // The save pipeline is used by QPDFJob when some kind of binary - // output is being saved. This includes saving attachments and - // stream data and also includes when the output file is standard - // output. If you want to grab that output, you can call setSave. - // See examples/qpdfjob-save-attachment.cc and - // examples/qpdfjob-c-save-attachment.c. + // The save pipeline is used by QPDFJob when some kind of binary output is being saved. This + // includes saving attachments and stream data and also includes when the output file is + // standard output. If you want to grab that output, you can call setSave. See + // examples/qpdfjob-save-attachment.cc and examples/qpdfjob-c-save-attachment.c. // - // You should never set the save pipeline to the same destination - // as something else. Doing so will corrupt your save output. If - // you want to save to standard output, use the method - // saveToStandardOutput(). In addition to setting the save - // pipeline, that does the following extra things: + // You should never set the save pipeline to the same destination as something else. Doing so + // will corrupt your save output. If you want to save to standard output, use the method + // saveToStandardOutput(). In addition to setting the save pipeline, that does the following + // extra things: // // * If standard output has been used, a logic error is thrown - // * If info is set to standard output at the time of the set save - // call, it is switched to standard error. + // * If info is set to standard output at the time of the set save call, it is switched to + // standard error. // - // This is not a guarantee. You can still mess this up in ways - // that are not checked. Here are a few examples: + // This is not a guarantee. You can still mess this up in ways that are not checked. Here are a + // few examples: // - // * Don't set any pipeline to standard output *after* passing it - // to setSave() - // * Don't use a separate mechanism to write stdout/stderr other - // than QPDFLogger::standardOutput() - // * Don't set anything to the same custom pipeline that save is - // set to. + // * Don't set any pipeline to standard output *after* passing it to setSave() + // * Don't use a separate mechanism to write stdout/stderr other than + // QPDFLogger::standardOutput() + // * Don't set anything to the same custom pipeline that save is set to. // - // Just be sure that if you change pipelines around, you should - // avoid having the save pipeline also be used for any other - // purpose. The special case for saving to standard output allows - // you to call saveToStandardOutput() early without having to - // worry about the info pipeline. + // Just be sure that if you change pipelines around, you should avoid having the save pipeline + // also be used for any other purpose. The special case for saving to standard output allows you + // to call saveToStandardOutput() early without having to worry about the info pipeline. QPDF_DLL void info(char const*); @@ -145,9 +128,8 @@ class QPDFLogger QPDF_DLL 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 - // warning is cleared so that it follows error. + // Shortcut for logic to reset output to new output/error streams. out_stream is used for info, + // err_stream is used for error, and warning is cleared so that it follows error. QPDF_DLL void setOutputStreams(std::ostream* out_stream, std::ostream* err_stream); diff --git a/include/qpdf/QPDFMatrix.hh b/include/qpdf/QPDFMatrix.hh index fb005e50..7abe6ec6 100644 --- a/include/qpdf/QPDFMatrix.hh +++ b/include/qpdf/QPDFMatrix.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFMATRIX_HH #define QPDFMATRIX_HH @@ -26,8 +23,7 @@ #include #include -// This class represents a PDF transformation matrix using a tuple -// such that +// This class represents a PDF transformation matrix using a tuple such that // // ┌ ┐ // │ a b 0 │ @@ -45,8 +41,7 @@ class QPDFMatrix QPDF_DLL QPDFMatrix(QPDFObjectHandle::Matrix const&); - // Returns the six values separated by spaces as real numbers with - // trimmed zeroes. + // Returns the six values separated by spaces as real numbers with trimmed zeroes. QPDF_DLL std::string unparse() const; @@ -75,14 +70,12 @@ class QPDFMatrix QPDF_DLL void transform(double x, double y, double& xp, double& yp) const; - // Transform a rectangle by creating a new rectangle that tightly - // bounds the polygon resulting from transforming the four - // corners. + // Transform a rectangle by creating a new rectangle that tightly bounds the polygon resulting + // from transforming the four corners. QPDF_DLL QPDFObjectHandle::Rectangle transformRectangle(QPDFObjectHandle::Rectangle r) const; - // operator== tests for exact equality, not considering deltas for - // floating point. + // operator== tests for exact equality, not considering deltas for floating point. QPDF_DLL bool operator==(QPDFMatrix const& rhs) const; QPDF_DLL diff --git a/include/qpdf/QPDFNameTreeObjectHelper.hh b/include/qpdf/QPDFNameTreeObjectHelper.hh index e0023013..9e59e1fb 100644 --- a/include/qpdf/QPDFNameTreeObjectHelper.hh +++ b/include/qpdf/QPDFNameTreeObjectHelper.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFNAMETREEOBJECTHELPER_HH #define QPDFNAMETREEOBJECTHELPER_HH @@ -30,13 +27,11 @@ #include -// This is an object helper for name trees. See section 7.9.6 in the -// PDF spec (ISO 32000) for a description of name trees. When looking -// up items in the name tree, use UTF-8 strings. All names are -// normalized for lookup purposes. +// This is an object helper for name trees. See section 7.9.6 in the PDF spec (ISO 32000) for a +// description of name trees. When looking up items in the name tree, use UTF-8 strings. All names +// are normalized for lookup purposes. -// See examples/pdf-name-number-tree.cc for a demonstration of using -// QPDFNameTreeObjectHelper. +// See examples/pdf-name-number-tree.cc for a demonstration of using QPDFNameTreeObjectHelper. class NNTreeImpl; class NNTreeIterator; @@ -45,8 +40,8 @@ class NNTreeDetails; class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper { public: - // The qpdf object is required so that this class can issue - // warnings, attempt repairs, and add indirect objects. + // The qpdf object is required so that this class can issue warnings, attempt repairs, and add + // indirect objects. QPDF_DLL QPDFNameTreeObjectHelper(QPDFObjectHandle, QPDF&, bool auto_repair = true); @@ -57,13 +52,11 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper QPDF_DLL virtual ~QPDFNameTreeObjectHelper(); - // Return whether the number tree has an explicit entry for this - // number. + // Return whether the number tree has an explicit entry for this number. QPDF_DLL bool hasName(std::string const& utf8); - // Find an object by name. If found, returns true and initializes - // oh. See also find(). + // Find an object by name. If found, returns true and initializes oh. See also find(). QPDF_DLL bool findObject(std::string const& utf8, QPDFObjectHandle& oh); @@ -115,21 +108,17 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper return !operator==(other); } - // DANGER: this method can create inconsistent trees if not - // used properly! Insert a new item immediately after the - // current iterator and increment so that it points to the new - // item. If the current iterator is end(), insert at the - // beginning. This method does not check for proper ordering, - // so if you use it, you must ensure that the item you are - // inserting belongs where you are putting it. The reason for - // this method is that it is more efficient than insert() and - // can be used safely when you are creating a new tree and - // inserting items in sorted order. + // DANGER: this method can create inconsistent trees if not used properly! Insert a new item + // immediately after the current iterator and increment so that it points to the new item. + // If the current iterator is end(), insert at the beginning. This method does not check for + // proper ordering, so if you use it, you must ensure that the item you are inserting + // belongs where you are putting it. The reason for this method is that it is more efficient + // than insert() and can be used safely when you are creating a new tree and inserting items + // in sorted order. QPDF_DLL void insertAfter(std::string const& key, QPDFObjectHandle value); - // Remove the current item and advance the iterator to the - // next item. + // Remove the current item and advance the iterator to the next item. QPDF_DLL void remove(); @@ -141,10 +130,9 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper value_type ivalue; }; - // The iterator looks like map iterator, so i.first is a string - // and i.second is a QPDFObjectHandle. Incrementing end() brings - // you to the first item. Decrementing end() brings you to the - // last item. + // The iterator looks like map iterator, so i.first is a string and i.second is a + // QPDFObjectHandle. Incrementing end() brings you to the first item. Decrementing end() brings + // you to the last item. QPDF_DLL iterator begin() const; QPDF_DLL @@ -153,8 +141,8 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper QPDF_DLL iterator last() const; - // Find the entry with the given key. If return_prev_if_not_found - // is true and the item is not found, return the next lower item. + // Find the entry with the given key. If return_prev_if_not_found is true and the item is not + // found, return the next lower item. QPDF_DLL iterator find(std::string const& key, bool return_prev_if_not_found = false); @@ -162,20 +150,18 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper QPDF_DLL iterator insert(std::string const& key, QPDFObjectHandle value); - // Remove an item. Return true if the item was found and removed; - // otherwise return false. If value is not null, initialize it to - // the value that was removed. + // Remove an item. Return true if the item was found and removed; otherwise return false. If + // value is not null, initialize it to the value that was removed. QPDF_DLL bool remove(std::string const& key, QPDFObjectHandle* value = nullptr); - // Return the contents of the name tree as a map. Note that name - // trees may be very large, so this may use a lot of RAM. It is - // more efficient to use QPDFNameTreeObjectHelper's iterator. + // Return the contents of the name tree as a map. Note that name trees may be very large, so + // this may use a lot of RAM. It is more efficient to use QPDFNameTreeObjectHelper's iterator. QPDF_DLL std::map getAsMap() const; - // Split a node if the number of items exceeds this value. There's - // no real reason to ever set this except for testing. + // Split a node if the number of items exceeds this value. There's no real reason to ever set + // this except for testing. QPDF_DLL void setSplitThreshold(int); diff --git a/include/qpdf/QPDFNumberTreeObjectHelper.hh b/include/qpdf/QPDFNumberTreeObjectHelper.hh index 82933b21..f2a66026 100644 --- a/include/qpdf/QPDFNumberTreeObjectHelper.hh +++ b/include/qpdf/QPDFNumberTreeObjectHelper.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFNUMBERTREEOBJECTHELPER_HH #define QPDFNUMBERTREEOBJECTHELPER_HH @@ -29,11 +26,10 @@ #include -// This is an object helper for number trees. See section 7.9.7 in the -// PDF spec (ISO 32000) for a description of number trees. +// This is an object helper for number trees. See section 7.9.7 in the PDF spec (ISO 32000) for a +// description of number trees. -// See examples/pdf-name-number-tree.cc for a demonstration of using -// QPDFNumberTreeObjectHelper. +// See examples/pdf-name-number-tree.cc for a demonstration of using QPDFNumberTreeObjectHelper. class NNTreeImpl; class NNTreeIterator; @@ -42,8 +38,8 @@ class NNTreeDetails; class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper { public: - // The qpdf object is required so that this class can issue - // warnings, attempt repairs, and add indirect objects. + // The qpdf object is required so that this class can issue warnings, attempt repairs, and add + // indirect objects. QPDF_DLL QPDFNumberTreeObjectHelper(QPDFObjectHandle, QPDF&, bool auto_repair = true); @@ -62,24 +58,20 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper QPDF_DLL numtree_number getMax(); - // Return whether the number tree has an explicit entry for this - // number. + // Return whether the number tree has an explicit entry for this number. QPDF_DLL bool hasIndex(numtree_number idx); - // Find an object with a specific index. If found, returns true - // and initializes oh. See also find(). + // Find an object with a specific index. If found, returns true and initializes oh. See also + // find(). QPDF_DLL bool findObject(numtree_number idx, QPDFObjectHandle& oh); - // Find the object at the index or, if not found, the object whose - // index is the highest index less than the requested index. If - // the requested index is less than the minimum, return false. - // Otherwise, return true, initialize oh to the object, and set - // offset to the difference between the requested index and the - // actual index. For example, if a number tree has values for 3 - // and 6 and idx is 5, this method would return true, initialize - // oh to the value with index 3, and set offset to 2 (5 - 3). See - // also find(). + // Find the object at the index or, if not found, the object whose index is the highest index + // less than the requested index. If the requested index is less than the minimum, return false. + // Otherwise, return true, initialize oh to the object, and set offset to the difference between + // the requested index and the actual index. For example, if a number tree has values for 3 and + // 6 and idx is 5, this method would return true, initialize oh to the value with index 3, and + // set offset to 2 (5 - 3). See also find(). QPDF_DLL bool findObjectAtOrBelow(numtree_number idx, QPDFObjectHandle& oh, numtree_number& offset); @@ -131,21 +123,17 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper return !operator==(other); } - // DANGER: this method can create inconsistent trees if not - // used properly! Insert a new item immediately after the - // current iterator and increment so that it points to the new - // item. If the current iterator is end(), insert at the - // beginning. This method does not check for proper ordering, - // so if you use it, you must ensure that the item you are - // inserting belongs where you are putting it. The reason for - // this method is that it is more efficient than insert() and - // can be used safely when you are creating a new tree and - // inserting items in sorted order. + // DANGER: this method can create inconsistent trees if not used properly! Insert a new item + // immediately after the current iterator and increment so that it points to the new item. + // If the current iterator is end(), insert at the beginning. This method does not check for + // proper ordering, so if you use it, you must ensure that the item you are inserting + // belongs where you are putting it. The reason for this method is that it is more efficient + // than insert() and can be used safely when you are creating a new tree and inserting items + // in sorted order. QPDF_DLL void insertAfter(numtree_number key, QPDFObjectHandle value); - // Remove the current item and advance the iterator to the - // next item. + // Remove the current item and advance the iterator to the next item. QPDF_DLL void remove(); @@ -157,10 +145,9 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper value_type ivalue; }; - // The iterator looks like map iterator, so i.first is a string - // and i.second is a QPDFObjectHandle. Incrementing end() brings - // you to the first item. Decrementing end() brings you to the - // last item. + // The iterator looks like map iterator, so i.first is a string and i.second is a + // QPDFObjectHandle. Incrementing end() brings you to the first item. Decrementing end() brings + // you to the last item. QPDF_DLL iterator begin() const; QPDF_DLL @@ -169,8 +156,8 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper QPDF_DLL iterator last() const; - // Find the entry with the given key. If return_prev_if_not_found - // is true and the item is not found, return the next lower item. + // Find the entry with the given key. If return_prev_if_not_found is true and the item is not + // found, return the next lower item. QPDF_DLL iterator find(numtree_number key, bool return_prev_if_not_found = false); @@ -178,22 +165,19 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper QPDF_DLL iterator insert(numtree_number key, QPDFObjectHandle value); - // Remove an item. Return true if the item was found and removed; - // otherwise return false. If value is not null, initialize it to - // the value that was removed. + // Remove an item. Return true if the item was found and removed; otherwise return false. If + // value is not null, initialize it to the value that was removed. QPDF_DLL bool remove(numtree_number key, QPDFObjectHandle* value = nullptr); - // Return the contents of the number tree as a map. Note that - // number trees may be very large, so this may use a lot of RAM. - // It is more efficient to use QPDFNumberTreeObjectHelper's - // iterator. + // Return the contents of the number tree as a map. Note that number trees may be very large, so + // this may use a lot of RAM. It is more efficient to use QPDFNumberTreeObjectHelper's iterator. typedef std::map idx_map; QPDF_DLL idx_map getAsMap() const; - // Split a node if the number of items exceeds this value. There's - // no real reason to ever set this except for testing. + // Split a node if the number of items exceeds this value. There's no real reason to ever set + // this except for testing. QPDF_DLL void setSplitThreshold(int); diff --git a/include/qpdf/QPDFObjGen.hh b/include/qpdf/QPDFObjGen.hh index 851e8d11..0f22b481 100644 --- a/include/qpdf/QPDFObjGen.hh +++ b/include/qpdf/QPDFObjGen.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFOBJGEN_HH #define QPDFOBJGEN_HH @@ -29,8 +26,8 @@ class QPDFObjectHandle; class QPDFObjectHelper; -// This class represents an object ID and generation pair. It is -// suitable to use as a key in a map or set. +// This class represents an object ID and generation pair. It is suitable to use as a key in a map +// or set. class QPDFObjGen { @@ -91,13 +88,11 @@ class QPDFObjGen // Convenience class for loop detection when processing objects. // - // The class adds 'add' methods to a std::set which allows - // to test whether an QPDFObjGen is present in the set and to insert it in - // a single operation. The 'add' method is overloaded to take a QPDFObjGen, - // QPDFObjectHandle or an QPDFObjectHelper as parameter. + // The class adds 'add' methods to a std::set which allows to test whether an + // QPDFObjGen is present in the set and to insert it in a single operation. The 'add' method is + // overloaded to take a QPDFObjGen, QPDFObjectHandle or an QPDFObjectHelper as parameter. // - // The erase method is modified to ignore requests to erase - // QPDFObjGen(0, 0). + // The erase method is modified to ignore requests to erase QPDFObjGen(0, 0). // // Usage example: // @@ -112,8 +107,8 @@ class QPDFObjGen class QPDF_DLL_CLASS set: public std::set { public: - // Add 'og' to the set. Return false if 'og' is already present in - // the set. Attempts to insert QPDFObjGen(0, 0) are ignored. + // Add 'og' to the set. Return false if 'og' is already present in the set. Attempts to + // insert QPDFObjGen(0, 0) are ignored. QPDF_DLL bool add(QPDFObjGen og) @@ -150,9 +145,8 @@ class QPDFObjGen }; private: - // This class does not use the Members pattern to avoid a memory - // allocation for every one of these. A lot of these get created - // and destroyed. + // This class does not use the Members pattern to avoid a memory allocation for every one of + // these. A lot of these get created and destroyed. int obj{0}; int gen{0}; }; diff --git a/include/qpdf/QPDFObjectHelper.hh b/include/qpdf/QPDFObjectHelper.hh index e79eff9d..30853a74 100644 --- a/include/qpdf/QPDFObjectHelper.hh +++ b/include/qpdf/QPDFObjectHelper.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFOBJECTHELPER_HH #define QPDFOBJECTHELPER_HH @@ -26,16 +23,13 @@ #include -// This is a base class for QPDF Object Helper classes. Object helpers -// are classes that provide a convenient, higher-level API for working -// with specific types of QPDF objects. Object helpers are always -// initialized with a QPDFObjectHandle, and the underlying object -// handle can always be retrieved. The intention is that you may -// freely intermix use of document helpers with the underlying QPDF -// objects unless there is a specific comment in a specific helper -// method that says otherwise. The pattern of using helper objects was -// introduced to allow creation of higher level helper functions -// without polluting the public interface of QPDFObjectHandle. +// This is a base class for QPDF Object Helper classes. Object helpers are classes that provide a +// convenient, higher-level API for working with specific types of QPDF objects. Object helpers are +// always initialized with a QPDFObjectHandle, and the underlying object handle can always be +// retrieved. The intention is that you may freely intermix use of document helpers with the +// underlying QPDF objects unless there is a specific comment in a specific helper method that says +// otherwise. The pattern of using helper objects was introduced to allow creation of higher level +// helper functions without polluting the public interface of QPDFObjectHandle. class QPDF_DLL_CLASS QPDFObjectHelper { diff --git a/include/qpdf/QPDFOutlineDocumentHelper.hh b/include/qpdf/QPDFOutlineDocumentHelper.hh index 38310302..23e4902c 100644 --- a/include/qpdf/QPDFOutlineDocumentHelper.hh +++ b/include/qpdf/QPDFOutlineDocumentHelper.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFOUTLINEDOCUMENTHELPER_HH #define QPDFOUTLINEDOCUMENTHELPER_HH @@ -33,11 +30,10 @@ #include -// This is a document helper for outlines, also known as bookmarks. -// Outlines are discussed in section 12.3.3 of the PDF spec -// (ISO-32000). With the help of QPDFOutlineObjectHelper, the outlines -// tree is traversed, and a bidirectional map is made between pages -// and outlines. See also QPDFOutlineObjectHelper. +// This is a document helper for outlines, also known as bookmarks. Outlines are discussed in +// section 12.3.3 of the PDF spec (ISO-32000). With the help of QPDFOutlineObjectHelper, the +// outlines tree is traversed, and a bidirectional map is made between pages and outlines. See also +// QPDFOutlineObjectHelper. class QPDFOutlineDocumentHelper: public QPDFDocumentHelper { @@ -53,15 +49,13 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper QPDF_DLL std::vector getTopLevelOutlines(); - // If the name is a name object, look it up in the /Dests key of - // the document catalog. If the name is a string, look it up in - // the name tree pointed to by the /Dests key of the names + // If the name is a name object, look it up in the /Dests key of the document catalog. If the + // name is a string, look it up in the name tree pointed to by the /Dests key of the names // dictionary. QPDF_DLL QPDFObjectHandle resolveNamedDest(QPDFObjectHandle name); - // Return a list outlines that are known to target the specified - // page + // Return a list outlines that are known to target the specified page QPDF_DLL std::vector getOutlinesForPage(QPDFObjGen const&); diff --git a/include/qpdf/QPDFOutlineObjectHelper.hh b/include/qpdf/QPDFOutlineObjectHelper.hh index 0ecbdd54..8a0b10c9 100644 --- a/include/qpdf/QPDFOutlineObjectHelper.hh +++ b/include/qpdf/QPDFOutlineObjectHelper.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFOUTLINEOBJECTHELPER_HH #define QPDFOUTLINEOBJECTHELPER_HH @@ -30,9 +27,8 @@ class QPDFOutlineDocumentHelper; #include -// This is an object helper for outline items. Outlines, also known as -// bookmarks, are described in section 12.3.3 of the PDF spec -// (ISO-32000). See comments below for details. +// This is an object helper for outline items. Outlines, also known as bookmarks, are described in +// section 12.3.3 of the PDF spec (ISO-32000). See comments below for details. class QPDFOutlineObjectHelper: public QPDFObjectHelper { @@ -40,16 +36,15 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper QPDF_DLL virtual ~QPDFOutlineObjectHelper() { - // This must be cleared explicitly to avoid circular references - // that prevent cleanup of pointer holders. + // This must be cleared explicitly to avoid circular references that prevent cleanup of + // pointer holders. m->parent = nullptr; } - // All constructors are private. You can only create one of these - // using QPDFOutlineDocumentHelper. + // All constructors are private. You can only create one of these using + // QPDFOutlineDocumentHelper. - // Return parent pointer. Returns a null pointer if this is a - // top-level outline. + // Return parent pointer. Returns a null pointer if this is a top-level outline. QPDF_DLL std::shared_ptr getParent(); @@ -57,29 +52,25 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper QPDF_DLL std::vector getKids(); - // Return the destination, regardless of whether it is named or - // explicit and whether it is directly provided or in a GoTo - // action. Returns a null object if the destination can't be - // determined. Named destinations can be resolved using the older - // root /Dest dictionary or the current names tree. + // Return the destination, regardless of whether it is named or explicit and whether it is + // directly provided or in a GoTo action. Returns a null object if the destination can't be + // determined. Named destinations can be resolved using the older root /Dest dictionary or the + // current names tree. QPDF_DLL QPDFObjectHandle getDest(); - // Return the page that the outline points to. Returns a null - // object if the destination page can't be determined. + // Return the page that the outline points to. Returns a null object if the destination page + // can't be determined. QPDF_DLL QPDFObjectHandle getDestPage(); - // Returns the value of /Count as present in the object, or 0 if - // not present. If count is positive, the outline is open. If - // negative, it is closed. Either way, the absolute value is the - // number descendant items that would be visible if this were - // open. + // Returns the value of /Count as present in the object, or 0 if not present. If count is + // positive, the outline is open. If negative, it is closed. Either way, the absolute value is + // the number descendant items that would be visible if this were open. QPDF_DLL int getCount(); - // Returns the title as a UTF-8 string. Returns the empty string - // if there is no title. + // Returns the title as a UTF-8 string. Returns the empty string if there is no title. QPDF_DLL std::string getTitle(); diff --git a/include/qpdf/QPDFPageDocumentHelper.hh b/include/qpdf/QPDFPageDocumentHelper.hh index 2cabbbb0..351a04f0 100644 --- a/include/qpdf/QPDFPageDocumentHelper.hh +++ b/include/qpdf/QPDFPageDocumentHelper.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFPAGEDOCUMENTHELPER_HH #define QPDFPAGEDOCUMENTHELPER_HH @@ -42,67 +39,53 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper QPDF_DLL virtual ~QPDFPageDocumentHelper() = default; - // Traverse page tree, and return all /Page objects wrapped in - // QPDFPageObjectHelper objects. Unlike with - // QPDF::getAllPages, the vector of pages returned by - // this call is not affected by additions or removals of pages. If - // you manipulate pages, you will have to call this again to get a - // new copy. Please see comments in QPDF.hh for getAllPages() for - // additional details. + // Traverse page tree, and return all /Page objects wrapped in QPDFPageObjectHelper objects. + // Unlike with QPDF::getAllPages, the vector of pages returned by this call is not affected by + // additions or removals of pages. If you manipulate pages, you will have to call this again to + // get a new copy. Please see comments in QPDF.hh for getAllPages() for additional details. QPDF_DLL std::vector getAllPages(); - // The PDF /Pages tree allows inherited values. Working with the - // pages of a pdf is much easier when the inheritance is resolved - // by explicitly setting the values in each /Page. + // The PDF /Pages tree allows inherited values. Working with the pages of a pdf is much easier + // when the inheritance is resolved by explicitly setting the values in each /Page. QPDF_DLL void pushInheritedAttributesToPage(); - // This calls QPDFPageObjectHelper::removeUnreferencedResources - // for every page in the document. See comments in - // QPDFPageObjectHelper.hh for details. + // This calls QPDFPageObjectHelper::removeUnreferencedResources for every page in the document. + // See comments in QPDFPageObjectHelper.hh for details. QPDF_DLL void removeUnreferencedResources(); - // Add new page at the beginning or the end of the current pdf. - // The newpage parameter may be either a direct object, an - // indirect object from this QPDF, or an indirect object from - // another QPDF. If it is a direct object, it will be made - // indirect. If it is an indirect object from another QPDF, this - // method will call pushInheritedAttributesToPage on the other - // file and then copy the page to this QPDF using the same - // underlying code as copyForeignObject. At this stage, if the - // indirect object is already in the pages tree, a shallow copy is - // made to avoid adding the same page more than once. In version - // 10.3.1 and earlier, adding a page that already existed would - // throw an exception and could cause qpdf to crash on subsequent - // page insertions in some cases. Note that this means that, in - // some cases, the page actually added won't be exactly the same - // object as the one passed in. If you want to do subsequent + // Add new page at the beginning or the end of the current pdf. The newpage parameter may be + // either a direct object, an indirect object from this QPDF, or an indirect object from another + // QPDF. If it is a direct object, it will be made indirect. If it is an indirect object from + // another QPDF, this method will call pushInheritedAttributesToPage on the other file and then + // copy the page to this QPDF using the same underlying code as copyForeignObject. At this + // stage, if the indirect object is already in the pages tree, a shallow copy is made to avoid + // adding the same page more than once. In version 10.3.1 and earlier, adding a page that + // already existed would throw an exception and could cause qpdf to crash on subsequent page + // insertions in some cases. Note that this means that, in some cases, the page actually added + // won't be exactly the same object as the one passed in. If you want to do subsequent // modification on the page, you should retrieve it again. // - // Note that you can call copyForeignObject directly to copy a - // page from a different file, but the resulting object will not - // be a page in the new file. You could do this, for example, to - // convert a page into a form XObject, though for that, you're - // better off using QPDFPageObjectHelper::getFormXObjectForPage. + // Note that you can call copyForeignObject directly to copy a page from a different file, but + // the resulting object will not be a page in the new file. You could do this, for example, to + // convert a page into a form XObject, though for that, you're better off using + // QPDFPageObjectHelper::getFormXObjectForPage. // - // This method does not have any specific awareness of annotations - // or form fields, so if you just add a page without thinking - // about it, you might end up with two pages that share form - // fields or annotations. While the page may look fine, it will - // probably not function properly with regard to interactive - // features. To work around this, you should called - // QPDFAcroFormDocumentHelper::fixCopiedAnnotations. A future - // version of qpdf will likely provide a higher-level interface - // for copying pages around that will handle document-level + // This method does not have any specific awareness of annotations or form fields, so if you + // just add a page without thinking about it, you might end up with two pages that share form + // fields or annotations. While the page may look fine, it will probably not function properly + // with regard to interactive features. To work around this, you should called + // QPDFAcroFormDocumentHelper::fixCopiedAnnotations. A future version of qpdf will likely + // provide a higher-level interface for copying pages around that will handle document-level // constructs in a less error-prone fashion. QPDF_DLL void addPage(QPDFPageObjectHelper newpage, bool first); - // Add new page before or after refpage. See comments for addPage - // for details about what newpage should be. + // Add new page before or after refpage. See comments for addPage for details about what newpage + // should be. QPDF_DLL void addPageAt(QPDFPageObjectHelper newpage, bool before, QPDFPageObjectHelper refpage); @@ -110,17 +93,13 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper QPDF_DLL void removePage(QPDFPageObjectHelper page); - // For every annotation, integrate the annotation's appearance - // stream into the containing page's content streams, merge the - // annotation's resources with the page's resources, and remove - // the annotation from the page. Handles widget annotations - // associated with interactive form fields as a special case, - // including removing the /AcroForm key from the document catalog. - // The values passed to required_flags and forbidden_flags are - // passed along to - // QPDFAnnotationObjectHelper::getPageContentForAppearance. See - // comments there in QPDFAnnotationObjectHelper.hh for meanings of - // those flags. + // For every annotation, integrate the annotation's appearance stream into the containing page's + // content streams, merge the annotation's resources with the page's resources, and remove the + // annotation from the page. Handles widget annotations associated with interactive form fields + // as a special case, including removing the /AcroForm key from the document catalog. The values + // passed to required_flags and forbidden_flags are passed along to + // QPDFAnnotationObjectHelper::getPageContentForAppearance. See comments there in + // QPDFAnnotationObjectHelper.hh for meanings of those flags. QPDF_DLL void flattenAnnotations(int required_flags = 0, int forbidden_flags = an_invisible | an_hidden); diff --git a/include/qpdf/QPDFPageLabelDocumentHelper.hh b/include/qpdf/QPDFPageLabelDocumentHelper.hh index dbb0a07e..64e85869 100644 --- a/include/qpdf/QPDFPageLabelDocumentHelper.hh +++ b/include/qpdf/QPDFPageLabelDocumentHelper.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFPAGELABELDOCUMENTHELPER_HH #define QPDFPAGELABELDOCUMENTHELPER_HH @@ -30,18 +27,15 @@ #include -// Page labels are discussed in the PDF spec (ISO-32000) in section -// 12.4.2. +// Page labels are discussed in the PDF spec (ISO-32000) in section 12.4.2. // -// Page labels are implemented as a number tree. Each key is a page -// index, numbered from 0. The values are dictionaries with the -// following keys, all optional: +// Page labels are implemented as a number tree. Each key is a page index, numbered from 0. The +// values are dictionaries with the following keys, all optional: // // * /Type: if present, must be /PageLabel -// * /S: one of /D, /R, /r, /A, or /a for decimal, upper-case and -// lower-case Roman numeral, or upper-case and lower-case alphabetic -// * /P: if present, a fixed prefix string that is prepended to each -// page number +// * /S: one of /D, /R, /r, /A, or /a for decimal, upper-case and lower-case Roman numeral, or +// upper-case and lower-case alphabetic +// * /P: if present, a fixed prefix string that is prepended to each page number // * /St: the starting number, or 1 if not specified class QPDFPageLabelDocumentHelper: public QPDFDocumentHelper @@ -55,25 +49,20 @@ class QPDFPageLabelDocumentHelper: public QPDFDocumentHelper QPDF_DLL bool hasPageLabels(); - // Return a page label dictionary representing the page label for - // the given page. The page does not need to appear explicitly in - // the page label dictionary. This method will adjust /St as + // Return a page label dictionary representing the page label for the given page. The page does + // not need to appear explicitly in the page label dictionary. This method will adjust /St as // needed to produce a label that is suitable for the page. QPDF_DLL QPDFObjectHandle getLabelForPage(long long page_idx); - // Append to the incoming vector a list of objects suitable for - // inclusion in a /PageLabels dictionary's /Nums field. start_idx - // and end_idx are the indexes to the starting and ending pages - // (inclusive) in the original file, and new_start_idx is the - // index to the first page in the new file. For example, if pages - // 10 through 12 of one file are being copied to a new file as - // pages 6 through 8, you would call getLabelsForPageRange(10, 12, - // 6), which would return as many entries as are required to add - // to the new file's PageLabels. This method fabricates a suitable - // entry even if the original document has no page labels. This - // behavior facilitates using this function to incrementally build - // up a page labels tree when merging files. + // Append to the incoming vector a list of objects suitable for inclusion in a /PageLabels + // dictionary's /Nums field. start_idx and end_idx are the indexes to the starting and ending + // pages (inclusive) in the original file, and new_start_idx is the index to the first page in + // the new file. For example, if pages 10 through 12 of one file are being copied to a new file + // as pages 6 through 8, you would call getLabelsForPageRange(10, 12, 6), which would return as + // many entries as are required to add to the new file's PageLabels. This method fabricates a + // suitable entry even if the original document has no page labels. This behavior facilitates + // using this function to incrementally build up a page labels tree when merging files. QPDF_DLL void getLabelsForPageRange( long long start_idx, diff --git a/include/qpdf/QPDFStreamFilter.hh b/include/qpdf/QPDFStreamFilter.hh index fec12851..4664f213 100644 --- a/include/qpdf/QPDFStreamFilter.hh +++ b/include/qpdf/QPDFStreamFilter.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFSTREAMFILTER_HH #define QPDFSTREAMFILTER_HH @@ -35,36 +32,29 @@ class QPDF_DLL_CLASS QPDFStreamFilter QPDF_DLL virtual ~QPDFStreamFilter() = default; - // A QPDFStreamFilter class must implement, at a minimum, - // setDecodeParms() and getDecodePipeline(). QPDF will always call - // setDecodeParms() before calling getDecodePipeline(). It is - // expected that you will store any needed information from - // decode_parms (or the decode_parms object itself) in your - // instance so that it can be used to construct the decode - // pipeline. + // A QPDFStreamFilter class must implement, at a minimum, setDecodeParms() and + // getDecodePipeline(). QPDF will always call setDecodeParms() before calling + // getDecodePipeline(). It is expected that you will store any needed information from + // decode_parms (or the decode_parms object itself) in your instance so that it can be used to + // construct the decode pipeline. - // Return a boolean indicating whether your filter can proceed - // with the given /DecodeParms. The default implementation accepts - // a null object and rejects everything else. + // Return a boolean indicating whether your filter can proceed with the given /DecodeParms. The + // default implementation accepts a null object and rejects everything else. QPDF_DLL virtual bool setDecodeParms(QPDFObjectHandle decode_parms); - // Return a pipeline that will decode data encoded with your - // filter. Your implementation must ensure that the pipeline is - // deleted when the instance of your class is destroyed. + // Return a pipeline that will decode data encoded with your filter. Your implementation must + // ensure that the pipeline is deleted when the instance of your class is destroyed. QPDF_DLL virtual Pipeline* getDecodePipeline(Pipeline* next) = 0; - // If your filter implements "specialized" compression or lossy - // compression, override one or both of these methods. The default - // implementations return false. See comments in QPDFWriter for - // details. QPDF defines specialized compression as non-lossy - // compression not intended for general-purpose data. qpdf, by - // default, doesn't mess with streams that are compressed with - // specialized compression, the idea being that the decision to - // use that compression scheme would fall outside of what - // QPDFWriter would know anything about, so any attempt to decode - // and re-encode would probably be undesirable. + // If your filter implements "specialized" compression or lossy compression, override one or + // both of these methods. The default implementations return false. See comments in QPDFWriter + // for details. QPDF defines specialized compression as non-lossy compression not intended for + // general-purpose data. qpdf, by default, doesn't mess with streams that are compressed with + // specialized compression, the idea being that the decision to use that compression scheme + // would fall outside of what QPDFWriter would know anything about, so any attempt to decode and + // re-encode would probably be undesirable. QPDF_DLL virtual bool isSpecializedCompression(); QPDF_DLL diff --git a/include/qpdf/QPDFSystemError.hh b/include/qpdf/QPDFSystemError.hh index fe75b272..7833b070 100644 --- a/include/qpdf/QPDFSystemError.hh +++ b/include/qpdf/QPDFSystemError.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFSYSTEMERROR_HH #define QPDFSYSTEMERROR_HH @@ -37,9 +34,8 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error QPDF_DLL virtual ~QPDFSystemError() noexcept = default; - // To get a complete error string, call what(), provided by - // std::exception. The accessors below return the original values - // used to create the exception. + // To get a complete error string, call what(), provided by std::exception. The accessors below + // return the original values used to create the exception. QPDF_DLL std::string const& getDescription() const; @@ -50,8 +46,8 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error QPDF_DLL_PRIVATE static std::string createWhat(std::string const& description, int system_errno); - // This class does not use the Members pattern to avoid needless - // memory allocations during exception handling. + // This class does not use the Members pattern to avoid needless memory allocations during + // exception handling. std::string description; int system_errno; diff --git a/include/qpdf/QPDFUsage.hh b/include/qpdf/QPDFUsage.hh index e1cadc10..538392a0 100644 --- a/include/qpdf/QPDFUsage.hh +++ b/include/qpdf/QPDFUsage.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFUSAGE_HH #define QPDFUSAGE_HH diff --git a/include/qpdf/QPDFWriter.hh b/include/qpdf/QPDFWriter.hh index d14d907f..63fba056 100644 --- a/include/qpdf/QPDFWriter.hh +++ b/include/qpdf/QPDFWriter.hh @@ -2,26 +2,22 @@ // // 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 +// 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. +// 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. +// 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. -// This class implements a simple writer for saving QPDF objects to -// new PDF files. See comments through the header file for additional -// details. +// This class implements a simple writer for saving QPDF objects to new PDF files. See comments +// through the header file for additional details. #ifndef QPDFWRITER_HH #define QPDFWRITER_HH @@ -57,21 +53,19 @@ class Pl_MD5; class QPDFWriter { public: - // Construct a QPDFWriter object without specifying output. You - // must call one of the output setting routines defined below. + // Construct a QPDFWriter object without specifying output. You must call one of the output + // setting routines defined below. QPDF_DLL QPDFWriter(QPDF& pdf); - // Create a QPDFWriter object that writes its output to a file or - // to stdout. This is equivalent to using the previous - // constructor and then calling setOutputFilename(). See + // Create a QPDFWriter object that writes its output to a file or to stdout. This is equivalent + // to using the previous constructor and then calling setOutputFilename(). See // setOutputFilename() for details. QPDF_DLL QPDFWriter(QPDF& pdf, char const* filename); - // Create a QPDFWriter object that writes its output to an already - // open FILE*. This is equivalent to calling the first - // constructor and then calling setOutputFile(). See + // Create a QPDFWriter object that writes its output to an already open FILE*. This is + // equivalent to calling the first constructor and then calling setOutputFile(). See // setOutputFile() for details. QPDF_DLL QPDFWriter(QPDF& pdf, char const* description, FILE* file, bool close_file); @@ -85,15 +79,13 @@ class QPDFWriter QPDF_DLL virtual ~ProgressReporter(); - // This method is called with a value from 0 to 100 to - // indicate approximate progress through the write process. - // See registerProgressReporter. + // This method is called with a value from 0 to 100 to indicate approximate progress through + // the write process. See registerProgressReporter. virtual void reportProgress(int) = 0; }; - // This is a progress reporter that takes a function. It is used - // by the C APIs, but it is available if you want to just register - // a C function as a handler. + // This is a progress reporter that takes a function. It is used by the C APIs, but it is + // available if you want to just register a C function as a handler. class QPDF_DLL_CLASS FunctionProgressReporter: public ProgressReporter { public: @@ -108,39 +100,31 @@ class QPDFWriter std::function handler; }; - // Setting Output. Output may be set only one time. If you don't - // use the filename version of the QPDFWriter constructor, you - // must call exactly one of these methods. + // Setting Output. Output may be set only one time. If you don't use the filename version of + // the QPDFWriter constructor, you must call exactly one of these methods. - // Passing null as filename means write to stdout. QPDFWriter - // will create a zero-length output file upon construction. If - // write fails, the empty or partially written file will not be - // deleted. This is by design: sometimes the partial file may be - // useful for tracking down problems. If your application doesn't - // want the partially written file to be left behind, you should - // delete it the eventual call to write fails. + // Passing null as filename means write to stdout. QPDFWriter will create a zero-length output + // file upon construction. If write fails, the empty or partially written file will not be + // deleted. This is by design: sometimes the partial file may be useful for tracking down + // problems. If your application doesn't want the partially written file to be left behind, you + // should delete it the eventual call to write fails. QPDF_DLL void setOutputFilename(char const* filename); - // Write to the given FILE*, which must be opened by the caller. - // If close_file is true, QPDFWriter will close the file. - // Otherwise, the caller must close the file. The file does not - // need to be seekable; it will be written to in a single pass. - // It must be open in binary mode. + // Write to the given FILE*, which must be opened by the caller. If close_file is true, + // QPDFWriter will close the file. Otherwise, the caller must close the file. The file does not + // need to be seekable; it will be written to in a single pass. It must be open in binary mode. QPDF_DLL void setOutputFile(char const* description, FILE* file, bool close_file); - // Indicate that QPDFWriter should create a memory buffer to - // contain the final PDF file. Obtain the memory by calling - // getBuffer(). + // Indicate that QPDFWriter should create a memory buffer to contain the final PDF file. Obtain + // the memory by calling getBuffer(). QPDF_DLL void setOutputMemory(); - // Return the buffer object containing the PDF file. If - // setOutputMemory() has been called, this method may be called - // exactly one time after write() has returned. The caller is - // responsible for deleting the buffer when done. See also - // getBufferSharedPointer(). + // Return the buffer object containing the PDF file. If setOutputMemory() has been called, this + // method may be called exactly one time after write() has returned. The caller is responsible + // for deleting the buffer when done. See also getBufferSharedPointer(). QPDF_DLL Buffer* getBuffer(); @@ -148,33 +132,27 @@ class QPDFWriter QPDF_DLL std::shared_ptr getBufferSharedPointer(); - // Supply your own pipeline object. Output will be written to - // this pipeline, and QPDFWriter will call finish() on the - // pipeline. It is the caller's responsibility to manage the - // memory for the pipeline. The pipeline is never deleted by - // QPDFWriter, which makes it possible for you to call additional - // methods on the pipeline after the writing is finished. + // Supply your own pipeline object. Output will be written to this pipeline, and QPDFWriter + // will call finish() on the pipeline. It is the caller's responsibility to manage the memory + // for the pipeline. The pipeline is never deleted by QPDFWriter, which makes it possible for + // you to call additional methods on the pipeline after the writing is finished. QPDF_DLL void setOutputPipeline(Pipeline*); // Setting Parameters - // Set the value of object stream mode. In disable mode, we never - // generate any object streams. In preserve mode, we preserve - // object stream structure from the original file. In generate - // mode, we generate our own object streams. In all cases, we - // generate a conventional cross-reference table if there are no - // object streams and a cross-reference stream if there are object - // streams. The default is o_preserve. + // Set the value of object stream mode. In disable mode, we never generate any object streams. + // In preserve mode, we preserve object stream structure from the original file. In generate + // mode, we generate our own object streams. In all cases, we generate a conventional + // cross-reference table if there are no object streams and a cross-reference stream if there + // are object streams. The default is o_preserve. QPDF_DLL void setObjectStreamMode(qpdf_object_stream_e); - // Set value of stream data mode. This is an older interface. - // Instead of using this, prefer setCompressStreams() and - // setDecodeLevel(). This method is retained for compatibility, - // but it does not cover the full range of available - // configurations. The mapping between this and the new methods is - // as follows: + // Set value of stream data mode. This is an older interface. Instead of using this, prefer + // setCompressStreams() and setDecodeLevel(). This method is retained for compatibility, but it + // does not cover the full range of available configurations. The mapping between this and the + // new methods is as follows: // // qpdf_s_uncompress: // setCompressStreams(false) @@ -190,205 +168,161 @@ class QPDFWriter QPDF_DLL void setStreamDataMode(qpdf_stream_data_e); - // If true, compress any uncompressed streams when writing them. - // Metadata streams are a special case and are not compressed even - // if this is true. This is true by default for QPDFWriter. If you - // want QPDFWriter to leave uncompressed streams uncompressed, - // pass false to this method. + // If true, compress any uncompressed streams when writing them. Metadata streams are a special + // case and are not compressed even if this is true. This is true by default for QPDFWriter. If + // you want QPDFWriter to leave uncompressed streams uncompressed, pass false to this method. QPDF_DLL void setCompressStreams(bool); - // When QPDFWriter encounters streams, this parameter controls the - // behavior with respect to attempting to apply any filters to the - // streams when copying to the output. The decode levels are as - // follows: + // When QPDFWriter encounters streams, this parameter controls the behavior with respect to + // attempting to apply any filters to the streams when copying to the output. The decode levels + // are as follows: // - // qpdf_dl_none: Do not attempt to apply any filters. Streams - // remain as they appear in the original file. Note that - // uncompressed streams may still be compressed on output. You can + // qpdf_dl_none: Do not attempt to apply any filters. Streams remain as they appear in the + // original file. Note that uncompressed streams may still be compressed on output. You can // disable that by calling setCompressStreams(false). // - // qpdf_dl_generalized: This is the default. QPDFWriter will apply - // LZWDecode, ASCII85Decode, ASCIIHexDecode, and FlateDecode - // filters on the input. When combined with - // setCompressStreams(true), which the default, the effect of this - // is that streams filtered with these older and less efficient - // filters will be recompressed with the Flate filter. By default, - // as a special case, if a stream is already compressed with - // FlateDecode and setCompressStreams is enabled, the original - // compressed data will be preserved. This behavior can be - // overridden by calling setRecompressFlate(true). + // qpdf_dl_generalized: This is the default. QPDFWriter will apply LZWDecode, ASCII85Decode, + // ASCIIHexDecode, and FlateDecode filters on the input. When combined with + // setCompressStreams(true), which the default, the effect of this is that streams filtered with + // these older and less efficient filters will be recompressed with the Flate filter. By + // default, as a special case, if a stream is already compressed with FlateDecode and + // setCompressStreams is enabled, the original compressed data will be preserved. This behavior + // can be overridden by calling setRecompressFlate(true). // - // qpdf_dl_specialized: In addition to uncompressing the - // generalized compression formats, supported non-lossy - // compression will also be decoded. At present, this includes - // the RunLengthDecode filter. + // qpdf_dl_specialized: In addition to uncompressing the generalized compression formats, + // supported non-lossy compression will also be decoded. At present, this includes the + // RunLengthDecode filter. // - // qpdf_dl_all: In addition to generalized and non-lossy - // specialized filters, supported lossy compression filters will - // be applied. At present, this includes DCTDecode (JPEG) - // compression. Note that compressing the resulting data with - // DCTDecode again will accumulate loss, so avoid multiple - // compression and decompression cycles. This is mostly useful for - // retrieving image data. + // qpdf_dl_all: In addition to generalized and non-lossy specialized filters, supported lossy + // compression filters will be applied. At present, this includes DCTDecode (JPEG) compression. + // Note that compressing the resulting data with DCTDecode again will accumulate loss, so avoid + // multiple compression and decompression cycles. This is mostly useful for retrieving image + // data. QPDF_DLL void setDecodeLevel(qpdf_stream_decode_level_e); - // By default, when both the input and output contents of a stream - // are compressed with Flate, qpdf does not uncompress and - // recompress the stream. Passing true here causes it to do so. - // This can be useful if recompressing all streams with a higher - // compression level, which can be set by calling the static - // method Pl_Flate::setCompressionLevel. + // By default, when both the input and output contents of a stream are compressed with Flate, + // qpdf does not uncompress and recompress the stream. Passing true here causes it to do so. + // This can be useful if recompressing all streams with a higher compression level, which can be + // set by calling the static method Pl_Flate::setCompressionLevel. QPDF_DLL void setRecompressFlate(bool); - // Set value of content stream normalization. The default is - // "false". If true, we attempt to normalize newlines inside of - // content streams. Some constructs such as inline images may - // thwart our efforts. There may be some cases where this can - // damage the content stream. This flag should be used only for - // debugging and experimenting with PDF content streams. Never - // use it for production files. + // Set value of content stream normalization. The default is "false". If true, we attempt to + // normalize newlines inside of content streams. Some constructs such as inline images may + // thwart our efforts. There may be some cases where this can damage the content stream. This + // flag should be used only for debugging and experimenting with PDF content streams. Never use + // it for production files. QPDF_DLL void setContentNormalization(bool); - // Set QDF mode. QDF mode causes special "pretty printing" of - // PDF objects, adds comments for easier perusing of files. - // Resulting PDF files can be edited in a text editor and then run - // through fix-qdf to update cross reference tables and stream - // lengths. + // Set QDF mode. QDF mode causes special "pretty printing" of PDF objects, adds comments for + // easier perusing of files. Resulting PDF files can be edited in a text editor and then run + // through fix-qdf to update cross reference tables and stream lengths. QPDF_DLL void setQDFMode(bool); - // Preserve unreferenced objects. The default behavior is to - // discard any object that is not visited during a traversal of - // the object structure from the trailer. + // Preserve unreferenced objects. The default behavior is to discard any object that is not + // visited during a traversal of the object structure from the trailer. QPDF_DLL void setPreserveUnreferencedObjects(bool); - // Always write a newline before the endstream keyword. This helps - // with PDF/A compliance, though it is not sufficient for it. + // Always write a newline before the endstream keyword. This helps with PDF/A compliance, though + // it is not sufficient for it. QPDF_DLL void setNewlineBeforeEndstream(bool); - // Set the minimum PDF version. If the PDF version of the input - // file (or previously set minimum version) is less than the - // version passed to this method, the PDF version of the output - // file will be set to this value. If the original PDF file's - // version or previously set minimum version is already this - // version or later, the original file's version will be used. - // QPDFWriter automatically sets the minimum version to 1.4 when - // R3 encryption parameters are used, and to 1.5 when object - // streams are used. + // Set the minimum PDF version. If the PDF version of the input file (or previously set minimum + // version) is less than the version passed to this method, the PDF version of the output file + // will be set to this value. If the original PDF file's version or previously set minimum + // version is already this version or later, the original file's version will be used. + // QPDFWriter automatically sets the minimum version to 1.4 when R3 encryption parameters are + // used, and to 1.5 when object streams are used. QPDF_DLL void setMinimumPDFVersion(std::string const&, int extension_level = 0); QPDF_DLL void setMinimumPDFVersion(PDFVersion const&); - // Force the PDF version of the output file to be a given version. - // Use of this function may create PDF files that will not work - // properly with older PDF viewers. When a PDF version is set - // using this function, qpdf will use this version even if the - // file contains features that are not supported in that version - // of PDF. In other words, you should only use this function if - // you are sure the PDF file in question has no features of newer - // versions of PDF or if you are willing to create files that old - // viewers may try to open but not be able to properly interpret. - // If any encryption has been applied to the document either - // explicitly or by preserving the encryption of the source - // document, forcing the PDF version to a value too low to support - // that type of encryption will explicitly disable decryption. - // Additionally, forcing to a version below 1.5 will disable - // object streams. + // Force the PDF version of the output file to be a given version. Use of this function may + // create PDF files that will not work properly with older PDF viewers. When a PDF version is + // set using this function, qpdf will use this version even if the file contains features that + // are not supported in that version of PDF. In other words, you should only use this function + // if you are sure the PDF file in question has no features of newer versions of PDF or if you + // are willing to create files that old viewers may try to open but not be able to properly + // interpret. If any encryption has been applied to the document either explicitly or by + // preserving the encryption of the source document, forcing the PDF version to a value too low + // to support that type of encryption will explicitly disable decryption. Additionally, forcing + // to a version below 1.5 will disable object streams. QPDF_DLL void forcePDFVersion(std::string const&, int extension_level = 0); - // Provide additional text to insert in the PDF file somewhere - // near the beginning of the file. This can be used to add - // comments to the beginning of a PDF file, for example, if those - // comments are to be consumed by some other application. No - // checks are performed to ensure that the text inserted here is - // valid PDF. If you want to insert multiline comments, you will - // need to include \n in the string yourself and start each line - // with %. An extra newline will be appended if one is not - // already present at the end of your text. + // Provide additional text to insert in the PDF file somewhere near the beginning of the file. + // This can be used to add comments to the beginning of a PDF file, for example, if those + // comments are to be consumed by some other application. No checks are performed to ensure + // that the text inserted here is valid PDF. If you want to insert multiline comments, you will + // need to include \n in the string yourself and start each line with %. An extra newline will + // be appended if one is not already present at the end of your text. QPDF_DLL void setExtraHeaderText(std::string const&); - // Causes a deterministic /ID value to be generated. When this is - // set, the current time and output file name are not used as part - // of /ID generation. Instead, a digest of all significant parts - // of the output file's contents is included in the /ID - // calculation. Use of a deterministic /ID can be handy when it is - // desirable for a repeat of the same qpdf operation on the same - // inputs being written to the same outputs with the same - // parameters to generate exactly the same results. This feature - // is incompatible with encrypted files because, for encrypted - // files, the /ID is generated before any part of the file is - // written since it is an input to the encryption process. + // Causes a deterministic /ID value to be generated. When this is set, the current time and + // output file name are not used as part of /ID generation. Instead, a digest of all significant + // parts of the output file's contents is included in the /ID calculation. Use of a + // deterministic /ID can be handy when it is desirable for a repeat of the same qpdf operation + // on the same inputs being written to the same outputs with the same parameters to generate + // exactly the same results. This feature is incompatible with encrypted files because, for + // encrypted files, the /ID is generated before any part of the file is written since it is an + // input to the encryption process. QPDF_DLL void setDeterministicID(bool); - // Cause a static /ID value to be generated. Use only in test - // suites. See also setDeterministicID. + // Cause a static /ID value to be generated. Use only in test suites. See also + // setDeterministicID. QPDF_DLL void setStaticID(bool); - // Use a fixed initialization vector for AES-CBC encryption. This - // is not secure. It should be used only in test suites for - // creating predictable encrypted output. + // Use a fixed initialization vector for AES-CBC encryption. This is not secure. It should be + // used only in test suites for creating predictable encrypted output. QPDF_DLL void setStaticAesIV(bool); - // Suppress inclusion of comments indicating original object IDs - // when writing QDF files. This can also be useful for testing, - // particularly when using comparison of two qdf files to + // Suppress inclusion of comments indicating original object IDs when writing QDF files. This + // can also be useful for testing, particularly when using comparison of two qdf files to // determine whether two PDF files have identical content. QPDF_DLL void setSuppressOriginalObjectIDs(bool); - // Preserve encryption. The default is true unless prefilering, - // content normalization, or qdf mode has been selected in which - // case encryption is never preserved. Encryption is also not + // Preserve encryption. The default is true unless prefilering, content normalization, or qdf + // mode has been selected in which case encryption is never preserved. Encryption is also not // preserved if we explicitly set encryption parameters. QPDF_DLL void setPreserveEncryption(bool); - // Copy encryption parameters from another QPDF object. If you - // want to copy encryption from the object you are writing, call - // setPreserveEncryption(true) instead. + // Copy encryption parameters from another QPDF object. If you want to copy encryption from the + // object you are writing, call setPreserveEncryption(true) instead. QPDF_DLL void copyEncryptionParameters(QPDF&); - // Set up for encrypted output. User and owner password both must - // be specified. Either or both may be the empty string. Note - // that qpdf does not apply any special treatment to the empty - // string, which makes it possible to create encrypted files with - // empty owner passwords and non-empty user passwords or with the - // same password for both user and owner. Some PDF reading - // products don't handle such files very well. Enabling - // encryption disables stream prefiltering and content - // normalization. Note that setting R2 encryption parameters sets - // the PDF version to at least 1.3, setting R3 encryption - // parameters pushes the PDF version number to at least 1.4, - // setting R4 parameters pushes the version to at least 1.5, or if - // AES is used, 1.6, and setting R5 or R6 parameters pushes the - // version to at least 1.7 with extension level 3. + // Set up for encrypted output. User and owner password both must be specified. Either or both + // may be the empty string. Note that qpdf does not apply any special treatment to the empty + // string, which makes it possible to create encrypted files with empty owner passwords and + // non-empty user passwords or with the same password for both user and owner. Some PDF reading + // products don't handle such files very well. Enabling encryption disables stream prefiltering + // and content normalization. Note that setting R2 encryption parameters sets the PDF version + // to at least 1.3, setting R3 encryption parameters pushes the PDF version number to at + // least 1.4, setting R4 parameters pushes the version to at least 1.5, or if AES is used, 1.6, + // and setting R5 or R6 parameters pushes the version to at least 1.7 with extension level 3. // - // Note about Unicode passwords: the PDF specification requires - // passwords to be encoded with PDF Doc encoding for R <= 4 and - // UTF-8 for R >= 5. In all cases, these methods take strings of - // bytes as passwords. It is up to the caller to ensure that - // passwords are properly encoded. The qpdf command-line tool - // tries to do this, as discussed in the manual. If you are doing - // this from your own application, QUtil contains many transcoding - // functions that could be useful to you, most notably - // utf8_to_pdf_doc. + // Note about Unicode passwords: the PDF specification requires passwords to be encoded with PDF + // Doc encoding for R <= 4 and UTF-8 for R >= 5. In all cases, these methods take strings of + // bytes as passwords. It is up to the caller to ensure that passwords are properly encoded. The + // qpdf command-line tool tries to do this, as discussed in the manual. If you are doing this + // from your own application, QUtil contains many transcoding functions that could be useful to + // you, most notably utf8_to_pdf_doc. - // R2 uses RC4, which is a weak cryptographic algorithm. Don't use - // it unless you have to. See "Weak Cryptography" in the manual. - // This encryption format is deprecated in the PDF 2.0 + // R2 uses RC4, which is a weak cryptographic algorithm. Don't use it unless you have to. See + // "Weak Cryptography" in the manual. This encryption format is deprecated in the PDF 2.0 // specification. QPDF_DLL void setR2EncryptionParametersInsecure( @@ -398,9 +332,8 @@ class QPDFWriter bool allow_modify, bool allow_extract, bool allow_annotate); - // R3 uses RC4, which is a weak cryptographic algorithm. Don't use - // it unless you have to. See "Weak Cryptography" in the manual. - // This encryption format is deprecated in the PDF 2.0 + // R3 uses RC4, which is a weak cryptographic algorithm. Don't use it unless you have to. See + // "Weak Cryptography" in the manual. This encryption format is deprecated in the PDF 2.0 // specification. QPDF_DLL void setR3EncryptionParametersInsecure( @@ -413,11 +346,10 @@ class QPDFWriter bool allow_form_filling, bool allow_modify_other, qpdf_r3_print_e print); - // When use_aes=false, this call enables R4 with RC4, which is a - // weak cryptographic algorithm. Even with use_aes=true, the - // overall encryption scheme is weak. Don't use it unless you have - // to. See "Weak Cryptography" in the manual. This encryption - // format is deprecated in the PDF 2.0 specification. + // When use_aes=false, this call enables R4 with RC4, which is a weak cryptographic algorithm. + // Even with use_aes=true, the overall encryption scheme is weak. Don't use it unless you have + // to. See "Weak Cryptography" in the manual. This encryption format is deprecated in the + // PDF 2.0 specification. QPDF_DLL void setR4EncryptionParametersInsecure( char const* user_password, @@ -431,9 +363,8 @@ class QPDFWriter qpdf_r3_print_e print, bool encrypt_metadata, bool use_aes); - // R5 is deprecated. Do not use it for production use. Writing - // R5 is supported by qpdf primarily to generate test files for - // applications that may need to test R5 support. + // R5 is deprecated. Do not use it for production use. Writing R5 is supported by qpdf + // primarily to generate test files for applications that may need to test R5 support. QPDF_DLL void setR5EncryptionParameters( char const* user_password, @@ -446,8 +377,7 @@ class QPDFWriter bool allow_modify_other, qpdf_r3_print_e print, bool encrypt_metadata); - // This is the only password-based encryption format supported by - // the PDF specification. + // This is the only password-based encryption format supported by the PDF specification. QPDF_DLL void setR6EncryptionParameters( char const* user_password, @@ -461,57 +391,49 @@ class QPDFWriter qpdf_r3_print_e print, bool encrypt_metadata_aes); - // Create linearized output. Disables qdf mode, content - // normalization, and stream prefiltering. + // Create linearized output. Disables qdf mode, content normalization, and stream prefiltering. QPDF_DLL void setLinearization(bool); - // For debugging QPDF: provide the name of a file to write pass1 - // of linearization to. The only reason to use this is to debug - // QPDF. To linearize, QPDF writes out the file in two passes. - // Usually the first pass is discarded, but lots of computations - // are made in pass 1. If a linearized file comes out wrong, it - // can be helpful to look at the first pass. + // For debugging QPDF: provide the name of a file to write pass1 of linearization to. The only + // reason to use this is to debug QPDF. To linearize, QPDF writes out the file in two passes. + // Usually the first pass is discarded, but lots of computations are made in pass 1. If a + // linearized file comes out wrong, it can be helpful to look at the first pass. QPDF_DLL void setLinearizationPass1Filename(std::string const&); - // Create PCLm output. This is only useful for clients that know - // how to create PCLm files. If a file is structured exactly as - // PCLm requires, this call will tell QPDFWriter to write the PCLm - // header, create certain unreferenced streams required by the - // standard, and write the objects in the required order. Calling - // this on an ordinary PDF serves no purpose. There is no + // Create PCLm output. This is only useful for clients that know how to create PCLm files. If a + // file is structured exactly as PCLm requires, this call will tell QPDFWriter to write the PCLm + // header, create certain unreferenced streams required by the standard, and write the objects + // in the required order. Calling this on an ordinary PDF serves no purpose. There is no // command-line argument that causes this method to be called. QPDF_DLL void setPCLm(bool); - // If you want to be notified of progress, derive a class from - // ProgressReporter and override the reportProgress method. + // If you want to be notified of progress, derive a class from ProgressReporter and override the + // reportProgress method. QPDF_DLL void registerProgressReporter(std::shared_ptr); - // Return the PDF version that will be written into the header. - // Calling this method does all the preparation for writing, so it - // is an error to call any methods that may cause a change to the - // version. Adding new objects to the original file after calling - // this may also cause problems. It is safe to update existing - // objects or stream contents after calling this method, e.g., to + // Return the PDF version that will be written into the header. Calling this method does all the + // preparation for writing, so it is an error to call any methods that may cause a change to the + // version. Adding new objects to the original file after calling this may also cause problems. + // It is safe to update existing objects or stream contents after calling this method, e.g., to // include the final version number in metadata. QPDF_DLL std::string getFinalVersion(); - // Write the final file. There is no expectation of being able to - // call write() more than once. + // Write the final file. There is no expectation of being able to call write() more than once. QPDF_DLL void write(); - // Return renumbered ObjGen that was written into the final file. - // This method can be used after calling write(). + // Return renumbered ObjGen that was written into the final file. This method can be used after + // calling write(). QPDF_DLL QPDFObjGen getRenumberedObjGen(QPDFObjGen); - // Return XRef entry that was written into the final file. - // This method can be used after calling write(). + // Return XRef entry that was written into the final file. This method can be used after calling + // write(). QPDF_DLL std::map getWrittenXRefTable(); @@ -525,15 +447,12 @@ class QPDFWriter enum trailer_e { t_normal, t_lin_first, t_lin_second }; - // An reference to a PipelinePopper instance is passed into - // activatePipelineStack. When the PipelinePopper goes out of - // scope, the pipeline stack is popped. PipelinePopper's - // destructor calls finish on the current pipeline and pops the - // pipeline stack until the top of stack is a previous active top - // of stack, and restores the pipeline to that point. It deletes - // any pipelines that it pops. If the bp argument is non-null and - // any of the stack items are of type Pl_Buffer, the buffer is - // retrieved. + // An reference to a PipelinePopper instance is passed into activatePipelineStack. When the + // PipelinePopper goes out of scope, the pipeline stack is popped. PipelinePopper's destructor + // calls finish on the current pipeline and pops the pipeline stack until the top of stack is a + // previous active top of stack, and restores the pipeline to that point. It deletes any + // pipelines that it pops. If the bp argument is non-null and any of the stack items are of type + // Pl_Buffer, the buffer is retrieved. class PipelinePopper { friend class QPDFWriter; @@ -672,10 +591,9 @@ class QPDFWriter int linearization_pass); size_t calculateXrefStreamPadding(qpdf_offset_t xref_bytes); - // When filtering subsections, push additional pipelines to the - // stack. When ready to switch, activate the pipeline stack. When - // the passed in PipelinePopper goes out of scope, the stack is - // popped. + // When filtering subsections, push additional pipelines to the stack. When ready to switch, + // activate the pipeline stack. When the passed in PipelinePopper goes out of scope, the stack + // is popped. Pipeline* pushPipeline(Pipeline*); void activatePipelineStack(PipelinePopper&); void initializePipelineStack(Pipeline*); @@ -779,9 +697,8 @@ class QPDFWriter int next_progress_report{0}; }; - // Keep all member variables inside the Members object, which we - // dynamically allocate. This makes it possible to add new private - // members without breaking binary compatibility. + // Keep all member variables inside the Members object, which we dynamically allocate. This + // makes it possible to add new private members without breaking binary compatibility. std::shared_ptr m; }; diff --git a/include/qpdf/QPDFXRefEntry.hh b/include/qpdf/QPDFXRefEntry.hh index afdca768..0593c02d 100644 --- a/include/qpdf/QPDFXRefEntry.hh +++ b/include/qpdf/QPDFXRefEntry.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QPDFXREFENTRY_HH #define QPDFXREFENTRY_HH @@ -28,8 +25,7 @@ class QPDFXRefEntry { public: - // Type constants are from the PDF spec section - // "Cross-Reference Streams": + // Type constants are from the PDF spec section "Cross-Reference Streams": // 0 = free entry; not used // 1 = "uncompressed"; field 1 = offset // 2 = "compressed"; field 1 = object stream number, field 2 = index @@ -65,8 +61,8 @@ class QPDFXRefEntry int getObjStreamIndex() const; // only for type 2 private: - // This class does not use the Members pattern to avoid a memory - // allocation for every one of these. A lot of these get created. + // This class does not use the Members pattern to avoid a memory allocation for every one of + // these. A lot of these get created. int type{0}; qpdf_offset_t field1{0}; int field2{0}; diff --git a/include/qpdf/QTC.hh b/include/qpdf/QTC.hh index 46d65607..030d4d97 100644 --- a/include/qpdf/QTC.hh +++ b/include/qpdf/QTC.hh @@ -2,33 +2,28 @@ // // 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 +// 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. +// 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. +// 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 QTC_HH #define QTC_HH #include -// Defining QPDF_DISABLE_QTC will effectively compile out any QTC::TC -// calls in any code that includes this file, but QTC will still be -// built into the library. That way, it is possible to build and -// package qpdf with QPDF_DISABLE_QTC while still making QTC::TC -// available to end users. +// Defining QPDF_DISABLE_QTC will effectively compile out any QTC::TC calls in any code that +// includes this file, but QTC will still be built into the library. That way, it is possible to +// build and package qpdf with QPDF_DISABLE_QTC while still making QTC::TC available to end users. namespace QTC { diff --git a/include/qpdf/QUtil.hh b/include/qpdf/QUtil.hh index 85e7f907..47ecf6bf 100644 --- a/include/qpdf/QUtil.hh +++ b/include/qpdf/QUtil.hh @@ -2,22 +2,19 @@ // // 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 +// 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. +// 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. +// 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 QUTIL_HH #define QUTIL_HH @@ -40,8 +37,7 @@ class Pipeline; namespace QUtil { - // This is a collection of useful utility functions that don't - // really go anywhere else. + // This is a collection of useful utility functions that don't really go anywhere else. QPDF_DLL std::string int_to_string(long long, int length = 0); QPDF_DLL @@ -53,8 +49,7 @@ namespace QUtil QPDF_DLL std::string double_to_string(double, int decimal_places = 0, bool trim_trailing_zeroes = true); - // These string to number methods throw std::runtime_error on - // underflow/overflow. + // These string to number methods throw std::runtime_error on underflow/overflow. QPDF_DLL long long string_to_ll(char const* str); QPDF_DLL @@ -64,63 +59,53 @@ namespace QUtil QPDF_DLL unsigned int string_to_uint(char const* str); - // Returns true if this exactly represents a long long. The - // determination is made by converting the string to a long long, - // then converting the result back to a string, and then comparing + // Returns true if this exactly represents a long long. The determination is made by converting + // the string to a long long, then converting the result back to a string, and then comparing // that result with the original string. QPDF_DLL bool is_long_long(char const* str); - // Pipeline's write method wants unsigned char*, but we often have - // some other type of string. These methods do combinations of - // const_cast and reinterpret_cast to give us an unsigned char*. - // They should only be used when it is known that it is safe. - // None of the pipelines in qpdf modify the data passed to them, - // so within qpdf, it should always be safe. + // Pipeline's write method wants unsigned char*, but we often have some other type of string. + // These methods do combinations of const_cast and reinterpret_cast to give us an unsigned + // char*. They should only be used when it is known that it is safe. None of the pipelines in + // qpdf modify the data passed to them, so within qpdf, it should always be safe. QPDF_DLL unsigned char* unsigned_char_pointer(std::string const& str); QPDF_DLL unsigned char* unsigned_char_pointer(char const* str); - // Throw QPDFSystemError, which is derived from - // std::runtime_error, with a string formed by appending to - // "description: " the standard string corresponding to the - // current value of errno. You can retrieve the value of errno by - // calling getErrno() on the QPDFSystemError. Prior to qpdf 8.2.0, - // this method threw system::runtime_error directly, but since - // QPDFSystemError is derived from system::runtime_error, old code - // that specifically catches std::runtime_error will still work. + // Throw QPDFSystemError, which is derived from std::runtime_error, with a string formed by + // appending to "description: " the standard string corresponding to the current value of errno. + // You can retrieve the value of errno by calling getErrno() on the QPDFSystemError. Prior to + // qpdf 8.2.0, this method threw system::runtime_error directly, but since QPDFSystemError is + // derived from system::runtime_error, old code that specifically catches std::runtime_error + // will still work. QPDF_DLL void throw_system_error(std::string const& description); - // The status argument is assumed to be the return value of a - // standard library call that sets errno when it fails. If status - // is -1, convert the current value of errno to a - // std::runtime_error that includes the standard error string. - // Otherwise, return status. + // The status argument is assumed to be the return value of a standard library call that sets + // errno when it fails. If status is -1, convert the current value of errno to a + // std::runtime_error that includes the standard error string. Otherwise, return status. QPDF_DLL int os_wrapper(std::string const& description, int status); - // If the open fails, throws std::runtime_error. Otherwise, the - // FILE* is returned. The filename should be UTF-8 encoded, even - // on Windows. It will be converted as needed on Windows. + // If the open fails, throws std::runtime_error. Otherwise, the FILE* is returned. The filename + // should be UTF-8 encoded, even on Windows. It will be converted as needed on Windows. QPDF_DLL FILE* safe_fopen(char const* filename, char const* mode); - // The FILE* argument is assumed to be the return of fopen. If - // null, throw std::runtime_error. Otherwise, return the FILE* - // argument. + // The FILE* argument is assumed to be the return of fopen. If null, throw std::runtime_error. + // Otherwise, return the FILE* argument. QPDF_DLL FILE* fopen_wrapper(std::string const&, FILE*); - // This is a little class to help with automatic closing files. - // You can do something like + // This is a little class to help with automatic closing files. You can do something like // // QUtil::FileCloser fc(QUtil::safe_fopen(filename, "rb")); // - // and then use fc.f to the file. Be sure to actually declare a - // variable of type FileCloser. Using it as a temporary won't work - // because it will close the file as soon as it goes out of scope. + // and then use fc.f to the file. Be sure to actually declare a variable of type FileCloser. + // Using it as a temporary won't work because it will close the file as soon as it goes out of + // scope. class FileCloser { public: @@ -160,28 +145,24 @@ namespace QUtil QPDF_DLL void rename_file(char const* oldname, char const* newname); - // Write the contents of filename as a binary file to the - // pipeline. + // Write the contents of filename as a binary file to the pipeline. QPDF_DLL void pipe_file(char const* filename, Pipeline* p); - // Return a function that will send the contents of the given file - // through the given pipeline as binary data. + // Return a function that will send the contents of the given file through the given pipeline as + // binary data. QPDF_DLL std::function file_provider(std::string const& filename); - // Return the last path element. On Windows, either / or \ are - // path separators. Otherwise, only / is a path separator. Strip - // any trailing path separators. Then, if any path separators - // remain, return everything after the last path separator. - // Otherwise, return the whole string. As a special case, if a - // string consists entirely of path separators, the first - // character is returned. + // Return the last path element. On Windows, either / or \ are path separators. Otherwise, only + // / is a path separator. Strip any trailing path separators. Then, if any path separators + // remain, return everything after the last path separator. Otherwise, return the whole string. + // As a special case, if a string consists entirely of path separators, the first character is + // returned. QPDF_DLL std::string path_basename(std::string const& filename); - // Returns a dynamically allocated copy of a string that the - // caller has to delete with delete[]. + // Returns a dynamically allocated copy of a string that the caller has to delete with delete[]. QPDF_DLL char* copy_string(std::string const&); @@ -193,8 +174,7 @@ namespace QUtil QPDF_DLL std::unique_ptr make_unique_cstr(std::string const&); - // Create a shared pointer to an array. From c++20, - // std::make_shared(n) does this. + // Create a shared pointer to an array. From c++20, std::make_shared(n) does this. template std::shared_ptr make_shared_array(size_t n) @@ -202,27 +182,24 @@ namespace QUtil return std::shared_ptr(new T[n], std::default_delete()); } - // Returns lower-case hex-encoded version of the string, treating - // each character in the input string as unsigned. The output - // string will be twice as long as the input string. + // Returns lower-case hex-encoded version of the string, treating each character in the input + // string as unsigned. The output string will be twice as long as the input string. QPDF_DLL std::string hex_encode(std::string const&); - // Returns lower-case hex-encoded version of the char including a leading - // "#". + // Returns lower-case hex-encoded version of the char including a leading "#". QPDF_DLL inline std::string hex_encode_char(char); - // Returns a string that is the result of decoding the input - // string. The input string may consist of mixed case hexadecimal - // digits. Any characters that are not hexadecimal digits will be - // silently ignored. If there are an odd number of hexadecimal - // digits, a trailing 0 will be assumed. + // Returns a string that is the result of decoding the input string. The input string may + // consist of mixed case hexadecimal digits. Any characters that are not hexadecimal digits will + // be silently ignored. If there are an odd number of hexadecimal digits, a trailing 0 will be + // assumed. QPDF_DLL std::string hex_decode(std::string const&); - // Decode a single hex digit into a char in the range 0 <= char < 16. Return - // a char >= 16 if digit is not a valid hex digit. + // Decode a single hex digit into a char in the range 0 <= char < 16. Return a char >= 16 if + // digit is not a valid hex digit. QPDF_DLL inline constexpr char hex_decode_char(char digit) noexcept; @@ -239,17 +216,15 @@ namespace QUtil QPDF_DLL char* getWhoami(char* argv0); - // Get the value of an environment variable in a portable fashion. - // Returns true iff the variable is defined. If `value' is - // non-null, initializes it with the value of the variable. + // Get the value of an environment variable in a portable fashion. Returns true iff the variable + // is defined. If `value' is non-null, initializes it with the value of the variable. QPDF_DLL bool get_env(std::string const& var, std::string* value = nullptr); QPDF_DLL time_t get_current_time(); - // Portable structure representing a point in time with second - // granularity and time zone offset + // Portable structure representing a point in time with second granularity and time zone offset struct QPDFTime { QPDFTime() = default; @@ -277,12 +252,11 @@ namespace QUtil QPDF_DLL QPDFTime get_current_qpdf_time(); - // Convert a QPDFTime structure to a PDF timestamp string, which - // is "D:yyyymmddhhmmss" where is either "Z" for UTC or - // "-hh'mm'" or "+hh'mm'" for timezone offset. may also be - // omitted. Examples: "D:20210207161528-05'00'", - // "D:20210207211528Z", "D:20210207211528". See - // get_current_qpdf_time and the QPDFTime structure above. + // Convert a QPDFTime structure to a PDF timestamp string, which is "D:yyyymmddhhmmss" where + // is either "Z" for UTC or "-hh'mm'" or "+hh'mm'" for timezone offset. may also be + // omitted. + // Examples: "D:20210207161528-05'00'", "D:20210207211528Z", "D:20210207211528". + // See get_current_qpdf_time and the QPDFTime structure above. QPDF_DLL std::string qpdf_time_to_pdf_time(QPDFTime const&); @@ -290,63 +264,53 @@ namespace QUtil QPDF_DLL std::string qpdf_time_to_iso8601(QPDFTime const&); - // Convert a PDF timestamp string to a QPDFTime. If syntactically - // valid, return true and fill in qtm. If not valid, return false, - // and do not modify qtm. If qtm is null, just check the validity - // of the string. + // Convert a PDF timestamp string to a QPDFTime. If syntactically valid, return true and fill in + // qtm. If not valid, return false, and do not modify qtm. If qtm is null, just check the + // validity of the string. QPDF_DLL bool pdf_time_to_qpdf_time(std::string const&, QPDFTime* qtm = nullptr); - // Convert PDF timestamp to a second-granularity ISO-8601 - // timestamp. If syntactically valid, return true and initialize - // iso8601. Otherwise, return false. + // Convert PDF timestamp to a second-granularity ISO-8601 timestamp. If syntactically valid, + // return true and initialize iso8601. Otherwise, return false. bool pdf_time_to_iso8601(std::string const& pdf_time, std::string& iso8601); - // Return a string containing the byte representation of the UTF-8 - // encoding for the unicode value passed in. + // Return a string containing the byte representation of the UTF-8 encoding for the unicode + // value passed in. QPDF_DLL std::string toUTF8(unsigned long uval); - // Return a string containing the byte representation of the - // UTF-16 big-endian encoding for the unicode value passed in. - // Unrepresentable code points are converted to U+FFFD. + // Return a string containing the byte representation of the UTF-16 big-endian encoding for the + // unicode value passed in. Unrepresentable code points are converted to U+FFFD. QPDF_DLL std::string toUTF16(unsigned long uval); - // If utf8_val.at(pos) points to the beginning of a valid - // UTF-8-encoded character, return the codepoint of the character - // and set error to false. Otherwise, return 0xfffd and set error - // to true. In all cases, pos is advanced to the next position - // that may begin a valid character. When the string has been - // consumed, pos will be set to the string length. It is an error - // to pass a value of pos that is greater than or equal to the - // length of the string. + // If utf8_val.at(pos) points to the beginning of a valid UTF-8-encoded character, return the + // codepoint of the character and set error to false. Otherwise, return 0xfffd and set error to + // true. In all cases, pos is advanced to the next position that may begin a valid character. + // When the string has been consumed, pos will be set to the string length. It is an error to + // pass a value of pos that is greater than or equal to the length of the string. QPDF_DLL unsigned long get_next_utf8_codepoint(std::string const& utf8_val, size_t& pos, bool& error); - // Test whether this is a UTF-16 string. This is indicated by - // first two bytes being 0xFE 0xFF (big-endian) or 0xFF 0xFE - // (little-endian), each of which is the encoding of U+FEFF, the - // Unicode marker. Starting in qpdf 10.6.2, this detects - // little-endian as well as big-endian. Even though the PDF spec - // doesn't allow little-endian, most readers seem to accept it. + // Test whether this is a UTF-16 string. This is indicated by first two bytes being 0xFE 0xFF + // (big-endian) or 0xFF 0xFE (little-endian), each of which is the encoding of U+FEFF, the + // Unicode marker. Starting in qpdf 10.6.2, this detects little-endian as well as big-endian. + // Even though the PDF spec doesn't allow little-endian, most readers seem to accept it. QPDF_DLL bool is_utf16(std::string const&); - // Test whether this is an explicit UTF-8 string as allowed by the - // PDF 2.0 spec. This is indicated by first three bytes being 0xEF - // 0xBB 0xBF, which is the UTF-8 encoding of U+FEFF. + // Test whether this is an explicit UTF-8 string as allowed by the PDF 2.0 spec. This is + // indicated by first three bytes being 0xEF 0xBB 0xBF, which is the UTF-8 encoding of U+FEFF. QPDF_DLL bool is_explicit_utf8(std::string const&); - // Convert a UTF-8 encoded string to UTF-16 big-endian. - // Unrepresentable code points are converted to U+FFFD. + // Convert a UTF-8 encoded string to UTF-16 big-endian. Unrepresentable code points are + // converted to U+FFFD. QPDF_DLL std::string utf8_to_utf16(std::string const& utf8); - // Convert a UTF-8 encoded string to the specified single-byte - // encoding system by replacing all unsupported characters with - // the given unknown_char. + // Convert a UTF-8 encoded string to the specified single-byte encoding system by replacing all + // unsupported characters with the given unknown_char. QPDF_DLL std::string utf8_to_ascii(std::string const& utf8, char unknown_char = '?'); QPDF_DLL @@ -356,9 +320,8 @@ namespace QUtil QPDF_DLL std::string utf8_to_pdf_doc(std::string const& utf8, char unknown_char = '?'); - // These versions return true if the conversion was successful and - // false if any unrepresentable characters were found and had to - // be substituted with the unknown character. + // These versions return true if the conversion was successful and false if any unrepresentable + // characters were found and had to be substituted with the unknown character. QPDF_DLL bool utf8_to_ascii(std::string const& utf8, std::string& ascii, char unknown_char = '?'); QPDF_DLL @@ -373,9 +336,8 @@ namespace QUtil QPDF_DLL std::string utf16_to_utf8(std::string const& utf16); - // Convert from the specified single-byte encoding system to - // UTF-8. There is no ascii_to_utf8 because all ASCII strings are - // already valid UTF-8. + // Convert from the specified single-byte encoding system to UTF-8. There is no ascii_to_utf8 + // because all ASCII strings are already valid UTF-8. QPDF_DLL std::string win_ansi_to_utf8(std::string const& win); QPDF_DLL @@ -383,39 +345,33 @@ namespace QUtil QPDF_DLL std::string pdf_doc_to_utf8(std::string const& pdfdoc); - // Analyze a string for encoding. We can't tell the difference - // between any single-byte encodings, and we can't tell for sure - // whether a string that happens to be valid UTF-8 isn't a - // different encoding, but we can at least tell a few things to - // help us guess. If there are no characters with the high bit - // set, has_8bit_chars is false, and the other values are also - // false, even though ASCII strings are valid UTF-8. is_valid_utf8 - // means that the string is non-trivially valid UTF-8. Although - // the PDF spec requires UTF-16 to be UTF-16BE, qpdf (and just - // about everything else) accepts UTF-16LE (as of 10.6.2). + // Analyze a string for encoding. We can't tell the difference between any single-byte + // encodings, and we can't tell for sure whether a string that happens to be valid UTF-8 isn't a + // different encoding, but we can at least tell a few things to help us guess. If there are no + // characters with the high bit set, has_8bit_chars is false, and the other values are also + // false, even though ASCII strings are valid UTF-8. is_valid_utf8 means that the string is + // non-trivially valid UTF-8. Although the PDF spec requires UTF-16 to be UTF-16BE, qpdf (and + // just about everything else) accepts UTF-16LE (as of 10.6.2). QPDF_DLL void analyze_encoding( std::string const& str, bool& has_8bit_chars, bool& is_valid_utf8, bool& is_utf16); - // Try to compensate for previously incorrectly encoded strings. - // We want to compensate for the following errors: + // Try to compensate for previously incorrectly encoded strings. We want to compensate for the + // following errors: // - // * The string was supposed to be UTF-8 but was one of the - // single-byte encodings - // * The string was supposed to be PDF Doc but was either UTF-8 or - // one of the other single-byte encodings + // * The string was supposed to be UTF-8 but was one of the single-byte encodings + // * The string was supposed to be PDF Doc but was either UTF-8 or one of the other single-byte + // encodings // - // The returned vector always contains the original string first, - // and then it contains what the correct string would be in the - // event that the original string was the result of any of the + // The returned vector always contains the original string first, and then it contains what the + // correct string would be in the event that the original string was the result of any of the // above errors. // - // This method is useful for attempting to recover a password that - // may have been previously incorrectly encoded. For example, the - // password was supposed to be UTF-8 but the previous application - // used a password encoded in WinAnsi, or if the previous password - // was supposed to be PDFDoc but was actually given as UTF-8 or - // WinAnsi, this method would find the correct password. + // This method is useful for attempting to recover a password that may have been previously + // incorrectly encoded. For example, the password was supposed to be UTF-8 but the previous + // application used a password encoded in WinAnsi, or if the previous password was supposed to + // be PDFDoc but was actually given as UTF-8 or WinAnsi, this method would find the correct + // password. QPDF_DLL std::vector possible_repaired_encodings(std::string); @@ -427,30 +383,25 @@ namespace QUtil QPDF_DLL void initializeWithRandomBytes(unsigned char* data, size_t len); - // Supply a random data provider. Starting in qpdf 10.0.0, qpdf - // uses the crypto provider as its source of random numbers. If - // you are using the native crypto provider, then qpdf will either - // use the operating system's secure random number source or, only - // if enabled at build time, an insecure random source from - // stdlib. The caller is responsible for managing the memory for - // the RandomDataProvider. This method modifies a static variable. - // If you are providing your own random data provider, you should - // call this at the beginning of your program before creating any - // QPDF objects. Passing a null to this method will reset the - // library back to its default random data provider. + // Supply a random data provider. Starting in qpdf 10.0.0, qpdf uses the crypto provider as its + // source of random numbers. If you are using the native crypto provider, then qpdf will either + // use the operating system's secure random number source or, only if enabled at build time, an + // insecure random source from stdlib. The caller is responsible for managing the memory for the + // RandomDataProvider. This method modifies a static variable. If you are providing your own + // random data provider, you should call this at the beginning of your program before creating + // any QPDF objects. Passing a null to this method will reset the library back to its default + // random data provider. QPDF_DLL void setRandomDataProvider(RandomDataProvider*); - // This returns the random data provider that would be used the - // next time qpdf needs random data. It will never return null. - // If no random data provider has been provided and the library - // was not compiled with any random data provider available, an - // exception will be thrown. + // This returns the random data provider that would be used the next time qpdf needs random + // data. It will never return null. If no random data provider has been provided and the + // library was not compiled with any random data provider available, an exception will be + // thrown. QPDF_DLL RandomDataProvider* getRandomDataProvider(); - // Filename is UTF-8 encoded, even on Windows, as described in the - // comments for safe_fopen. + // Filename is UTF-8 encoded, even on Windows, as described in the comments for safe_fopen. QPDF_DLL std::list read_lines_from_file(char const* filename, bool preserve_eol = false); QPDF_DLL @@ -471,15 +422,13 @@ namespace QUtil QPDF_DLL std::string read_file_into_string(FILE* f, std::string_view filename = ""); - // This used to be called strcasecmp, but that is a macro on some - // platforms, so we have to give it a name that is not likely to - // be a macro anywhere. + // This used to be called strcasecmp, but that is a macro on some platforms, so we have to give + // it a name that is not likely to be a macro anywhere. QPDF_DLL int str_compare_nocase(char const*, char const*); - // These routines help the tokenizer recognize certain character - // classes without using ctype, which we avoid because of locale - // considerations. + // These routines help the tokenizer recognize certain character classes without using ctype, + // which we avoid because of locale considerations. QPDF_DLL inline bool is_hex_digit(char); @@ -492,21 +441,19 @@ namespace QUtil QPDF_DLL inline bool is_number(char const*); - // This method parses the numeric range syntax used by the qpdf - // command-line tool. May throw std::runtime_error. + // This method parses the numeric range syntax used by the qpdf command-line tool. May throw + // std::runtime_error. QPDF_DLL std::vector parse_numrange(char const* range, int max); #ifndef QPDF_NO_WCHAR_T - // If you are building qpdf on a stripped down system that doesn't - // have wchar_t, such as may be the case in some embedded - // environments, you may define QPDF_NO_WCHAR_T in your build. - // This symbol is never defined automatically. Search for wchar_t - // in qpdf's top-level README.md file for details. + // If you are building qpdf on a stripped down system that doesn't have wchar_t, such as may be + // the case in some embedded environments, you may define QPDF_NO_WCHAR_T in your build. This + // symbol is never defined automatically. Search for wchar_t in qpdf's top-level README.md file + // for details. - // Take an argv array consisting of wchar_t, as when wmain is - // invoked, convert all UTF-16 encoded strings to UTF-8, and call - // another main. + // Take an argv array consisting of wchar_t, as when wmain is invoked, convert all UTF-16 + // encoded strings to UTF-8, and call another main. QPDF_DLL int call_main_from_wmain(int argc, wchar_t* argv[], std::function realmain); QPDF_DLL @@ -516,13 +463,10 @@ namespace QUtil std::function realmain); #endif // QPDF_NO_WCHAR_T - // Try to return the maximum amount of memory allocated by the - // current process and its threads. Return 0 if unable to - // determine. This is Linux-specific and not implemented to be - // completely reliable. It is used during development for - // performance testing to detect changes that may significantly - // change memory usage. It is not recommended for use for other - // purposes. + // Try to return the maximum amount of memory allocated by the current process and its threads. + // Return 0 if unable to determine. This is Linux-specific and not implemented to be completely + // reliable. It is used during development for performance testing to detect changes that may + // significantly change memory usage. It is not recommended for use for other purposes. QPDF_DLL size_t get_max_memory_usage(); }; // namespace QUtil diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h index 4e258e9a..e3639a43 100644 --- a/include/qpdf/qpdf-c.h +++ b/include/qpdf/qpdf-c.h @@ -2,138 +2,113 @@ * * 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 + * 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. + * 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. + * 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 QPDF_C_H #define QPDF_C_H /* - * This file defines a basic "C" API for qpdf. It provides access to - * a subset of the QPDF library's capabilities to make them accessible - * to callers who can't handle calling C++ functions or working with - * C++ classes. This may be especially useful to Windows users who - * are accessing the qpdf DLL directly or to other people programming - * in non-C/C++ languages that can call C code but not C++ code. + * This file defines a basic "C" API for qpdf. It provides access to a subset of the QPDF library's + * capabilities to make them accessible to callers who can't handle calling C++ functions or working + * with C++ classes. This may be especially useful to Windows users who are accessing the qpdf DLL + * directly or to other people programming in non-C/C++ languages that can call C code but not C++ + * code. * * There are several things to keep in mind when using the C API. * - * Error handling is tricky because the underlying C++ API uses - * exception handling. See "ERROR HANDLING" below for a detailed - * explanation. + * Error handling is tricky because the underlying C++ API uses exception handling. See "ERROR + * HANDLING" below for a detailed explanation. * - * The C API is not as rich as the C++ API. For any operations - * that involve actually manipulating PDF objects, you must use - * the C++ API. The C API is primarily useful for doing basic - * transformations on PDF files similar to what you might do with - * the qpdf command-line tool. + * The C API is not as rich as the C++ API. For any operations that involve actually + * manipulating PDF objects, you must use the C++ API. The C API is primarily useful for doing + * basic transformations on PDF files similar to what you might do with the qpdf command-line + * tool. * - * These functions store their state in a qpdf_data object. - * Individual instances of qpdf_data are not thread-safe: although - * you may access different qpdf_data objects from different - * threads, you may not access one qpdf_data simultaneously from - * multiple threads. + * These functions store their state in a qpdf_data object. Individual instances of qpdf_data + * are not thread-safe: although you may access different qpdf_data objects from different + * threads, you may not access one qpdf_data simultaneously from multiple threads. * - * All dynamic memory, except for that of the qpdf_data object - * itself, is managed by the library unless otherwise noted. You - * must create a qpdf_data object using qpdf_init and free it - * using qpdf_cleanup. + * All dynamic memory, except for that of the qpdf_data object itself, is managed by the library + * unless otherwise noted. You must create a qpdf_data object using qpdf_init and free it using + * qpdf_cleanup. * - * Many functions return char*. In all cases, the char* values - * returned are pointers to data inside the qpdf_data object. As - * such, they are always freed by qpdf_cleanup. In most cases, - * strings returned by functions here may be invalidated by - * subsequent function calls, sometimes even to different - * functions. If you want a string to last past the next qpdf call - * or after a call to qpdf_cleanup, you should make a copy of it. + * Many functions return char*. In all cases, the char* values returned are pointers to data + * inside the qpdf_data object. As such, they are always freed by qpdf_cleanup. In most cases, + * strings returned by functions here may be invalidated by subsequent function calls, sometimes + * even to different functions. If you want a string to last past the next qpdf call or after a + * call to qpdf_cleanup, you should make a copy of it. * - * Since it is possible for a PDF string to contain null - * characters, a function that returns data originating from a PDF - * string may also contain null characters. To handle that case, - * you call qpdf_get_last_string_length() to get the length of - * whatever string was just returned. See STRING FUNCTIONS below. + * Since it is possible for a PDF string to contain null characters, a function that returns + * data originating from a PDF string may also contain null characters. To handle that case, you + * call qpdf_get_last_string_length() to get the length of whatever string was just returned. + * See STRING FUNCTIONS below. * - * Most functions defined here have obvious counterparts that are - * methods to either QPDF or QPDFWriter. Please see comments in - * QPDF.hh and QPDFWriter.hh for details on their use. In order - * to avoid duplication of information, comments here focus - * primarily on differences between the C and C++ API. + * Most functions defined here have obvious counterparts that are methods to either QPDF or + * QPDFWriter. Please see comments in QPDF.hh and QPDFWriter.hh for details on their use. In + * order to avoid duplication of information, comments here focus primarily on differences + * between the C and C++ API. */ /* ERROR HANDLING -- changed in qpdf 10.5 */ -/* SUMMARY: The only way to know whether a function that does not - * return an error code has encountered an error is to call - * qpdf_has_error after each function. You can do this even for - * functions that do return error codes. You can also call - * qpdf_silence_errors to prevent qpdf from writing these errors to - * stderr. +/* SUMMARY: The only way to know whether a function that does not return an error code has + * encountered an error is to call qpdf_has_error after each function. You can do this even for + * functions that do return error codes. You can also call qpdf_silence_errors to prevent qpdf from + * writing these errors to stderr. * * DETAILS: * - * The data type underlying qpdf_data maintains a list of warnings and - * a single error. To retrieve warnings, call qpdf_next_warning while - * qpdf_more_warnings is true. To retrieve the error, call + * The data type underlying qpdf_data maintains a list of warnings and a single error. To retrieve + * warnings, call qpdf_next_warning while qpdf_more_warnings is true. To retrieve the error, call * qpdf_get_error when qpdf_has_error is true. * * There are several things that are important to understand. * - * Some functions return an error code. The value of the error code is - * made up of a bitwise-OR of QPDF_WARNINGS and QPDF_ERRORS. The - * QPDF_ERRORS bit is set if there was an error during the *most - * recent call* to the API. The QPDF_WARNINGS bit is set if there are - * any warnings that have not yet been retrieved by calling - * qpdf_more_warnings. It is possible for both its or neither bit to - * be set. + * Some functions return an error code. The value of the error code is made up of a bitwise-OR of + * QPDF_WARNINGS and QPDF_ERRORS. The QPDF_ERRORS bit is set if there was an error during the *most + * recent call* to the API. The QPDF_WARNINGS bit is set if there are any warnings that have not yet + * been retrieved by calling qpdf_more_warnings. It is possible for both its or neither bit to be + * set. * - * The expected mode of operation is to go through a series of - * operations, checking for errors after each call, but only checking - * for warnings at the end. This is similar to how it works in the C++ - * API where warnings are handled in exactly this way but errors - * result in exceptions being thrown. However, in both the C and C++ - * API, it is possible to check for and handle warnings as they arise. + * The expected mode of operation is to go through a series of operations, checking for errors after + * each call, but only checking for warnings at the end. This is similar to how it works in the C++ + * API where warnings are handled in exactly this way but errors result in exceptions being thrown. + * However, in both the C and C++ API, it is possible to check for and handle warnings as they + * arise. * - * Some functions return values (or void) rather than an error code. - * This is especially true with the object handling functions. Those - * functions can still generate errors. To handle errors in those - * cases, you should explicitly call qpdf_has_error(). Note that, if - * you want to avoid the inconsistencies in the interface, you can - * always check for error conditions in this way rather than looking - * at status return codes. + * Some functions return values (or void) rather than an error code. This is especially true with + * the object handling functions. Those functions can still generate errors. To handle errors in + * those cases, you should explicitly call qpdf_has_error(). Note that, if you want to avoid the + * inconsistencies in the interface, you can always check for error conditions in this way rather + * than looking at status return codes. * - * Prior to qpdf 10.5, if one of the functions that does not return an - * error code encountered an exception, it would cause the entire - * program to crash. Starting in qpdf 10.5, the default response to an - * error condition in these situations is to print the error to - * standard error, issue exactly one warning indicating that such an - * error occurred, and return a sensible fallback value (0 for - * numbers, QPDF_FALSE for booleans, "" for strings, or a null or - * uninitialized object handle). This is better than the old behavior - * but still undesirable as the best option is to explicitly check for - * error conditions. + * Prior to qpdf 10.5, if one of the functions that does not return an error code encountered an + * exception, it would cause the entire program to crash. Starting in qpdf 10.5, the default + * response to an error condition in these situations is to print the error to standard error, issue + * exactly one warning indicating that such an error occurred, and return a sensible fallback value + * (0 for numbers, QPDF_FALSE for booleans, "" for strings, or a null or uninitialized object + * handle). This is better than the old behavior but still undesirable as the best option is to + * explicitly check for error conditions. * - * To prevent qpdf from writing error messages to stderr in this way, - * you can call qpdf_silence_errors(). This signals to the qpdf - * library that you intend to check the error codes yourself. + * To prevent qpdf from writing error messages to stderr in this way, you can call + * qpdf_silence_errors(). This signals to the qpdf library that you intend to check the error codes + * yourself. * - * If you encounter a situation where an exception from the C++ code - * is not properly converted to an error as described above, it is a - * bug in qpdf, which should be reported at + * If you encounter a situation where an exception from the C++ code is not properly converted to an + * error as described above, it is a bug in qpdf, which should be reported at * https://github.com/qpdf/qpdf/issues/new. */ @@ -150,9 +125,8 @@ extern "C" { typedef struct _qpdf_data* qpdf_data; typedef struct _qpdf_error* qpdf_error; - /* Many functions return an integer error code. Codes are defined - * below. See comments at the top of the file for details. Note - * that the values below can be logically orred together. + /* Many functions return an integer error code. Codes are defined below. See comments at the + * top of the file for details. Note that the values below can be logically orred together. */ typedef int QPDF_ERROR_CODE; #define QPDF_SUCCESS 0 @@ -163,76 +137,68 @@ extern "C" { #define QPDF_TRUE 1 #define QPDF_FALSE 0 - /* From qpdf 10.5: call this method to signal to the library that - * you are explicitly handling errors from functions that don't - * return error codes. Otherwise, the library will print these - * error conditions to stderr and issue a warning. Prior to 10.5, - * the program would have crashed from an unhandled exception. + /* From qpdf 10.5: call this method to signal to the library that you are explicitly handling + * errors from functions that don't return error codes. Otherwise, the library will print these + * error conditions to stderr and issue a warning. Prior to 10.5, the program would have + * crashed from an unhandled exception. */ QPDF_DLL void qpdf_silence_errors(qpdf_data qpdf); - /* Returns the version of the qpdf software. This is guaranteed to - * be a static value. + /* Returns the version of the qpdf software. This is guaranteed to be a static value. */ QPDF_DLL char const* qpdf_get_qpdf_version(); - /* Returns dynamically allocated qpdf_data pointer; must be freed - * by calling qpdf_cleanup. You must call qpdf_read, one of the - * other qpdf_read_* functions, or qpdf_empty_pdf before calling + /* Returns dynamically allocated qpdf_data pointer; must be freed by calling qpdf_cleanup. You + * must call qpdf_read, one of the other qpdf_read_* functions, or qpdf_empty_pdf before calling * any function that would need to operate on the PDF file. */ QPDF_DLL qpdf_data qpdf_init(); - /* Pass a pointer to the qpdf_data pointer created by qpdf_init to - * clean up resources. This does not include buffers initialized - * by functions that return stream data but it otherwise includes - * all data associated with the QPDF object or any object handles. + /* Pass a pointer to the qpdf_data pointer created by qpdf_init to clean up resources. This does + * not include buffers initialized by functions that return stream data but it otherwise + * includes all data associated with the QPDF object or any object handles. */ QPDF_DLL void qpdf_cleanup(qpdf_data* qpdf); /* ERROR REPORTING */ - /* Returns 1 if there is an error condition. The error condition - * can be retrieved by a single call to qpdf_get_error. + /* Returns 1 if there is an error condition. The error condition can be retrieved by a single + * call to qpdf_get_error. */ QPDF_DLL QPDF_BOOL qpdf_has_error(qpdf_data qpdf); - /* Returns the error condition, if any. The return value is a - * pointer to data that will become invalid after the next call to - * this function, qpdf_next_warning, or qpdf_cleanup. After this - * function is called, qpdf_has_error will return QPDF_FALSE until - * the next error condition occurs. If there is no error - * condition, this function returns a null pointer. + /* Returns the error condition, if any. The return value is a pointer to data that will become + * invalid after the next call to this function, qpdf_next_warning, or qpdf_cleanup. After this + * function is called, qpdf_has_error will return QPDF_FALSE until the next error condition + * occurs. If there is no error condition, this function returns a null pointer. */ QPDF_DLL qpdf_error qpdf_get_error(qpdf_data qpdf); - /* Returns 1 if there are any unretrieved warnings, and zero - * otherwise. + /* Returns 1 if there are any unretrieved warnings, and zero otherwise. */ QPDF_DLL QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf); - /* If there are any warnings, returns a pointer to the next - * warning. Otherwise returns a null pointer. + /* If there are any warnings, returns a pointer to the next warning. Otherwise returns a null + * pointer. */ QPDF_DLL qpdf_error qpdf_next_warning(qpdf_data qpdf); /* Extract fields of the error. */ - /* Use this function to get a full error message suitable for - * showing to the user. */ + /* Use this function to get a full error message suitable for showing to the user. */ QPDF_DLL char const* qpdf_get_error_full_text(qpdf_data q, qpdf_error e); - /* Use these functions to extract individual fields from the - * error; see QPDFExc.hh for details. */ + /* Use these functions to extract individual fields from the error; see QPDFExc.hh for details. + */ QPDF_DLL enum qpdf_error_code_e qpdf_get_error_code(qpdf_data q, qpdf_error e); QPDF_DLL @@ -242,9 +208,8 @@ extern "C" { QPDF_DLL char const* qpdf_get_error_message_detail(qpdf_data q, qpdf_error e); - /* By default, warnings are written to stderr. Passing true to - * this function will prevent warnings from being written to - * stderr. They will still be available by calls to + /* By default, warnings are written to stderr. Passing true to this function will prevent + * warnings from being written to stderr. They will still be available by calls to * qpdf_next_warning. */ QPDF_DLL @@ -252,11 +217,9 @@ extern "C" { /* LOG FUNCTIONS */ - /* Set or get the current logger. You need to call - * qpdflogger_cleanup on the logger handles when you are done with - * the handles. The underlying logger is cleaned up automatically - * and persists if needed after the logger handle is destroyed. - * See comments in qpdflogger-c.h for details. + /* Set or get the current logger. You need to call qpdflogger_cleanup on the logger handles when + * you are done with the handles. The underlying logger is cleaned up automatically and persists + * if needed after the logger handle is destroyed. See comments in qpdflogger-c.h for details. */ QPDF_DLL @@ -266,8 +229,7 @@ extern "C" { /* CHECK FUNCTIONS */ - /* Attempt to read the entire PDF file to see if there are any - * errors qpdf can detect. + /* Attempt to read the entire PDF file to see if there are any errors qpdf can detect. */ QPDF_DLL QPDF_ERROR_CODE qpdf_check_pdf(qpdf_data qpdf); @@ -284,20 +246,17 @@ extern "C" { /* This functions process a PDF or JSON input source. */ - /* Calling qpdf_read causes processFile to be called in the C++ - * API. Basic parsing is performed, but data from the file is - * only read as needed. For files without passwords, pass a null - * pointer or an empty string as the password. + /* Calling qpdf_read causes processFile to be called in the C++ API. Basic parsing is + * performed, but data from the file is only read as needed. For files without passwords, pass + * a null pointer or an empty string as the password. */ QPDF_DLL QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename, char const* password); - /* Calling qpdf_read_memory causes processMemoryFile to be called - * in the C++ API. Otherwise, it behaves in the same way as - * qpdf_read. The description argument will be used in place of - * the file name in any error or warning messages generated by the - * library. + /* Calling qpdf_read_memory causes processMemoryFile to be called in the C++ API. Otherwise, it + * behaves in the same way as qpdf_read. The description argument will be used in place of the + * file name in any error or warning messages generated by the library. */ QPDF_DLL QPDF_ERROR_CODE qpdf_read_memory( @@ -307,22 +266,20 @@ extern "C" { unsigned long long size, char const* password); - /* Calling qpdf_empty_pdf initializes this qpdf object with an - * empty PDF, making it possible to create a PDF from scratch - * using the C API. Added in 10.6. + /* Calling qpdf_empty_pdf initializes this qpdf object with an empty PDF, making it possible to + * create a PDF from scratch using the C API. Added in 10.6. */ QPDF_DLL QPDF_ERROR_CODE qpdf_empty_pdf(qpdf_data qpdf); - /* Create a PDF from a JSON file. This calls createFromJSON in the - * C++ API. + /* Create a PDF from a JSON file. This calls createFromJSON in the C++ API. */ QPDF_DLL QPDF_ERROR_CODE qpdf_create_from_json_file(qpdf_data qpdf, char const* filename); - /* Create a PDF from JSON data in a null-terminated string. This - * calls createFromJSON in the C++ API. + /* Create a PDF from JSON data in a null-terminated string. This calls createFromJSON in the C++ + * API. */ QPDF_DLL QPDF_ERROR_CODE @@ -330,10 +287,9 @@ extern "C" { /* JSON UPDATE FUNCTIONS */ - /* Update a QPDF object from a JSON file or buffer. These - * functions call updateFromJSON. One of the other processing - * functions has to be called first so that the QPDF object is - * initialized with PDF data. + /* Update a QPDF object from a JSON file or buffer. These functions call updateFromJSON. One of + * the other processing functions has to be called first so that the QPDF object is initialized + * with PDF data. */ QPDF_DLL QPDF_ERROR_CODE @@ -344,18 +300,16 @@ extern "C" { /* READ FUNCTIONS */ - /* Read functions below must be called after qpdf_read or any of - * the other functions that process a PDF. */ + /* Read functions below must be called after qpdf_read or any of the other functions that + * process a PDF. */ /* - * NOTE: Functions that return char* are returning a pointer to an - * internal buffer that will be reused for each call to a function - * that returns a char*. You must use or copy the value before - * calling any other qpdf library functions. + * NOTE: Functions that return char* are returning a pointer to an internal buffer that will be + * reused for each call to a function that returns a char*. You must use or copy the value + * before calling any other qpdf library functions. */ - /* Return the version of the PDF file. See warning above about - * functions that return char*. */ + /* Return the version of the PDF file. See warning above about functions that return char*. */ QPDF_DLL char const* qpdf_get_pdf_version(qpdf_data qpdf); @@ -363,30 +317,26 @@ extern "C" { QPDF_DLL int qpdf_get_pdf_extension_level(qpdf_data qpdf); - /* Return the user password. If the file is opened using the - * owner password, the user password may be retrieved using this - * function. If the file is opened using the user password, this - * function will return that user password. See warning above - * about functions that return char*. + /* Return the user password. If the file is opened using the owner password, the user password + * may be retrieved using this function. If the file is opened using the user password, this + * function will return that user password. See warning above about functions that return + * char*. */ QPDF_DLL char const* qpdf_get_user_password(qpdf_data qpdf); - /* Return the string value of a key in the document's Info - * dictionary. The key parameter should include the leading - * slash, e.g. "/Author". If the key is not present or has a - * non-string value, a null pointer is returned. Otherwise, a - * pointer to an internal buffer is returned. See warning above - * about functions that return char*. + /* Return the string value of a key in the document's Info dictionary. The key parameter should + * include the leading slash, e.g. "/Author". If the key is not present or has a non-string + * value, a null pointer is returned. Otherwise, a pointer to an internal buffer is returned. + * See warning above about functions that return char*. */ QPDF_DLL char const* qpdf_get_info_key(qpdf_data qpdf, char const* key); - /* Set a value in the info dictionary, possibly replacing an - * existing value. The key must include the leading slash - * (e.g. "/Author"). Passing a null pointer as a value will - * remove the key from the info dictionary. Otherwise, a copy - * will be made of the string that is passed in. + /* Set a value in the info dictionary, possibly replacing an existing value. The key must + * include the leading slash (e.g. "/Author"). Passing a null pointer as a value will remove + * the key from the info dictionary. Otherwise, a copy will be made of the string that is + * passed in. */ QPDF_DLL void qpdf_set_info_key(qpdf_data qpdf, char const* key, char const* value); @@ -420,21 +370,16 @@ extern "C" { /* JSON WRITE FUNCTIONS */ - /* This function serializes the PDF to JSON. This calls writeJSON - * from the C++ API. + /* This function serializes the PDF to JSON. This calls writeJSON from the C++ API. * * - version: the JSON version, currently must be 2 - * - fn: a function that will be called with blocks of JSON data; - * will be called with data, a length, and the value of the - * udata parameter to this function - * - udata: will be passed as the third argument to fn with each - * call; use this for your own tracking or pass a null pointer - * if you don't need it - * - For decode_level, json_stream_data, file_prefix, and - * wanted_objects, see comments in QPDF.hh. For this API, - * wanted_objects should be a null-terminated array of - * null-terminated strings. Pass a null pointer if you want all - * objects. + * - fn: a function that will be called with blocks of JSON data; will be called with data, a + * length, and the value of the udata parameter to this function + * - udata: will be passed as the third argument to fn with each call; use this for your own + * tracking or pass a null pointer if you don't need it + * - For decode_level, json_stream_data, file_prefix, and wanted_objects, see comments in + * QPDF.hh. For this API, wanted_objects should be a null-terminated array of null-terminated + * strings. Pass a null pointer if you want all objects. */ /* Function should return 0 on success. */ @@ -453,37 +398,29 @@ extern "C" { /* WRITE FUNCTIONS */ - /* Set up for writing. No writing is actually performed until the - * call to qpdf_write(). + /* Set up for writing. No writing is actually performed until the call to qpdf_write(). */ - /* Supply the name of the file to be written and initialize the - * qpdf_data object to handle writing operations. This function - * also attempts to create the file. The PDF data is not written - * until the call to qpdf_write. qpdf_init_write may be called - * multiple times for the same qpdf_data object. When - * qpdf_init_write is called, all information from previous calls - * to functions that set write parameters (qpdf_set_linearization, - * etc.) is lost, so any write parameter functions must be called - * again. + /* Supply the name of the file to be written and initialize the qpdf_data object to handle + * writing operations. This function also attempts to create the file. The PDF data is not + * written until the call to qpdf_write. qpdf_init_write may be called multiple times for the + * same qpdf_data object. When qpdf_init_write is called, all information from previous calls + * to functions that set write parameters (qpdf_set_linearization, etc.) is lost, so any write + * parameter functions must be called again. */ QPDF_DLL QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename); - /* Initialize for writing but indicate that the PDF file should be - * written to memory. Call qpdf_get_buffer_length and - * qpdf_get_buffer to retrieve the resulting buffer. The memory - * containing the PDF file will be destroyed when qpdf_cleanup is - * called. + /* Initialize for writing but indicate that the PDF file should be written to memory. Call + * qpdf_get_buffer_length and qpdf_get_buffer to retrieve the resulting buffer. The memory + * containing the PDF file will be destroyed when qpdf_cleanup is called. */ QPDF_DLL QPDF_ERROR_CODE qpdf_init_write_memory(qpdf_data qpdf); - /* Retrieve the buffer used if the file was written to memory. - * qpdf_get_buffer returns a null pointer if data was not written - * to memory. The memory is freed when qpdf_cleanup is called or - * if a subsequent call to qpdf_init_write or - * qpdf_init_write_memory is called. */ + /* Retrieve the buffer used if the file was written to memory. qpdf_get_buffer returns a null + * pointer if data was not written to memory. The memory is freed when qpdf_cleanup is called + * or if a subsequent call to qpdf_init_write or qpdf_init_write_memory is called. */ QPDF_DLL size_t qpdf_get_buffer_length(qpdf_data qpdf); QPDF_DLL @@ -516,14 +453,14 @@ extern "C" { QPDF_DLL void qpdf_set_deterministic_ID(qpdf_data qpdf, QPDF_BOOL value); - /* Never use qpdf_set_static_ID except in test suites to suppress - * generation of a random /ID. See also qpdf_set_deterministic_ID. + /* Never use qpdf_set_static_ID except in test suites to suppress generation of a random /ID. + * See also qpdf_set_deterministic_ID. */ QPDF_DLL void qpdf_set_static_ID(qpdf_data qpdf, QPDF_BOOL value); - /* Never use qpdf_set_static_aes_IV except in test suites to - * create predictable AES encrypted output. + /* Never use qpdf_set_static_aes_IV except in test suites to create predictable AES encrypted + * output. */ QPDF_DLL void qpdf_set_static_aes_IV(qpdf_data qpdf, QPDF_BOOL value); @@ -534,9 +471,8 @@ extern "C" { QPDF_DLL void qpdf_set_preserve_encryption(qpdf_data qpdf, QPDF_BOOL value); - /* The *_insecure functions are identical to the old versions but - * have been renamed as a an alert to the caller that they are - * insecure. See "Weak Cryptographic" in the manual for + /* The *_insecure functions are identical to the old versions but have been renamed as a an + * alert to the caller that they are insecure. See "Weak Cryptographic" in the manual for * details. */ QPDF_DLL @@ -622,15 +558,12 @@ extern "C" { void qpdf_force_pdf_version_and_extension(qpdf_data qpdf, char const* version, int extension_level); - /* During write, your report_progress function will be called with - * a value between 0 and 100 representing the approximate write - * progress. The data object you pass to - * qpdf_register_progress_reporter will be handed back to your - * function. This function must be called after qpdf_init_write - * (or qpdf_init_write_memory) and before qpdf_write. The - * registered progress reporter applies only to a single write, so - * you must call it again if you perform a subsequent write with a - * new writer. + /* During write, your report_progress function will be called with a value between 0 and 100 + * representing the approximate write progress. The data object you pass to + * qpdf_register_progress_reporter will be handed back to your function. This function must be + * called after qpdf_init_write (or qpdf_init_write_memory) and before qpdf_write. The + * registered progress reporter applies only to a single write, so you must call it again if you + * perform a subsequent write with a new writer. */ QPDF_DLL void qpdf_register_progress_reporter( @@ -642,67 +575,51 @@ extern "C" { /* Object handling. * - * These functions take and return a qpdf_oh object handle, which - * is just an unsigned integer. The value 0 is never returned, which - * makes it usable as an uninitialized value. The handles returned by - * these functions are guaranteed to be unique, i.e. two calls to - * (the same of different) functions will return distinct handles - * even when they refer to the same object. + * These functions take and return a qpdf_oh object handle, which is just an unsigned integer. + * The value 0 is never returned, which makes it usable as an uninitialized value. The handles + * returned by these functions are guaranteed to be unique, i.e. two calls to (the same of + * different) functions will return distinct handles even when they refer to the same object. * - * Each function below, starting with qpdf_oh, corresponds to a - * specific method of QPDFObjectHandler. For example, - * qpdf_oh_is_bool corresponds to QPDFObjectHandle::isBool. If the - * C++ method is overloaded, the C function's name will be - * disambiguated. If the C++ method takes optional arguments, the C - * function will have required arguments in those positions. For - * details about the method, please see comments in - * QPDFObjectHandle.hh. Comments here only explain things that are - * specific to the "C" API. + * Each function below, starting with qpdf_oh, corresponds to a specific method of + * QPDFObjectHandler. For example, qpdf_oh_is_bool corresponds to QPDFObjectHandle::isBool. If + * the C++ method is overloaded, the C function's name will be disambiguated. If the C++ method + * takes optional arguments, the C function will have required arguments in those positions. For + * details about the method, please see comments in QPDFObjectHandle.hh. Comments here only + * explain things that are specific to the "C" API. * - * Only a fraction of the methods of QPDFObjectHandle are - * available here. Most of the basic methods for creating, - * accessing, and modifying most types of objects are present. - * Most of the higher-level functions are not implemented. - * Functions for dealing with content streams as well as objects - * that only exist in content streams (operators and inline - * images) are mostly not provided. + * Only a fraction of the methods of QPDFObjectHandle are available here. Most of the basic + * methods for creating, accessing, and modifying most types of objects are present. Most of the + * higher-level functions are not implemented. Functions for dealing with content streams as + * well as objects that only exist in content streams (operators and inline images) are mostly + * not provided. * - * To refer to a specific QPDFObjectHandle, you need a pair - * consisting of a qpdf_data and a qpdf_oh, which is just an index - * into an internal table of objects. All memory allocated by any - * of these functions is returned when qpdf_cleanup is called. + * To refer to a specific QPDFObjectHandle, you need a pair consisting of a qpdf_data and a + * qpdf_oh, which is just an index into an internal table of objects. All memory allocated by + * any of these functions is returned when qpdf_cleanup is called. * - * Regarding memory, the same rules apply as the above functions. - * Specifically, if a function returns a char*, the memory is - * managed by the library and, unless otherwise specified, is not + * Regarding memory, the same rules apply as the above functions. Specifically, if a function + * returns a char*, the memory is managed by the library and, unless otherwise specified, is not * expected to be valid after the next qpdf call. * - * The qpdf_data object keeps a cache of handles returned by these - * functions. Once you are finished referencing a handle, you can - * optionally release it. Releasing handles is optional since they - * will all get released by qpdf_cleanup, but it can help to - * reduce the memory footprint of the qpdf_data object to release - * them when you're done. Releasing a handle does not destroy the - * object. All QPDFObjectHandle objects are deleted when they are - * no longer referenced. Releasing an object handle simply - * invalidates it. For example, if you create an object, - * add it to an existing dictionary or array, and then release its - * handle, the object is safely part of the dictionary or array. - * Similarly, any other object handle refering to the object remains - * valid. Explicitly releasing an object handle is essentially the - * same as letting a QPDFObjectHandle go out of scope in the C++ - * API. + * The qpdf_data object keeps a cache of handles returned by these functions. Once you are + * finished referencing a handle, you can optionally release it. Releasing handles is optional + * since they will all get released by qpdf_cleanup, but it can help to reduce the memory + * footprint of the qpdf_data object to release them when you're done. Releasing a handle does + * not destroy the object. All QPDFObjectHandle objects are deleted when they are no longer + * referenced. Releasing an object handle simply invalidates it. For example, if you create an + * object, add it to an existing dictionary or array, and then release its handle, the object is + * safely part of the dictionary or array. Similarly, any other object handle refering to the + * object remains valid. Explicitly releasing an object handle is essentially the same as + * letting a QPDFObjectHandle go out of scope in the C++ API. * - * Please see "ERROR HANDLING" above for details on how error - * conditions are handled. + * Please see "ERROR HANDLING" above for details on how error conditions are handled. */ /* For examples of using this API, see examples/pdf-c-objects.c */ typedef unsigned int qpdf_oh; - /* Releasing objects -- see comments above. These functions have no - * equivalent in the C++ API. + /* Releasing objects -- see comments above. These functions have no equivalent in the C++ API. */ QPDF_DLL void qpdf_oh_release(qpdf_data qpdf, qpdf_oh oh); @@ -727,13 +644,11 @@ extern "C" { QPDF_DLL void qpdf_replace_object(qpdf_data qpdf, int objid, int generation, qpdf_oh oh); - /* Wrappers around QPDFObjectHandle methods. Be sure to read - * corresponding comments in QPDFObjectHandle.hh to understand - * what each function does and what kinds of objects it applies - * to. Note that names are to appear in a canonicalized form - * starting with a leading slash and with all PDF escaping - * resolved. See comments for getName() in QPDFObjectHandle.hh for - * details. + /* Wrappers around QPDFObjectHandle methods. Be sure to read corresponding comments in + * QPDFObjectHandle.hh to understand what each function does and what kinds of objects it + * applies to. Note that names are to appear in a canonicalized form starting with a leading + * slash and with all PDF escaping resolved. See comments for getName() in QPDFObjectHandle.hh + * for details. */ QPDF_DLL @@ -829,18 +744,14 @@ extern "C" { QPDF_BOOL qpdf_oh_get_value_as_name(qpdf_data qpdf, qpdf_oh oh, char const** value, size_t* length); - /* Return the length of the last string returned. This enables you - * to retrieve the entire string for cases in which a char* - * returned by one of the functions below points to a string with - * embedded null characters. The function - * qpdf_oh_get_binary_string_value takes a length pointer, which - * can be useful if you are retrieving the value of a string that - * is expected to contain binary data, such as a checksum or - * document ID. It is always valid to call - * qpdf_get_last_string_length, but it is usually not necessary as - * C strings returned by the library are only expected to be able - * to contain null characters if their values originate from PDF - * strings in the input. + /* Return the length of the last string returned. This enables you to retrieve the entire string + * for cases in which a char* returned by one of the functions below points to a string with + * embedded null characters. The function qpdf_oh_get_binary_string_value takes a length + * pointer, which can be useful if you are retrieving the value of a string that is expected to + * contain binary data, such as a checksum or document ID. It is always valid to call + * qpdf_get_last_string_length, but it is usually not necessary as C strings returned by the + * library are only expected to be able to contain null characters if their values originate + * from PDF strings in the input. */ QPDF_DLL size_t qpdf_get_last_string_length(qpdf_data qpdf); @@ -865,10 +776,9 @@ extern "C" { QPDF_DLL qpdf_oh qpdf_oh_get_array_item(qpdf_data qpdf, qpdf_oh oh, int n); - /* In all dictionary APIs, keys are specified/represented as - * canonicalized name strings starting with / and with all PDF - * escaping resolved. See comments for getName() in - * QPDFObjectHandle for details. + /* In all dictionary APIs, keys are specified/represented as canonicalized name strings starting + * with / and with all PDF escaping resolved. See comments for getName() in QPDFObjectHandle for + * details. */ /* "C"-specific dictionary key iteration */ @@ -878,11 +788,9 @@ extern "C" { void qpdf_oh_begin_dict_key_iter(qpdf_data qpdf, qpdf_oh dict); QPDF_DLL QPDF_BOOL qpdf_oh_dict_more_keys(qpdf_data qpdf); - /* The memory returned by qpdf_oh_dict_next_key is owned by - * qpdf_data. It is good until the next call to - * qpdf_oh_dict_next_key with the same qpdf_data object. Calling - * the function again, even with a different dict, invalidates - * previous return values. + /* The memory returned by qpdf_oh_dict_next_key is owned by qpdf_data. It is good until the next + * call to qpdf_oh_dict_next_key with the same qpdf_data object. Calling the function again, + * even with a different dict, invalidates previous return values. */ QPDF_DLL char const* qpdf_oh_dict_next_key(qpdf_data qpdf); @@ -918,8 +826,8 @@ extern "C" { qpdf_oh qpdf_oh_new_string(qpdf_data qpdf, char const* str); QPDF_DLL qpdf_oh qpdf_oh_new_unicode_string(qpdf_data qpdf, char const* utf8_str); - /* Use qpdf_oh_new_binary_string for creating a string that may - * contain atrbitary binary data including embedded null characters. + /* Use qpdf_oh_new_binary_string for creating a string that may contain atrbitary binary data + * including embedded null characters. */ QPDF_DLL qpdf_oh qpdf_oh_new_binary_string(qpdf_data qpdf, char const* str, size_t length); @@ -930,11 +838,10 @@ extern "C" { QPDF_DLL qpdf_oh qpdf_oh_new_dictionary(qpdf_data qpdf); - /* Create a new stream. Use qpdf_oh_get_dict to get (and - * subsequently modify) the stream dictionary if needed. See - * comments in QPDFObjectHandle.hh for newStream() for additional - * notes. You must call qpdf_oh_replace_stream_data to provide - * data for the stream. See STREAM FUNCTIONS below. + /* Create a new stream. Use qpdf_oh_get_dict to get (and subsequently modify) the stream + * dictionary if needed. See comments in QPDFObjectHandle.hh for newStream() for additional + * notes. You must call qpdf_oh_replace_stream_data to provide data for the stream. See STREAM + * FUNCTIONS below. */ QPDF_DLL qpdf_oh qpdf_oh_new_stream(qpdf_data qpdf); @@ -973,40 +880,33 @@ extern "C" { QPDF_DLL char const* qpdf_oh_unparse_binary(qpdf_data qpdf, qpdf_oh oh); - /* Note about foreign objects: the C API does not have enough - * information in the value of a qpdf_oh to know what QPDF object - * it belongs to. To uniquely specify a qpdf object handle from a - * specific qpdf_data instance, you always pair the qpdf_oh with - * the correct qpdf_data. Otherwise, you are likely to get - * completely the wrong object if you are not lucky enough to get - * an error about the object being invalid. + /* Note about foreign objects: the C API does not have enough information in the value of a + * qpdf_oh to know what QPDF object it belongs to. To uniquely specify a qpdf object handle from + * a specific qpdf_data instance, you always pair the qpdf_oh with the correct qpdf_data. + * Otherwise, you are likely to get completely the wrong object if you are not lucky enough to + * get an error about the object being invalid. */ - /* Copy foreign object: the qpdf_oh returned belongs to `qpdf`, - * while `foreign_oh` belongs to `other_qpdf`. + /* Copy foreign object: the qpdf_oh returned belongs to `qpdf`, while `foreign_oh` belongs to + * `other_qpdf`. */ QPDF_DLL qpdf_oh qpdf_oh_copy_foreign_object(qpdf_data qpdf, qpdf_data other_qpdf, qpdf_oh foreign_oh); /* STREAM FUNCTIONS */ - /* These functions provide basic access to streams and stream - * data. They are not as comprehensive as what is in - * QPDFObjectHandle, but they do allow for working with streams - * and stream data as caller-managed memory. + /* These functions provide basic access to streams and stream data. They are not as + * comprehensive as what is in QPDFObjectHandle, but they do allow for working with streams and + * stream data as caller-managed memory. */ - /* Get stream data as a buffer. The buffer is allocated with - * malloc and must be freed by the caller. The size of the buffer - * is stored in *len. The arguments are similar to those in - * QPDFObjectHandle::pipeStreamData. To get raw stream data, pass - * qpdf_dl_none as decode_level. Otherwise, filtering is attempted - * and *filtered is set to indicate whether it was successful. If - * *filtered is QPDF_FALSE, then raw, unfiltered stream data was - * returned. You may pass a null pointer as filtered if you don't - * care about the result. If you pass a null pointer as bufp (and - * len), the value of filtered will be set to whether the stream - * can be filterable. + /* Get stream data as a buffer. The buffer is allocated with malloc and must be freed by the + * caller. The size of the buffer is stored in *len. The arguments are similar to those in + * QPDFObjectHandle::pipeStreamData. To get raw stream data, pass qpdf_dl_none as decode_level. + * Otherwise, filtering is attempted and *filtered is set to indicate whether it was successful. + * If *filtered is QPDF_FALSE, then raw, unfiltered stream data was returned. You may pass a + * null pointer as filtered if you don't care about the result. If you pass a null pointer as + * bufp (and len), the value of filtered will be set to whether the stream can be filterable. */ QPDF_DLL QPDF_ERROR_CODE qpdf_oh_get_stream_data( @@ -1017,17 +917,16 @@ extern "C" { unsigned char** bufp, size_t* len); - /* This function returns the concatenation of all of a page's - * content streams as a single, dynamically allocated buffer. As - * with qpdf_oh_get_stream_data, the buffer is allocated with + /* This function returns the concatenation of all of a page's content streams as a single, + * dynamically allocated buffer. As with qpdf_oh_get_stream_data, the buffer is allocated with * malloc and must be freed by the caller. */ QPDF_DLL QPDF_ERROR_CODE qpdf_oh_get_page_content_data( qpdf_data qpdf, qpdf_oh page_oh, unsigned char** bufp, size_t* len); - /* The data pointed to by bufp will be copied by the library. It - * does not need to remain valid after the call returns. + /* The data pointed to by bufp will be copied by the library. It does not need to remain valid + * after the call returns. */ QPDF_DLL void qpdf_oh_replace_stream_data( @@ -1040,21 +939,18 @@ extern "C" { /* PAGE FUNCTIONS */ - /* The first time a page function is called, qpdf will traverse - * the /Pages tree. Subsequent calls to retrieve the number of - * pages or a specific page run in constant time as they are - * accessing the pages cache. If you manipulate the page tree - * outside of these functions, you should call - * qpdf_update_all_pages_cache. See comments for getAllPages() and + /* The first time a page function is called, qpdf will traverse the /Pages tree. Subsequent + * calls to retrieve the number of pages or a specific page run in constant time as they are + * accessing the pages cache. If you manipulate the page tree outside of these functions, you + * should call qpdf_update_all_pages_cache. See comments for getAllPages() and * updateAllPagesCache() in QPDF.hh. */ - /* For each function, the corresponding method in QPDF.hh is - * referenced. Please see comments in QPDF.hh for details. + /* For each function, the corresponding method in QPDF.hh is referenced. Please see comments in + * QPDF.hh for details. */ - /* calls getAllPages(). On error, returns -1 and sets error for - * qpdf_get_error. */ + /* calls getAllPages(). On error, returns -1 and sets error for qpdf_get_error. */ QPDF_DLL int qpdf_get_num_pages(qpdf_data qpdf); /* returns uninitialized object if out of range */ @@ -1065,9 +961,8 @@ extern "C" { QPDF_DLL QPDF_ERROR_CODE qpdf_update_all_pages_cache(qpdf_data qpdf); - /* findPage() -- return zero-based index. If page is not found, - * return -1 and save the error to be retrieved with - * qpdf_get_error. + /* findPage() -- return zero-based index. If page is not found, return -1 and save the error to + * be retrieved with qpdf_get_error. */ QPDF_DLL int qpdf_find_page_by_id(qpdf_data qpdf, int objid, int generation); @@ -1078,10 +973,9 @@ extern "C" { QPDF_DLL QPDF_ERROR_CODE qpdf_push_inherited_attributes_to_page(qpdf_data qpdf); - /* Functions that add pages may add pages from other files. If - * adding a page from the same file, newpage_qpdf and qpdf are the - * same. - /*/ + /* Functions that add pages may add pages from other files. If adding a page from the same file, + newpage_qpdf and qpdf are the same. + */ /* addPage() */ QPDF_DLL diff --git a/include/qpdf/qpdfjob-c.h b/include/qpdf/qpdfjob-c.h index c41dbeee..3db41d3e 100644 --- a/include/qpdf/qpdfjob-c.h +++ b/include/qpdf/qpdfjob-c.h @@ -2,33 +2,29 @@ * * 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 + * 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. + * 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. + * 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 QPDFJOB_C_H #define QPDFJOB_C_H /* - * This file defines a basic "C" API for QPDFJob. See also qpdf-c.h, - * which defines an API that exposes more of the library's API. This - * API is primarily intended to make it simpler for programs in - * languages other than C++ to incorporate functionality that could be - * run directly from the command-line. + * This file defines a basic "C" API for QPDFJob. See also qpdf-c.h, which defines an API that + * exposes more of the library's API. This API is primarily intended to make it simpler for programs + * in languages other than C++ to incorporate functionality that could be run directly from the + * command-line. */ #include @@ -40,52 +36,46 @@ #endif /* - * This file provides a minimal wrapper around QPDFJob. See - * examples/qpdfjob-c.c for an example of its use. + * This file provides a minimal wrapper around QPDFJob. See examples/qpdfjob-c.c for an example of + * its use. */ #ifdef __cplusplus extern "C" { #endif - /* SHORT INTERFACE -- These functions are single calls that take - * care of the whole life cycle of QPDFJob. They can be used for - * one-shot operations where no additional configuration is + /* SHORT INTERFACE -- These functions are single calls that take care of the whole life cycle of + * QPDFJob. They can be used for one-shot operations where no additional configuration is * needed. See FULL INTERFACE below. */ - /* This function does the equivalent of running the qpdf - * command-line with the given arguments and returns the exit code - * that qpdf would use. argv must be a null-terminated array of - * null-terminated UTF8-encoded strings. If calling this from - * wmain on Windows, use qpdfjob_run_from_wide_argv instead. Exit - * code values are defined in Constants.h in the qpdf_exit_code_e - * type. + /* This function does the equivalent of running the qpdf command-line with the given arguments + * and returns the exit code that qpdf would use. argv must be a null-terminated array of + * null-terminated UTF8-encoded strings. If calling this from wmain on Windows, use + * qpdfjob_run_from_wide_argv instead. Exit code values are defined in Constants.h in the + * qpdf_exit_code_e type. */ QPDF_DLL int qpdfjob_run_from_argv(char const* const argv[]); #ifndef QPDF_NO_WCHAR_T - /* This function is the same as qpdfjob_run_from_argv except argv - * is encoded with wide characters. This would be suitable for - * calling from a Windows wmain function. + /* This function is the same as qpdfjob_run_from_argv except argv is encoded with wide + * characters. This would be suitable for calling from a Windows wmain function. */ QPDF_DLL int qpdfjob_run_from_wide_argv(wchar_t const* const argv[]); #endif /* QPDF_NO_WCHAR_T */ - /* This function runs QPDFJob from a job JSON file. See the "QPDF - * Job" section of the manual for details. The JSON string must be - * UTF8-encoded. It returns the error code that qpdf would return - * with the equivalent command-line invocation. Exit code values - * are defined in Constants.h in the qpdf_exit_code_e type. + /* This function runs QPDFJob from a job JSON file. See the "QPDF Job" section of the manual for + * details. The JSON string must be UTF8-encoded. It returns the error code that qpdf would + * return with the equivalent command-line invocation. Exit code values are defined in + * Constants.h in the qpdf_exit_code_e type. */ QPDF_DLL int qpdfjob_run_from_json(char const* json); - /* FULL INTERFACE -- new in qpdf11. Similar to the qpdf-c.h API, - * you must call qpdfjob_init to get a qpdfjob_handle and, when - * done, call qpdfjob_cleanup to free resources. Remaining methods - * take qpdfjob_handle as an argument. This interface requires - * more calls but also offers greater flexibility. + /* FULL INTERFACE -- new in qpdf11. Similar to the qpdf-c.h API, you must call qpdfjob_init to + * get a qpdfjob_handle and, when done, call qpdfjob_cleanup to free resources. Remaining + * methods take qpdfjob_handle as an argument. This interface requires more calls but also + * offers greater flexibility. */ typedef struct _qpdfjob_handle* qpdfjob_handle; QPDF_DLL @@ -94,11 +84,9 @@ extern "C" { QPDF_DLL void qpdfjob_cleanup(qpdfjob_handle* j); - /* Set or get the current logger. You need to call - * qpdflogger_cleanup on the logger handles when you are done with - * the handles. The underlying logger is cleaned up automatically - * and persists if needed after the logger handle is destroyed. - * See comments in qpdflogger-c.h for details. + /* Set or get the current logger. You need to call qpdflogger_cleanup on the logger handles when + * you are done with the handles. The underlying logger is cleaned up automatically and persists + * if needed after the logger handle is destroyed. See comments in qpdflogger-c.h for details. */ QPDF_DLL @@ -106,62 +94,54 @@ extern "C" { QPDF_DLL qpdflogger_handle qpdfjob_get_logger(qpdfjob_handle j); - /* This function wraps QPDFJob::initializeFromArgv. The return - * value is the same as qpdfjob_run. If this returns an error, it - * is invalid to call any other functions this job handle. + /* This function wraps QPDFJob::initializeFromArgv. The return value is the same as qpdfjob_run. + * If this returns an error, it is invalid to call any other functions this job handle. */ QPDF_DLL int qpdfjob_initialize_from_argv(qpdfjob_handle j, char const* const argv[]); #ifndef QPDF_NO_WCHAR_T - /* This function is the same as qpdfjob_initialize_from_argv - * except argv is encoded with wide characters. This would be - * suitable for calling from a Windows wmain function. + /* This function is the same as qpdfjob_initialize_from_argv except argv is encoded with wide + * characters. This would be suitable for calling from a Windows wmain function. */ QPDF_DLL int qpdfjob_initialize_from_wide_argv(qpdfjob_handle j, wchar_t const* const argv[]); #endif /* QPDF_NO_WCHAR_T */ - /* This function wraps QPDFJob::initializeFromJson. The return - * value is the same as qpdfjob_run. If this returns an error, it - * is invalid to call any other functions this job handle. + /* This function wraps QPDFJob::initializeFromJson. The return value is the same as qpdfjob_run. + * If this returns an error, it is invalid to call any other functions this job handle. */ QPDF_DLL int qpdfjob_initialize_from_json(qpdfjob_handle j, char const* json); - /* This function wraps QPDFJob::run. It returns the error code - * that qpdf would return with the equivalent command-line - * invocation. Exit code values are defined in Constants.h in the + /* This function wraps QPDFJob::run. It returns the error code that qpdf would return with the + * equivalent command-line invocation. Exit code values are defined in Constants.h in the * qpdf_exit_code_e type. */ QPDF_DLL int qpdfjob_run(qpdfjob_handle j); - /* The following two functions allow a job to be run in two stages - - * creation of a qpdf_data object and writing of the qpdf_data object. This - * allows the qpdf_data object to be modified prior to writing it out. See - * examples/qpdfjob-remove-annotations for a C++ illustration of its use. + /* The following two functions allow a job to be run in two stages - creation of a qpdf_data + * object and writing of the qpdf_data object. This allows the qpdf_data object to be modified + * prior to writing it out. See examples/qpdfjob-remove-annotations for a C++ illustration of + * its use. * - * This function wraps QPDFJob::createQPDF. It runs the first stage of the - * job. A nullptr is returned if the job did not produce any pdf file to be - * written. + * This function wraps QPDFJob::createQPDF. It runs the first stage of the job. A nullptr is + * returned if the job did not produce any pdf file to be written. */ QPDF_DLL qpdf_data qpdfjob_create_qpdf(qpdfjob_handle j); - /* This function wraps QPDFJob::writeQPDF. It returns the error code that - * qpdf would return with the equivalent command-line invocation. Exit code - * values are defined in Constants.h in the qpdf_exit_code_e type. NOTE it - * is the callers responsibility to clean up the resources associated - * qpdf_data object by calling qpdf_cleanup after the call to - * qpdfjob_write_qpdf. + /* This function wraps QPDFJob::writeQPDF. It returns the error code that qpdf would return with + * the equivalent command-line invocation. Exit code values are defined in Constants.h in the + * qpdf_exit_code_e type. NOTE it is the callers responsibility to clean up the resources + * associated qpdf_data object by calling qpdf_cleanup after the call to qpdfjob_write_qpdf. */ QPDF_DLL int qpdfjob_write_qpdf(qpdfjob_handle j, qpdf_data qpdf); - /* Allow specification of a custom progress reporter. The progress - * reporter is only used if progress is otherwise requested (with - * the --progress option or "progress": "" in the JSON). + /* Allow specification of a custom progress reporter. The progress reporter is only used if + * progress is otherwise requested (with the --progress option or "progress": "" in the JSON). */ QPDF_DLL void qpdfjob_register_progress_reporter( diff --git a/include/qpdf/qpdflogger-c.h b/include/qpdf/qpdflogger-c.h index 966c47f1..ce3d87a4 100644 --- a/include/qpdf/qpdflogger-c.h +++ b/include/qpdf/qpdflogger-c.h @@ -2,30 +2,26 @@ * * 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 + * 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. + * 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. + * 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 and + * This file provides a C API for QPDFLogger. See QPDFLogger.hh for information about the logger and * examples/qpdfjob-c-save-attachment.c for an example. */ @@ -36,26 +32,21 @@ 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. There are functions in qpdf-c.h and qpdfjob-c.h that - * also take or return logger handles. When you're done with the - * logger handler, call qpdflogger_cleanup. This cleans up the - * handle but leaves the underlying log object intact. (It uses a - * shared pointer and will be cleaned up automatically when it is - * no longer in use.) That means you can create a logger with - * qpdflogger_create(), pass the logger handle to a function in - * qpdf-c.h or qpdfjob-c.h, and then clean it up, subject to - * constraints imposed by the other function. + /* To operate on a logger, you need a handle to it. call qpdflogger_default_logger to get a + * handle for the default logger. There are functions in qpdf-c.h and qpdfjob-c.h that also take + * or return logger handles. When you're done with the logger handler, call qpdflogger_cleanup. + * This cleans up the handle but leaves the underlying log object intact. (It uses a shared + * pointer and will be cleaned up automatically when it is no longer in use.) That means you can + * create a logger with qpdflogger_create(), pass the logger handle to a function in qpdf-c.h or + * qpdfjob-c.h, and then clean it up, subject to constraints imposed by the other function. */ typedef struct _qpdflogger_handle* qpdflogger_handle; QPDF_DLL qpdflogger_handle qpdflogger_default_logger(); - /* Calling cleanup on the handle returned by qpdflogger_create - * destroys the handle but not the underlying logger. See comments - * above. + /* Calling cleanup on the handle returned by qpdflogger_create destroys the handle but not the + * underlying logger. See comments above. */ QPDF_DLL qpdflogger_handle qpdflogger_create(); @@ -84,8 +75,8 @@ extern "C" { 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. + /* 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( diff --git a/libqpdf/ClosedFileInputSource.cc b/libqpdf/ClosedFileInputSource.cc index 06ebb156..5e607a76 100644 --- a/libqpdf/ClosedFileInputSource.cc +++ b/libqpdf/ClosedFileInputSource.cc @@ -11,8 +11,7 @@ ClosedFileInputSource::ClosedFileInputSource(char const* filename) : ClosedFileInputSource::~ClosedFileInputSource() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void @@ -91,8 +90,7 @@ ClosedFileInputSource::unreadCh(char ch) { before(); this->fis->unreadCh(ch); - // Don't call after -- the file has to stay open after this - // operation. + // Don't call after -- the file has to stay open after this operation. } void diff --git a/libqpdf/ContentNormalizer.cc b/libqpdf/ContentNormalizer.cc index b05b4220..47830f42 100644 --- a/libqpdf/ContentNormalizer.cc +++ b/libqpdf/ContentNormalizer.cc @@ -41,9 +41,8 @@ ContentNormalizer::handleToken(QPDFTokenizer::Token const& token) break; case QPDFTokenizer::tt_string: - // Replacing string and name tokens in this way normalizes - // their representation as this will automatically handle - // quoting of unprintable characters, etc. + // Replacing string and name tokens in this way normalizes their representation as this will + // automatically handle quoting of unprintable characters, etc. writeToken(QPDFTokenizer::Token(QPDFTokenizer::tt_string, token.getValue())); break; diff --git a/libqpdf/FileInputSource.cc b/libqpdf/FileInputSource.cc index 0e0cfa50..ec6e84be 100644 --- a/libqpdf/FileInputSource.cc +++ b/libqpdf/FileInputSource.cc @@ -27,8 +27,7 @@ FileInputSource::FileInputSource(char const* description, FILE* filep, bool clos FileInputSource::~FileInputSource() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer if (this->file && this->close_file) { fclose(this->file); } @@ -68,8 +67,7 @@ FileInputSource::findAndSkipNextEOL() char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2; if (p) { result = cur_offset + (p - buf); - // We found \r or \n. Keep reading until we get past - // \r and \n characters. + // We found \r or \n. Keep reading until we get past \r and \n characters. this->seek(result + 1, SEEK_SET); char ch; while (!done) { diff --git a/libqpdf/InputSource.cc b/libqpdf/InputSource.cc index 597781fe..f5dc7706 100644 --- a/libqpdf/InputSource.cc +++ b/libqpdf/InputSource.cc @@ -20,12 +20,10 @@ InputSource::getLastOffset() const std::string InputSource::readLine(size_t max_line_length) { - // Return at most max_line_length characters from the next line. - // Lines are terminated by one or more \r or \n characters. - // Consume the trailing newline characters but don't return them. - // After this is called, the file will be positioned after a line - // terminator or at the end of the file, and last_offset will - // point to position the file had when this method was called. + // Return at most max_line_length characters from the next line. Lines are terminated by one or + // more \r or \n characters. Consume the trailing newline characters but don't return them. + // After this is called, the file will be positioned after a line terminator or at the end of + // the file, and last_offset will point to position the file had when this method was called. qpdf_offset_t offset = this->tell(); auto bp = std::make_unique(max_line_length + 1); @@ -45,22 +43,18 @@ InputSource::readLine(size_t max_line_length) bool InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len, Finder& finder) { - // Basic approach: search for the first character of start_chars - // starting from offset but not going past len (if len != 0). Once - // the first character is found, see if it is the beginning of a - // sequence of characters matching start_chars. If so, call - // finder.check() to do caller-specific additional checks. If not, - // keep searching. + // Basic approach: search for the first character of start_chars starting from offset but not + // going past len (if len != 0). Once the first character is found, see if it is the beginning + // of a sequence of characters matching start_chars. If so, call finder.check() to do + // caller-specific additional checks. If not, keep searching. - // This code is tricky and highly subject to off-by-one or other - // edge case logic errors. See comments throughout that explain - // how we're not missing any edge cases. There are also tests - // specifically constructed to make sure we caught the edge cases - // in testing. + // This code is tricky and highly subject to off-by-one or other edge case logic errors. See + // comments throughout that explain how we're not missing any edge cases. There are also tests + // specifically constructed to make sure we caught the edge cases in testing. char buf[1025]; // size known to input_source.cc in libtests - // To enable us to guarantee null-termination, save an extra byte - // so that buf[size] is valid memory. + // To enable us to guarantee null-termination, save an extra byte so that buf[size] is valid + // memory. size_t size = sizeof(buf) - 1; if ((strlen(start_chars) < 1) || (strlen(start_chars) > size)) { throw std::logic_error("InputSource::findSource called with" @@ -71,19 +65,15 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len qpdf_offset_t buf_offset = offset; size_t bytes_read = 0; - // Guarantee that we return from this loop. Each time through, we - // either return, advance p, or restart the loop with a condition - // that will cause return on the next pass. Eventually we will - // either be out of range or hit EOF, either of which forces us to - // return. + // Guarantee that we return from this loop. Each time through, we either return, advance p, or + // restart the loop with a condition that will cause return on the next pass. Eventually we will + // either be out of range or hit EOF, either of which forces us to return. while (true) { - // Do we need to read more data? Pretend size = 5, buf starts - // at 0, and start_chars has 3 characters. buf[5] is valid and - // null. If p == 2, start_chars could be buf[2] through - // buf[4], so p + strlen(start_chars) == buf + size is okay. - // If p points to buf[size], since strlen(start_chars) is - // always >= 1, this overflow test will be correct for that - // case regardless of start_chars. + // Do we need to read more data? Pretend size = 5, buf starts at 0, and start_chars has 3 + // characters. buf[5] is valid and null. If p == 2, start_chars could be buf[2] through + // buf[4], so p + strlen(start_chars) == buf + size is okay. If p points to buf[size], since + // strlen(start_chars) is always >= 1, this overflow test will be correct for that case + // regardless of start_chars. if ((p == nullptr) || ((p + strlen(start_chars)) > (buf + bytes_read))) { if (p) { QTC::TC( @@ -91,9 +81,8 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len buf_offset += (p - buf); } this->seek(buf_offset, SEEK_SET); - // Read into buffer and zero out the rest of the buffer - // including buf[size]. We allocated an extra byte so that - // we could guarantee null termination as an extra + // Read into buffer and zero out the rest of the buffer including buf[size]. We + // allocated an extra byte so that we could guarantee null termination as an extra // protection against overrun when using string functions. bytes_read = this->read(buf, size); if (bytes_read < strlen(start_chars)) { @@ -122,19 +111,16 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len } } if ((p + strlen(start_chars)) > (buf + bytes_read)) { - // If there are not enough bytes left in the file for - // start_chars, we will detect this on the next pass - // as EOF and return. + // If there are not enough bytes left in the file for start_chars, we will detect + // this on the next pass as EOF and return. QTC::TC("libtests", "InputSource not enough bytes"); continue; } - // See if p points to a sequence matching start_chars. We - // already checked above to make sure we are not going to - // overrun memory. + // See if p points to a sequence matching start_chars. We already checked above to make + // sure we are not going to overrun memory. if (strncmp(p, start_chars, strlen(start_chars)) == 0) { - // Call finder.check() with the input source - // positioned to the point of the match. + // Call finder.check() with the input source positioned to the point of the match. this->seek(buf_offset + (p - buf), SEEK_SET); if (finder.check()) { return true; @@ -144,8 +130,8 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len } else { QTC::TC("libtests", "InputSource first char matched but not string"); } - // This occurrence of the first character wasn't a match. - // Skip over it and keep searching. + // This occurrence of the first character wasn't a match. Skip over it and keep + // searching. ++p; } else { // Trigger reading the next block diff --git a/libqpdf/InsecureRandomDataProvider.cc b/libqpdf/InsecureRandomDataProvider.cc index 5f247167..1c7fb9ef 100644 --- a/libqpdf/InsecureRandomDataProvider.cc +++ b/libqpdf/InsecureRandomDataProvider.cc @@ -21,9 +21,8 @@ long InsecureRandomDataProvider::random() { if (!this->seeded_random) { - // Seed the random number generator with something simple, but - // just to be interesting, don't use the unmodified current - // time. It would be better if this were a more secure seed. + // Seed the random number generator with something simple, but just to be interesting, don't + // use the unmodified current time. It would be better if this were a more secure seed. auto seed = static_cast(QUtil::get_current_time() ^ 0xcccc); #ifdef HAVE_RANDOM ::srandom(seed); diff --git a/libqpdf/JSONHandler.cc b/libqpdf/JSONHandler.cc index f4360a2d..b5c7c35d 100644 --- a/libqpdf/JSONHandler.cc +++ b/libqpdf/JSONHandler.cc @@ -133,12 +133,10 @@ JSONHandler::handle(std::string const& path, JSON j) } if (!handled) { - // It would be nice to include information about what type the - // object was and what types were allowed, but we're relying - // on schema validation to make sure input is properly - // structured before calling the handlers. It would be - // different if this code were trying to be part of a - // general-purpose JSON package. + // It would be nice to include information about what type the object was and what types + // were allowed, but we're relying on schema validation to make sure input is properly + // structured before calling the handlers. It would be different if this code were trying to + // be part of a general-purpose JSON package. QTC::TC("libtests", "JSONHandler unhandled value"); usage("JSON handler: value at " + path + " is not of expected type"); } diff --git a/libqpdf/MD5.cc b/libqpdf/MD5.cc index c0782124..b8e07cf9 100644 --- a/libqpdf/MD5.cc +++ b/libqpdf/MD5.cc @@ -78,8 +78,7 @@ MD5::encodeFile(char const* filename, qpdf_offset_t up_to_offset) } } while (len > 0); if (ferror(file)) { - // Assume, perhaps incorrectly, that errno was set by the - // underlying call to read.... + // Assume, perhaps incorrectly, that errno was set by the underlying call to read.... (void)fclose(file); QUtil::throw_system_error(std::string("MD5: read error on ") + filename); } diff --git a/libqpdf/NNTree.cc b/libqpdf/NNTree.cc index bbdd83f8..129c8734 100644 --- a/libqpdf/NNTree.cc +++ b/libqpdf/NNTree.cc @@ -36,23 +36,18 @@ NNTreeIterator::NNTreeIterator(NNTreeImpl& impl) : void NNTreeIterator::updateIValue(bool allow_invalid) { - // ivalue should never be used inside the class since we return a - // pointer/reference to it. Every bit of code that ever changes - // what object the iterator points to should take care to call - // updateIValue. Failure to do this means that any old references - // to *iter will point to incorrect objects, though the next - // dereference of the iterator will fix it. This isn't necessarily - // catastrophic, but it would be confusing. The test suite - // attempts to exercise various cases to ensure we don't introduce - // that bug in the future, but sadly it's tricky to verify by - // reasoning about the code that this constraint is always - // satisfied. Whenever we update what the iterator points to, we - // should call setItemNumber, which calls this. If we change what - // the iterator in some other way, such as replacing a value or - // removing an item and making the iterator point at a different - // item in potentially the same position, we must call - // updateIValue as well. These cases are handled, and for good - // measure, we also call updateIValue in operator* and operator->. + // ivalue should never be used inside the class since we return a pointer/reference to it. Every + // bit of code that ever changes what object the iterator points to should take care to call + // updateIValue. Failure to do this means that any old references to *iter will point to + // incorrect objects, though the next dereference of the iterator will fix it. This isn't + // necessarily catastrophic, but it would be confusing. The test suite attempts to exercise + // various cases to ensure we don't introduce that bug in the future, but sadly it's tricky to + // verify by reasoning about the code that this constraint is always satisfied. Whenever we + // update what the iterator points to, we should call setItemNumber, which calls this. If we + // change what the iterator in some other way, such as replacing a value or removing an item and + // making the iterator point at a different item in potentially the same position, we must call + // updateIValue as well. These cases are handled, and for good measure, we also call + // updateIValue in operator* and operator->. bool okay = false; if ((item_number >= 0) && this->node.isDictionary()) { @@ -228,12 +223,11 @@ NNTreeIterator::resetLimits(QPDFObjectHandle node, std::list::itera void NNTreeIterator::split(QPDFObjectHandle to_split, std::list::iterator parent) { - // Split some node along the path to the item pointed to by this - // iterator, and adjust the iterator so it points to the same - // item. + // Split some node along the path to the item pointed to by this iterator, and adjust the + // iterator so it points to the same item. - // In examples, for simplicity, /Nums is show to just contain - // numbers instead of pairs. Imagine this tree: + // In examples, for simplicity, /Nums is show to just contain numbers instead of pairs. Imagine + // this tree: // // root: << /Kids [ A B C D ] >> // A: << /Nums [ 1 2 3 4 ] >> @@ -260,8 +254,7 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list::iterato throw std::logic_error("NNTreeIterator::split called an invalid iterator"); } - // Find the array we actually need to split, which is either this - // node's kids or items. + // Find the array we actually need to split, which is either this node's kids or items. auto kids = to_split.getKey("/Kids"); int nkids = kids.isArray() ? kids.getArrayNItems() : 0; auto items = to_split.getKey(impl.details.itemsKey()); @@ -294,30 +287,22 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list::iterato bool is_root = (parent == this->path.end()); bool is_leaf = (nitems > 0); - // CURRENT STATE: tree is in original state; iterator is valid and - // unchanged. + // CURRENT STATE: tree is in original state; iterator is valid and unchanged. if (is_root) { - // What we want to do is to create a new node for the second - // half of the items and put it in the parent's /Kids array - // right after the element that points to the current to_split - // node, but if we're splitting root, there is no parent, so - // handle that first. + // What we want to do is to create a new node for the second half of the items and put it in + // the parent's /Kids array right after the element that points to the current to_split + // node, but if we're splitting root, there is no parent, so handle that first. - // In the non-root case, parent points to the path element - // whose /Kids contains the first half node, and the first - // half node is to_split. If we are splitting the root, we - // need to push everything down a level, but we want to keep - // the actual root object the same so that indirect references - // to it remain intact (and also in case it might be a direct - // object, which it shouldn't be but that case probably exists - // in the wild). To achieve this, we create a new node for the - // first half and then replace /Kids in the root to contain - // it. Then we adjust the path so that the first element is - // root and the second element, if any, is the new first half. - // In this way, we make the root case identical to the - // non-root case so remaining logic can handle them in the - // same way. + // In the non-root case, parent points to the path element whose /Kids contains the first + // half node, and the first half node is to_split. If we are splitting the root, we need to + // push everything down a level, but we want to keep the actual root object the same so that + // indirect references to it remain intact (and also in case it might be a direct object, + // which it shouldn't be but that case probably exists in the wild). To achieve this, we + // create a new node for the first half and then replace /Kids in the root to contain it. + // Then we adjust the path so that the first element is root and the second element, if any, + // is the new first half. In this way, we make the root case identical to the non-root case + // so remaining logic can handle them in the same way. auto first_node = impl.qpdf.makeIndirectObject(QPDFObjectHandle::newDictionary()); first_node.replaceKey(key, first_half); @@ -339,12 +324,11 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list::iterato to_split = first_node; } - // CURRENT STATE: parent is guaranteed to be defined, and we have - // the invariants that parent[/Kids][kid_number] == to_split and - // (++parent).node == to_split. + // CURRENT STATE: parent is guaranteed to be defined, and we have the invariants that + // parent[/Kids][kid_number] == to_split and (++parent).node == to_split. - // Create a second half array, and transfer the second half of the - // items into the second half array. + // Create a second half array, and transfer the second half of the items into the second half + // array. QPDFObjectHandle second_half = QPDFObjectHandle::newArray(); int start_idx = ((n / 2) & ~1); while (first_half.getArrayNItems() > start_idx) { @@ -358,15 +342,13 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list::iterato second_node.replaceKey(key, second_half); resetLimits(second_node, parent); - // CURRENT STATE: half the items from the kids or items array in - // the node being split have been moved into a new node. The new - // node is not yet attached to the tree. The iterator may have a + // CURRENT STATE: half the items from the kids or items array in the node being split have been + // moved into a new node. The new node is not yet attached to the tree. The iterator may have a // path element or leaf node that is out of bounds. - // We need to adjust the parent to add the second node to /Kids - // and, if needed, update kid_number to traverse through it. We - // need to update to_split's path element, or the node if this is - // a leaf, so that the kid/item number points to the right place. + // We need to adjust the parent to add the second node to /Kids and, if needed, update + // kid_number to traverse through it. We need to update to_split's path element, or the node if + // this is a leaf, so that the kid/item number points to the right place. auto parent_kids = parent->node.getKey("/Kids"); parent_kids.insertItem(parent->kid_number + 1, second_node); @@ -430,8 +412,7 @@ NNTreeIterator::insertAfter(QPDFObjectHandle key, QPDFObjectHandle value) void NNTreeIterator::remove() { - // Remove this item, leaving the tree valid and this iterator - // pointing to the next item. + // Remove this item, leaving the tree valid and this iterator pointing to the next item. if (!valid()) { throw std::logic_error("attempt made to remove an invalid iterator"); @@ -450,34 +431,32 @@ NNTreeIterator::remove() // There are still items left if ((this->item_number == 0) || (this->item_number == nitems)) { - // We removed either the first or last item of an items array - // that remains non-empty, so we have to adjust limits. + // We removed either the first or last item of an items array that remains non-empty, so + // we have to adjust limits. QTC::TC("qpdf", "NNTree remove reset limits"); resetLimits(this->node, lastPathElement()); } if (this->item_number == nitems) { - // We removed the last item of a non-empty items array, so - // advance to the successor of the previous item. + // We removed the last item of a non-empty items array, so advance to the successor of + // the previous item. QTC::TC("qpdf", "NNTree erased last item"); this->item_number -= 2; increment(false); } else if (this->item_number < nitems) { - // We don't have to do anything since the removed item's - // successor now occupies its former location. + // We don't have to do anything since the removed item's successor now occupies its + // former location. QTC::TC("qpdf", "NNTree erased non-last item"); updateIValue(); } else { - // We already checked to ensure this condition would not - // happen. + // We already checked to ensure this condition would not happen. throw std::logic_error("NNTreeIterator::remove: item_number > nitems after erase"); } return; } if (this->path.empty()) { - // Special case: if this is the root node, we can leave it - // empty. + // Special case: if this is the root node, we can leave it empty. QTC::TC("qpdf", "NNTree erased all items on leaf/root"); setItemNumber(impl.oh, -1); return; @@ -485,9 +464,8 @@ NNTreeIterator::remove() QTC::TC("qpdf", "NNTree items is empty after remove"); - // We removed the last item from this items array, so we need to - // remove this node from the parent on up the tree. Then we need - // to position ourselves at the removed item's successor. + // We removed the last item from this items array, so we need to remove this node from the + // parent on up the tree. Then we need to position ourselves at the removed item's successor. bool done = false; while (!done) { auto element = lastPathElement(); @@ -503,8 +481,7 @@ NNTreeIterator::remove() resetLimits(element->node, parent); } if (element->kid_number == nkids) { - // Move to the successor of the last child of the - // previous kid. + // Move to the successor of the last child of the previous kid. setItemNumber(QPDFObjectHandle(), -1); --element->kid_number; deepen(kids.getArrayItem(element->kid_number), false, true); @@ -523,8 +500,7 @@ NNTreeIterator::remove() } done = true; } else if (parent == this->path.end()) { - // We erased the very last item. Convert the root to an - // empty items array. + // We erased the very last item. Convert the root to an empty items array. QTC::TC("qpdf", "NNTree non-flat tree is empty after remove"); element->node.removeKey("/Kids"); element->node.replaceKey(impl.details.itemsKey(), QPDFObjectHandle::newArray()); @@ -608,9 +584,8 @@ NNTreeIterator::addPathElement(QPDFObjectHandle const& node, int kid_number) bool NNTreeIterator::deepen(QPDFObjectHandle node, bool first, bool allow_empty) { - // Starting at this node, descend through the first or last kid - // until we reach a node with items. If we succeed, return true; - // otherwise return false and leave path alone. + // Starting at this node, descend through the first or last kid until we reach a node with + // items. If we succeed, return true; otherwise return false and leave path alone. auto opath = this->path; bool failed = false; diff --git a/libqpdf/Pl_AES_PDF.cc b/libqpdf/Pl_AES_PDF.cc index a71052a5..e1a3ea33 100644 --- a/libqpdf/Pl_AES_PDF.cc +++ b/libqpdf/Pl_AES_PDF.cc @@ -98,9 +98,8 @@ Pl_AES_PDF::finish() flush(false); } if (!this->disable_padding) { - // Pad as described in section 3.5.1 of version 1.7 of the PDF - // specification, including providing an entire block of padding - // if the input was a multiple of 16 bytes. + // Pad as described in section 3.5.1 of version 1.7 of the PDF specification, including + // providing an entire block of padding if the input was a multiple of 16 bytes. unsigned char pad = QIntC::to_uchar(this->buf_size - this->offset); memset(this->inbuf + this->offset, pad, pad); this->offset = this->buf_size; @@ -108,11 +107,9 @@ Pl_AES_PDF::finish() } } else { if (this->offset != this->buf_size) { - // This is never supposed to happen as the output is - // always supposed to be padded. However, we have - // encountered files for which the output is not a - // multiple of the block size. In this case, pad with - // zeroes and hope for the best. + // This is never supposed to happen as the output is always supposed to be padded. + // However, we have encountered files for which the output is not a multiple of the + // block size. In this case, pad with zeroes and hope for the best. if (this->offset >= this->buf_size) { throw std::logic_error("buffer overflow in AES encryption" " pipeline"); @@ -156,19 +153,19 @@ Pl_AES_PDF::flush(bool strip_padding) bool return_after_init = false; if (this->cbc_mode) { if (encrypt) { - // Set cbc_block to the initialization vector, and if - // not zero, write it to the output stream. + // Set cbc_block to the initialization vector, and if not zero, write it to the + // output stream. initializeVector(); if (!(this->use_zero_iv || this->use_specified_iv)) { getNext()->write(this->cbc_block, this->buf_size); } } else if (this->use_zero_iv || this->use_specified_iv) { - // Initialize vector with zeroes; zero vector was not - // written to the beginning of the input file. + // Initialize vector with zeroes; zero vector was not written to the beginning of + // the input file. initializeVector(); } else { - // Take the first block of input as the initialization - // vector. There's nothing to write at this time. + // Take the first block of input as the initialization vector. There's nothing to + // write at this time. memcpy(this->cbc_block, this->inbuf, this->buf_size); this->offset = 0; return_after_init = true; diff --git a/libqpdf/Pl_ASCII85Decoder.cc b/libqpdf/Pl_ASCII85Decoder.cc index e789a753..fd36722a 100644 --- a/libqpdf/Pl_ASCII85Decoder.cc +++ b/libqpdf/Pl_ASCII85Decoder.cc @@ -91,8 +91,7 @@ Pl_ASCII85Decoder::flush() } QTC::TC("libtests", "Pl_ASCII85Decoder partial flush", (this->pos == 5) ? 0 : 1); - // Reset before calling getNext()->write in case that throws an - // exception. + // Reset before calling getNext()->write in case that throws an exception. auto t = this->pos - 1; this->pos = 0; memset(this->inbuf, 117, 5); diff --git a/libqpdf/Pl_ASCIIHexDecoder.cc b/libqpdf/Pl_ASCIIHexDecoder.cc index 313d8fed..7cc57a70 100644 --- a/libqpdf/Pl_ASCIIHexDecoder.cc +++ b/libqpdf/Pl_ASCIIHexDecoder.cc @@ -79,8 +79,7 @@ Pl_ASCIIHexDecoder::flush() auto ch = static_cast((b[0] << 4) + b[1]); QTC::TC("libtests", "Pl_ASCIIHexDecoder partial flush", (this->pos == 2) ? 0 : 1); - // Reset before calling getNext()->write in case that throws an - // exception. + // Reset before calling getNext()->write in case that throws an exception. this->pos = 0; this->inbuf[0] = '0'; this->inbuf[1] = '0'; diff --git a/libqpdf/Pl_Concatenate.cc b/libqpdf/Pl_Concatenate.cc index ecb20a44..8f974c05 100644 --- a/libqpdf/Pl_Concatenate.cc +++ b/libqpdf/Pl_Concatenate.cc @@ -7,8 +7,7 @@ Pl_Concatenate::Pl_Concatenate(char const* identifier, Pipeline* next) : Pl_Concatenate::~Pl_Concatenate() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_Count.cc b/libqpdf/Pl_Count.cc index cb458f0c..07bb2654 100644 --- a/libqpdf/Pl_Count.cc +++ b/libqpdf/Pl_Count.cc @@ -16,8 +16,7 @@ Pl_Count::Pl_Count(char const* identifier, Pipeline* next) : Pl_Count::~Pl_Count() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_DCT.cc b/libqpdf/Pl_DCT.cc index 5634e022..f82fc2aa 100644 --- a/libqpdf/Pl_DCT.cc +++ b/libqpdf/Pl_DCT.cc @@ -77,8 +77,7 @@ Pl_DCT::Pl_DCT( Pl_DCT::~Pl_DCT() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void @@ -92,14 +91,12 @@ Pl_DCT::finish() { m->buf.finish(); - // Using a std::shared_ptr here and passing it into compress - // and decompress causes a memory leak with setjmp/longjmp. Just - // use a pointer and delete it. + // Using a std::shared_ptr here and passing it into compress and decompress causes a + // memory leak with setjmp/longjmp. Just use a pointer and delete it. Buffer* b = m->buf.getBuffer(); if (b->getSize() == 0) { - // Special case: empty data will never succeed and probably - // means we're calling finish a second time from an exception - // handler. + // Special case: empty data will never succeed and probably means we're calling finish a + // second time from an exception handler. delete b; this->getNext()->finish(); return; @@ -114,8 +111,7 @@ Pl_DCT::finish() jerr.pub.error_exit = error_handler; bool error = false; - // The jpeg library is a "C" library, so we use setjmp and longjmp - // for exception handling. + // The jpeg library is a "C" library, so we use setjmp and longjmp for exception handling. if (setjmp(jerr.jmpbuf) == 0) { try { if (m->action == a_compress) { @@ -124,9 +120,8 @@ Pl_DCT::finish() decompress(reinterpret_cast(&cinfo_decompress), b); } } catch (std::exception& e) { - // Convert an exception back to a longjmp so we can ensure - // that the right cleanup happens. This will get converted - // back to an exception. + // Convert an exception back to a longjmp so we can ensure that the right cleanup + // happens. This will get converted back to an exception. jerr.msg = e.what(); longjmp(jerr.jmpbuf, 1); } @@ -205,9 +200,8 @@ init_buffer_source(j_decompress_ptr) static boolean fill_buffer_input_buffer(j_decompress_ptr) { - // The whole JPEG data is expected to reside in the supplied memory - // buffer, so any request for more data beyond the given buffer size - // is treated as an error. + // The whole JPEG data is expected to reside in the supplied memory buffer, so any request for + // more data beyond the given buffer size is treated as an error. throw std::runtime_error("invalid jpeg data reading from buffer"); return TRUE; } @@ -216,8 +210,8 @@ static void skip_buffer_input_data(j_decompress_ptr cinfo, long num_bytes) { if (num_bytes < 0) { - throw std::runtime_error("reading jpeg: jpeg library requested" - " skipping a negative number of bytes"); + throw std::runtime_error( + "reading jpeg: jpeg library requested skipping a negative number of bytes"); } size_t to_skip = QIntC::to_size(num_bytes); if ((to_skip > 0) && (to_skip <= cinfo->src->bytes_in_buffer)) { diff --git a/libqpdf/Pl_Discard.cc b/libqpdf/Pl_Discard.cc index f1078e3a..d9ddaef3 100644 --- a/libqpdf/Pl_Discard.cc +++ b/libqpdf/Pl_Discard.cc @@ -9,8 +9,7 @@ Pl_Discard::Pl_Discard() : Pl_Discard::~Pl_Discard() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_Flate.cc b/libqpdf/Pl_Flate.cc index c3e4a9f5..f43c0b7f 100644 --- a/libqpdf/Pl_Flate.cc +++ b/libqpdf/Pl_Flate.cc @@ -16,16 +16,14 @@ Pl_Flate::Members::Members(size_t out_bufsize, action_e action) : zdata(nullptr) { this->outbuf = QUtil::make_shared_array(out_bufsize); - // Indirect through zdata to reach the z_stream so we don't have - // to include zlib.h in Pl_Flate.hh. This means people using - // shared library versions of qpdf don't have to have zlib - // development files available, which particularly helps in a - // Windows environment. + // Indirect through zdata to reach the z_stream so we don't have to include zlib.h in + // Pl_Flate.hh. This means people using shared library versions of qpdf don't have to have zlib + // development files available, which particularly helps in a Windows environment. this->zdata = new z_stream; if (out_bufsize > UINT_MAX) { - throw std::runtime_error("Pl_Flate: zlib doesn't support buffer" - " sizes larger than unsigned int"); + throw std::runtime_error( + "Pl_Flate: zlib doesn't support buffer sizes larger than unsigned int"); } z_stream& zstream = *(static_cast(this->zdata)); @@ -62,8 +60,7 @@ Pl_Flate::Pl_Flate( Pl_Flate::~Pl_Flate() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void @@ -88,8 +85,7 @@ Pl_Flate::write(unsigned char const* data, size_t len) this->identifier + ": Pl_Flate: write() called after finish() called"); } - // Write in chunks in case len is too big to fit in an int. - // Assume int is at least 32 bits. + // Write in chunks in case len is too big to fit in an int. Assume int is at least 32 bits. static size_t const max_bytes = 1 << 30; size_t bytes_left = len; unsigned char const* buf = data; @@ -105,20 +101,18 @@ void Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) { if (len > UINT_MAX) { - throw std::runtime_error("Pl_Flate: zlib doesn't support data" - " blocks larger than int"); + throw std::runtime_error("Pl_Flate: zlib doesn't support data blocks larger than int"); } z_stream& zstream = *(static_cast(m->zdata)); - // zlib is known not to modify the data pointed to by next_in but - // doesn't declare the field value const unless compiled to do so. + // zlib is known not to modify the data pointed to by next_in but doesn't declare the field + // value const unless compiled to do so. zstream.next_in = const_cast(data); zstream.avail_in = QIntC::to_uint(len); if (!m->initialized) { int err = Z_OK; - // deflateInit and inflateInit are macros that use old-style - // casts. + // deflateInit and inflateInit are macros that use old-style casts. #if ((defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406) || defined(__clang__)) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wold-style-cast" @@ -147,21 +141,18 @@ Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) } if ((m->action == a_inflate) && (err != Z_OK) && zstream.msg && (strcmp(zstream.msg, "incorrect data check") == 0)) { - // Other PDF readers ignore this specific error. Combining - // this with Z_SYNC_FLUSH enables qpdf to handle some - // broken zlib streams without losing data. + // Other PDF readers ignore this specific error. Combining this with Z_SYNC_FLUSH + // enables qpdf to handle some broken zlib streams without losing data. err = Z_STREAM_END; } switch (err) { case Z_BUF_ERROR: - // Probably shouldn't be able to happen, but possible as a - // boundary condition: if the last call to inflate exactly - // filled the output buffer, it's possible that the next - // call to inflate could have nothing to do. There are PDF - // files in the wild that have this error (including at - // least one in qpdf's test suite). In some cases, we want - // to know about this, because it indicates incorrect - // compression, so call a callback if provided. + // Probably shouldn't be able to happen, but possible as a boundary condition: if the + // last call to inflate exactly filled the output buffer, it's possible that the next + // call to inflate could have nothing to do. There are PDF files in the wild that have + // this error (including at least one in qpdf's test suite). In some cases, we want to + // know about this, because it indicates incorrect compression, so call a callback if + // provided. this->warn("input stream is complete but output may still be valid", err); done = true; break; @@ -173,9 +164,8 @@ Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) case Z_OK: { if ((zstream.avail_in == 0) && (zstream.avail_out > 0)) { - // There is nothing left to read, and there was - // sufficient buffer space to write everything we - // needed, so we're done for now. + // There is nothing left to read, and there was sufficient buffer space to write + // everything we needed, so we're done for now. done = true; } uLong ready = QIntC::to_ulong(m->out_bufsize - zstream.avail_out); diff --git a/libqpdf/Pl_Function.cc b/libqpdf/Pl_Function.cc index 2cb22926..c75df2a4 100644 --- a/libqpdf/Pl_Function.cc +++ b/libqpdf/Pl_Function.cc @@ -41,8 +41,7 @@ Pl_Function::Pl_Function(char const* identifier, Pipeline* next, writer_c_char_t Pl_Function::~Pl_Function() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_LZWDecoder.cc b/libqpdf/Pl_LZWDecoder.cc index 8e5fd9d1..4ffcaa3f 100644 --- a/libqpdf/Pl_LZWDecoder.cc +++ b/libqpdf/Pl_LZWDecoder.cc @@ -149,9 +149,8 @@ Pl_LZWDecoder::handleCode(unsigned int code) this->eod = true; } else { if (this->last_code != 256) { - // Add to the table from last time. New table entry would - // be what we read last plus the first character of what - // we're reading now. + // Add to the table from last time. New table entry would be what we read last plus the + // first character of what we're reading now. unsigned char next = '\0'; unsigned int table_size = QIntC::to_uint(table.size()); if (code < 256) { @@ -162,10 +161,8 @@ Pl_LZWDecoder::handleCode(unsigned int code) if (idx > table_size) { throw std::runtime_error("LZWDecoder: bad code received"); } else if (idx == table_size) { - // The encoder would have just created this entry, - // so the first character of this entry would have - // been the same as the first character of the - // last entry. + // The encoder would have just created this entry, so the first character of + // this entry would have been the same as the first character of the last entry. QTC::TC("libtests", "Pl_LZWDecoder last was table size"); next = getFirstChar(this->last_code); } else { diff --git a/libqpdf/Pl_MD5.cc b/libqpdf/Pl_MD5.cc index c0714839..8d45f17a 100644 --- a/libqpdf/Pl_MD5.cc +++ b/libqpdf/Pl_MD5.cc @@ -19,8 +19,7 @@ Pl_MD5::write(unsigned char const* buf, size_t len) this->in_progress = true; } - // Write in chunks in case len is too big to fit in an int. - // Assume int is at least 32 bits. + // Write in chunks in case len is too big to fit in an int. Assume int is at least 32 bits. static size_t const max_bytes = 1 << 30; size_t bytes_left = len; unsigned char const* data = buf; diff --git a/libqpdf/Pl_OStream.cc b/libqpdf/Pl_OStream.cc index 28a08bdc..73fbad21 100644 --- a/libqpdf/Pl_OStream.cc +++ b/libqpdf/Pl_OStream.cc @@ -15,8 +15,7 @@ Pl_OStream::Pl_OStream(char const* identifier, std::ostream& os) : Pl_OStream::~Pl_OStream() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_PNGFilter.cc b/libqpdf/Pl_PNGFilter.cc index b9e297d7..4c2dd623 100644 --- a/libqpdf/Pl_PNGFilter.cc +++ b/libqpdf/Pl_PNGFilter.cc @@ -33,8 +33,8 @@ Pl_PNGFilter::Pl_PNGFilter( } if (!((bits_per_sample == 1) || (bits_per_sample == 2) || (bits_per_sample == 4) || (bits_per_sample == 8) || (bits_per_sample == 16))) { - throw std::runtime_error("PNGFilter created with invalid bits_per_sample not" - " 1, 2, 4, 8, or 16"); + throw std::runtime_error( + "PNGFilter created with invalid bits_per_sample not 1, 2, 4, 8, or 16"); } this->bytes_per_pixel = ((bits_per_sample * samples_per_pixel) + 7) / 8; unsigned long long bpr = ((columns * bits_per_sample * samples_per_pixel) + 7) / 8; diff --git a/libqpdf/Pl_QPDFTokenizer.cc b/libqpdf/Pl_QPDFTokenizer.cc index f2612e85..576c2bfb 100644 --- a/libqpdf/Pl_QPDFTokenizer.cc +++ b/libqpdf/Pl_QPDFTokenizer.cc @@ -23,8 +23,7 @@ Pl_QPDFTokenizer::Pl_QPDFTokenizer( Pl_QPDFTokenizer::~Pl_QPDFTokenizer() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_RunLength.cc b/libqpdf/Pl_RunLength.cc index d9e6799a..d1a5e318 100644 --- a/libqpdf/Pl_RunLength.cc +++ b/libqpdf/Pl_RunLength.cc @@ -18,8 +18,7 @@ Pl_RunLength::Pl_RunLength(char const* identifier, Pipeline* next, action_e acti Pl_RunLength::~Pl_RunLength() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void @@ -135,10 +134,9 @@ Pl_RunLength::flush_encode() void Pl_RunLength::finish() { - // When decoding, we might have read a length byte not followed by - // data, which means the stream was terminated early, but we will - // just ignore this case since this is the only sensible thing to - // do. + // When decoding, we might have read a length byte not followed by data, which means the stream + // was terminated early, but we will just ignore this case since this is the only sensible thing + // to do. if (m->action == a_encode) { flush_encode(); unsigned char ch = 128; diff --git a/libqpdf/Pl_SHA2.cc b/libqpdf/Pl_SHA2.cc index f431ff7d..04ef924c 100644 --- a/libqpdf/Pl_SHA2.cc +++ b/libqpdf/Pl_SHA2.cc @@ -20,8 +20,7 @@ Pl_SHA2::write(unsigned char const* buf, size_t len) this->in_progress = true; } - // Write in chunks in case len is too big to fit in an int. - // Assume int is at least 32 bits. + // Write in chunks in case len is too big to fit in an int. Assume int is at least 32 bits. static size_t const max_bytes = 1 << 30; size_t bytes_left = len; unsigned char const* data = buf; diff --git a/libqpdf/Pl_StdioFile.cc b/libqpdf/Pl_StdioFile.cc index 918aacde..a95d4898 100644 --- a/libqpdf/Pl_StdioFile.cc +++ b/libqpdf/Pl_StdioFile.cc @@ -19,8 +19,7 @@ Pl_StdioFile::Pl_StdioFile(char const* identifier, FILE* f) : Pl_StdioFile::~Pl_StdioFile() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_String.cc b/libqpdf/Pl_String.cc index 0bee11b3..40c4b56f 100644 --- a/libqpdf/Pl_String.cc +++ b/libqpdf/Pl_String.cc @@ -15,8 +15,7 @@ Pl_String::Pl_String(char const* identifier, Pipeline* next, std::string& s) : Pl_String::~Pl_String() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 64ff4715..6f718742 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -106,9 +106,8 @@ namespace throwException() { throw std::logic_error("QPDF operation attempted on a QPDF object with no input " - "source." - " QPDF operations are invalid before processFile (or another" - " process method) or after closeInputSource"); + "source. QPDF operations are invalid before processFile (or " + "another process method) or after closeInputSource"); } }; } // namespace diff --git a/libqpdf/QPDFAnnotationObjectHelper.cc b/libqpdf/QPDFAnnotationObjectHelper.cc index 81ea5a7f..b967a5b3 100644 --- a/libqpdf/QPDFAnnotationObjectHelper.cc +++ b/libqpdf/QPDFAnnotationObjectHelper.cc @@ -54,13 +54,10 @@ QPDFAnnotationObjectHelper::getAppearanceStream(std::string const& which, std::s if (ap.isDictionary()) { QPDFObjectHandle ap_sub = ap.getKey(which); if (ap_sub.isStream()) { - // According to the spec, Appearance State is supposed to - // refer to a subkey of the appearance stream when /AP is - // a dictionary, but files have been seen in the wild - // where Appearance State is `/N` and `/AP` is a stream. - // Therefore, if `which` points to a stream, disregard - // state and just use the stream. See qpdf issue #949 for - // details. + // According to the spec, Appearance State is supposed to refer to a subkey of the + // appearance stream when /AP is a dictionary, but files have been seen in the wild + // where Appearance State is `/N` and `/AP` is a stream. Therefore, if `which` points to + // a stream, disregard state and just use the stream. See qpdf issue #949 for details. QTC::TC("qpdf", "QPDFAnnotationObjectHelper AP stream"); return ap_sub; } @@ -85,84 +82,66 @@ QPDFAnnotationObjectHelper::getPageContentForAppearance( return ""; } - // The appearance matrix computed by this method is the - // transformation matrix that needs to be in effect when drawing - // this annotation's appearance stream on the page. The algorithm - // for computing the appearance matrix described in section 12.5.5 - // of the ISO-32000 PDF spec is similar but not identical to what - // we are doing here. + // The appearance matrix computed by this method is the transformation matrix that needs to be + // in effect when drawing this annotation's appearance stream on the page. The algorithm for + // computing the appearance matrix described in section 12.5.5 of the ISO-32000 PDF spec is + // similar but not identical to what we are doing here. - // When rendering an appearance stream associated with an - // annotation, there are four relevant components: + // When rendering an appearance stream associated with an annotation, there are four relevant + // components: // // * The appearance stream's bounding box (/BBox) // * The appearance stream's matrix (/Matrix) // * The annotation's rectangle (/Rect) - // * In the case of form fields with the NoRotate flag, the - // page's rotation + // * In the case of form fields with the NoRotate flag, the page's rotation - // When rendering a form xobject in isolation, just drawn with a - // /Do operator, there is no form field, so page rotation is not - // relevant, and there is no annotation, so /Rect is not relevant, - // so only /BBox and /Matrix are relevant. The effect of these are - // as follows: + // When rendering a form xobject in isolation, just drawn with a /Do operator, there is no form + // field, so page rotation is not relevant, and there is no annotation, so /Rect is not + // relevant, so only /BBox and /Matrix are relevant. The effect of these are as follows: // * /BBox is treated as a clipping region - // * /Matrix is applied as a transformation prior to rendering the - // appearance stream. + // * /Matrix is applied as a transformation prior to rendering the appearance stream. - // There is no relationship between /BBox and /Matrix in this - // case. + // There is no relationship between /BBox and /Matrix in this case. - // When rendering a form xobject in the context of an annotation, - // things are a little different. In particular, a matrix is - // established such that /BBox, when transformed by /Matrix, would - // fit completely inside of /Rect. /BBox is no longer a clipping - // region. To illustrate the difference, consider a /Matrix of - // [2 0 0 2 0 0], which is scaling by a factor of two along both - // axes. If the appearance stream drew a rectangle equal to /BBox, - // in the case of the form xobject in isolation, this matrix would - // cause only the lower-left quadrant of the rectangle to be - // visible since the scaling would cause the rest of it to fall - // outside of the clipping region. In the case of the form xobject - // displayed in the context of an annotation, such a matrix would - // have no effect at all because it would be applied to the - // bounding box first, and then when the resulting enclosing - // quadrilateral was transformed to fit into /Rect, the effect of - // the scaling would be undone. + // When rendering a form xobject in the context of an annotation, things are a little different. + // In particular, a matrix is established such that /BBox, when transformed by /Matrix, would + // fit completely inside of /Rect. /BBox is no longer a clipping region. To illustrate the + // difference, consider a /Matrix of [2 0 0 2 0 0], which is scaling by a factor of two along + // both axes. If the appearance stream drew a rectangle equal to /BBox, in the case of the form + // xobject in isolation, this matrix would cause only the lower-left quadrant of the rectangle + // to be visible since the scaling would cause the rest of it to fall outside of the clipping + // region. In the case of the form xobject displayed in the context of an annotation, such a + // matrix would have no effect at all because it would be applied to the bounding box first, and + // then when the resulting enclosing quadrilateral was transformed to fit into /Rect, the effect + // of the scaling would be undone. - // Our job is to create a transformation matrix that compensates - // for these differences so that the appearance stream of an - // annotation can be drawn as a regular form xobject. + // Our job is to create a transformation matrix that compensates for these differences so that + // the appearance stream of an annotation can be drawn as a regular form xobject. - // To do this, we perform the following steps, which overlap - // significantly with the algorithm in 12.5.5: + // To do this, we perform the following steps, which overlap significantly with the algorithm + // in 12.5.5: - // 1. Transform the four corners of /BBox by applying /Matrix to - // them, creating an arbitrarily transformed quadrilateral. + // 1. Transform the four corners of /BBox by applying /Matrix to them, creating an arbitrarily + // transformed quadrilateral. - // 2. Find the minimum upright rectangle that encompasses the - // resulting quadrilateral. This is the "transformed appearance - // box", T. + // 2. Find the minimum upright rectangle that encompasses the resulting quadrilateral. This is + // the "transformed appearance box", T. - // 3. Compute matrix A that maps the lower left and upper right - // corners of T to the annotation's /Rect. This can be done by - // scaling so that the sizes match and translating so that the + // 3. Compute matrix A that maps the lower left and upper right corners of T to the annotation's + // /Rect. This can be done by scaling so that the sizes match and translating so that the // scaled T exactly overlaps /Rect. - // If the annotation's /F flag has bit 4 set, this means that - // annotation is to be rotated about its upper left corner to - // counteract any rotation of the page so it remains upright. To + // If the annotation's /F flag has bit 4 set, this means that annotation is to be rotated about + // its upper left corner to counteract any rotation of the page so it remains upright. To // achieve this effect, we do the following extra steps: - // 1. Perform the rotation on /BBox box prior to transforming it - // with /Matrix (by replacing matrix with concatenation of - // matrix onto the rotation) + // 1. Perform the rotation on /BBox box prior to transforming it with /Matrix (by replacing + // matrix with concatenation of matrix onto the rotation) // 2. Rotate the destination rectangle by the specified amount - // 3. Apply the rotation to A as computed above to get the final - // appearance matrix. + // 3. Apply the rotation to A as computed above to get the final appearance matrix. QPDFObjectHandle rect_obj = this->oh.getKey("/Rect"); QPDFObjectHandle as = getAppearanceStream("/N").getDict(); @@ -192,14 +171,12 @@ QPDFAnnotationObjectHelper::getPageContentForAppearance( QPDFObjectHandle::Rectangle rect = rect_obj.getArrayAsRectangle(); bool do_rotate = (rotate && (flags & an_no_rotate)); if (do_rotate) { - // If the the annotation flags include the NoRotate bit and - // the page is rotated, we have to rotate the annotation about - // its upper left corner by the same amount in the opposite - // direction so that it will remain upright in absolute - // coordinates. Since the semantics of /Rotate for a page are - // to rotate the page, while the effect of rotating using a - // transformation matrix is to rotate the coordinate system, - // the opposite directionality is explicit in the code. + // If the the annotation flags include the NoRotate bit and the page is rotated, we have to + // rotate the annotation about its upper left corner by the same amount in the opposite + // direction so that it will remain upright in absolute coordinates. Since the semantics of + // /Rotate for a page are to rotate the page, while the effect of rotating using a + // transformation matrix is to rotate the coordinate system, the opposite directionality is + // explicit in the code. QPDFMatrix mr; mr.rotatex90(rotate); mr.concat(matrix); diff --git a/libqpdf/QPDFArgParser.cc b/libqpdf/QPDFArgParser.cc index 7e1980ad..78e5e843 100644 --- a/libqpdf/QPDFArgParser.cc +++ b/libqpdf/QPDFArgParser.cc @@ -139,8 +139,8 @@ QPDFArgParser::addInvalidChoiceHandler(std::string const& arg, param_arg_handler auto i = m->option_table->find(arg); if (i == m->option_table->end()) { QTC::TC("libtests", "QPDFArgParser invalid choice handler to unknown"); - throw std::logic_error("QPDFArgParser: attempt to add invalid choice handler" - " to unknown argument"); + throw std::logic_error( + "QPDFArgParser: attempt to add invalid choice handler to unknown argument"); } auto& oe = i->second; oe.invalid_choice_handler = handler; @@ -231,9 +231,9 @@ QPDFArgParser::invalidHelpArg(std::string const& p) void QPDFArgParser::handleArgFileArguments() { - // Support reading arguments from files. Create a new argv. Ensure - // that argv itself as well as all its contents are automatically - // deleted by using shared pointers to back the pointers in argv. + // Support reading arguments from files. Create a new argv. Ensure that argv itself as well as + // all its contents are automatically deleted by using shared pointers to back the pointers in + // argv. m->new_argv.push_back(QUtil::make_shared_cstr(m->argv[0])); for (int i = 1; i < m->argc; ++i) { char const* argfile = nullptr; @@ -264,12 +264,10 @@ QPDFArgParser::handleArgFileArguments() void QPDFArgParser::handleBashArguments() { - // Do a minimal job of parsing bash_line into arguments. This - // doesn't do everything the shell does (e.g. $(...), variable - // expansion, arithmetic, globs, etc.), but it should be good - // enough for purposes of handling completion. As we build up the - // new argv, we can't use m->new_argv because this code has to - // interoperate with @file arguments, so memory for both ways of + // Do a minimal job of parsing bash_line into arguments. This doesn't do everything the shell + // does (e.g. $(...), variable expansion, arithmetic, globs, etc.), but it should be good enough + // for purposes of handling completion. As we build up the new argv, we can't use m->new_argv + // because this code has to interoperate with @file arguments, so memory for both ways of // fabricating argv has to be protected. bool last_was_backslash = false; @@ -321,12 +319,11 @@ QPDFArgParser::handleBashArguments() } } if (m->bash_argv.empty()) { - // This can't happen if properly invoked by bash, but ensure - // we have a valid argv[0] regardless. + // This can't happen if properly invoked by bash, but ensure we have a valid argv[0] + // regardless. m->bash_argv.push_back(QUtil::make_shared_cstr(m->argv[0])); } - // Explicitly discard any non-space-terminated word. The "current - // word" is handled specially. + // Explicitly discard any non-space-terminated word. The "current word" is handled specially. m->bash_argv_ph = QUtil::make_shared_array(1 + m->bash_argv.size()); for (size_t i = 0; i < m->bash_argv.size(); ++i) { m->bash_argv_ph.get()[i] = m->bash_argv.at(i).get(); @@ -367,12 +364,10 @@ QPDFArgParser::checkCompletion() { // See if we're being invoked from bash completion. std::string bash_point_env; - // On Windows with mingw, there have been times when there appears - // to be no way to distinguish between an empty environment - // variable and an unset variable. There are also conditions under - // which bash doesn't set COMP_LINE. Therefore, enter this logic - // if either COMP_LINE or COMP_POINT are set. They will both be - // set together under ordinary circumstances. + // On Windows with mingw, there have been times when there appears to be no way to distinguish + // between an empty environment variable and an unset variable. There are also conditions under + // which bash doesn't set COMP_LINE. Therefore, enter this logic if either COMP_LINE or + // COMP_POINT are set. They will both be set together under ordinary circumstances. bool got_line = QUtil::get_env("COMP_LINE", &m->bash_line); bool got_point = QUtil::get_env("COMP_POINT", &bash_point_env); if (got_line || got_point) { @@ -385,15 +380,12 @@ QPDFArgParser::checkCompletion() if (p > m->bash_line.length()) { p = m->bash_line.length(); } - // Set bash_cur and bash_prev based on bash_line rather than - // relying on argv. This enables us to use bashcompinit to get - // completion in zsh too since bashcompinit sets COMP_LINE and - // COMP_POINT but doesn't invoke the command with options like - // bash does. + // Set bash_cur and bash_prev based on bash_line rather than relying on argv. This enables + // us to use bashcompinit to get completion in zsh too since bashcompinit sets COMP_LINE and + // COMP_POINT but doesn't invoke the command with options like bash does. - // p is equal to length of the string. Walk backwards looking - // for the first separator. bash_cur is everything after the - // last separator, possibly empty. + // p is equal to length of the string. Walk backwards looking for the first separator. + // bash_cur is everything after the last separator, possibly empty. char sep(0); while (p > 0) { --p; @@ -407,10 +399,9 @@ QPDFArgParser::checkCompletion() m->bash_cur = m->bash_line.substr(1 + p, std::string::npos); } if ((sep == ':') || (sep == '=')) { - // Bash sets prev to the non-space separator if any. - // Actually, if there are multiple separators in a row, - // they are all included in prev, but that detail is not - // important to us and not worth coding. + // Bash sets prev to the non-space separator if any. Actually, if there are multiple + // separators in a row, they are all included in prev, but that detail is not important + // to us and not worth coding. m->bash_prev = m->bash_line.substr(p, 1); } else { // Go back to the last separator and set prev based on @@ -429,8 +420,8 @@ QPDFArgParser::checkCompletion() m->bash_prev = m->bash_line.substr(0, p); } if (m->argc == 1) { - // This is probably zsh using bashcompinit. There are a - // few differences in the expected output. + // This is probably zsh using bashcompinit. There are a few differences in the expected + // output. m->zsh_completion = true; } handleBashArguments(); @@ -454,8 +445,7 @@ QPDFArgParser::parseArgs() std::string o_arg(arg); std::string arg_s(arg); if (strcmp(arg, "--") == 0) { - // Special case for -- option, which is used to break out - // of subparsers. + // Special case for -- option, which is used to break out of subparsers. oep = m->option_table->find("--"); end_option = true; if (oep == m->option_table->end()) { @@ -471,11 +461,9 @@ QPDFArgParser::parseArgs() QTC::TC("libtests", "QPDFArgParser single dash"); } - // Prevent --=something from being treated as an empty arg - // by searching for = from after the first character. We - // do this since the empty string in the option table is - // for positional arguments. Besides, it doesn't make - // sense to have an empty option. + // Prevent --=something from being treated as an empty arg by searching for = from after + // the first character. We do this since the empty string in the option table is for + // positional arguments. Besides, it doesn't make sense to have an empty option. arg_s = arg; size_t equal_pos = std::string::npos; if (arg_s.length() > 0) { @@ -489,8 +477,7 @@ QPDFArgParser::parseArgs() if ((!m->bash_completion) && (m->argc == 2) && (m->cur_arg == 1) && m->help_option_table.count(arg_s)) { - // Handle help option, which is only valid as the sole - // option. + // Handle help option, which is only valid as the sole option. QTC::TC("libtests", "QPDFArgParser help option"); oep = m->help_option_table.find(arg_s); help_option = true; @@ -500,8 +487,7 @@ QPDFArgParser::parseArgs() oep = m->option_table->find(arg_s); } } else { - // The empty string maps to the positional argument - // handler. + // The empty string maps to the positional argument handler. QTC::TC("libtests", "QPDFArgParser positional"); oep = m->option_table->find(""); parameter = arg; @@ -522,8 +508,7 @@ QPDFArgParser::parseArgs() std::string message = "--" + arg_s + " must be given as --" + arg_s + "="; if (oe.invalid_choice_handler) { oe.invalid_choice_handler(parameter); - // Method should call usage() or exit. Just in case it - // doesn't... + // Method should call usage() or exit. Just in case it doesn't... message += "option"; } else if (!oe.choices.empty()) { QTC::TC("libtests", "QPDFArgParser required choices"); @@ -609,8 +594,8 @@ QPDFArgParser::addOptionsToCompletions(option_table_t& option_table) std::string base = "--" + arg; if (oe.param_arg_handler) { if (m->zsh_completion) { - // zsh doesn't treat = as a word separator, so add all - // the options so we don't get a space after the =. + // zsh doesn't treat = as a word separator, so add all the options so we don't get a + // space after the =. addChoicesToCompletions(option_table, arg, base + "="); } m->completions.insert(base + "="); diff --git a/libqpdf/QPDFCryptoProvider.cc b/libqpdf/QPDFCryptoProvider.cc index 37f152c9..2a18a366 100644 --- a/libqpdf/QPDFCryptoProvider.cc +++ b/libqpdf/QPDFCryptoProvider.cc @@ -92,8 +92,7 @@ QPDFCryptoProvider::setDefaultProvider_internal(std::string const& name) { if (!m->providers.count(name)) { throw std::logic_error( - "QPDFCryptoProvider: request to set default" - " provider to unknown implementation \"" + + "QPDFCryptoProvider: request to set default provider to unknown implementation \"" + name + "\""); } m->default_provider = name; diff --git a/libqpdf/QPDFCrypto_gnutls.cc b/libqpdf/QPDFCrypto_gnutls.cc index c96cdfbc..ee460416 100644 --- a/libqpdf/QPDFCrypto_gnutls.cc +++ b/libqpdf/QPDFCrypto_gnutls.cc @@ -233,9 +233,8 @@ QPDFCrypto_gnutls::rijndael_process(unsigned char* in_data, unsigned char* out_d this->cipher_ctx, in_data, rijndael_buf_size, out_data, rijndael_buf_size); } - // Gnutls doesn't support AES in ECB (non-CBC) mode, but the - // result is the same as if you just reset the cbc block to all - // zeroes each time. We jump through a few hoops here to make this + // Gnutls doesn't support AES in ECB (non-CBC) mode, but the result is the same as if you just + // reset the cbc block to all zeroes each time. We jump through a few hoops here to make this // work. if (!this->cbc_mode) { static unsigned char zeroes[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/libqpdf/QPDFCrypto_openssl.cc b/libqpdf/QPDFCrypto_openssl.cc index 87591eb5..f82230be 100644 --- a/libqpdf/QPDFCrypto_openssl.cc +++ b/libqpdf/QPDFCrypto_openssl.cc @@ -83,8 +83,8 @@ static void check_openssl(int status) { if (status != 1) { - // OpenSSL creates a "queue" of errors; copy the first (innermost) - // error to the exception message. + // OpenSSL creates a "queue" of errors; copy the first (innermost) error to the exception + // message. char buf[256] = ""; ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); std::string what = "OpenSSL error: "; diff --git a/libqpdf/QPDFDocumentHelper.cc b/libqpdf/QPDFDocumentHelper.cc index ad23e6f8..cdafc5fb 100644 --- a/libqpdf/QPDFDocumentHelper.cc +++ b/libqpdf/QPDFDocumentHelper.cc @@ -2,6 +2,5 @@ QPDFDocumentHelper::~QPDFDocumentHelper() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/QPDFEFStreamObjectHelper.cc b/libqpdf/QPDFEFStreamObjectHelper.cc index a7ece6ae..b21c8981 100644 --- a/libqpdf/QPDFEFStreamObjectHelper.cc +++ b/libqpdf/QPDFEFStreamObjectHelper.cc @@ -134,8 +134,8 @@ QPDFEFStreamObjectHelper::newFromStream(QPDFObjectHandle stream) QPDFEFStreamObjectHelper result(stream); stream.getDict().replaceKey("/Type", QPDFObjectHandle::newName("/EmbeddedFile")); Pl_Discard discard; - // The PDF spec specifies use of MD5 here and notes that it is not - // to be used for security. MD5 is known to be insecure. + // The PDF spec specifies use of MD5 here and notes that it is not to be used for security. MD5 + // is known to be insecure. Pl_MD5 md5("EF md5", &discard); Pl_Count count("EF size", &md5); if (!stream.pipeStreamData(&count, nullptr, 0, qpdf_dl_all)) { diff --git a/libqpdf/QPDFEmbeddedFileDocumentHelper.cc b/libqpdf/QPDFEmbeddedFileDocumentHelper.cc index d1c7a05c..fd735e79 100644 --- a/libqpdf/QPDFEmbeddedFileDocumentHelper.cc +++ b/libqpdf/QPDFEmbeddedFileDocumentHelper.cc @@ -1,10 +1,9 @@ #include -// File attachments are stored in the /EmbeddedFiles (name tree) key -// of the /Names dictionary from the document catalog. Each entry -// points to a /FileSpec, which in turn points to one more Embedded -// File Streams. Note that file specs can appear in other places as -// well, such as file attachment annotations, among others. +// File attachments are stored in the /EmbeddedFiles (name tree) key of the /Names dictionary from +// the document catalog. Each entry points to a /FileSpec, which in turn points to one more Embedded +// File Streams. Note that file specs can appear in other places as well, such as file attachment +// annotations, among others. // // root -> /Names -> /EmbeddedFiles = name tree // filename -> filespec diff --git a/libqpdf/QPDFJob_argv.cc b/libqpdf/QPDFJob_argv.cc index 3116b097..4a9addbd 100644 --- a/libqpdf/QPDFJob_argv.cc +++ b/libqpdf/QPDFJob_argv.cc @@ -65,9 +65,9 @@ ArgParser::initOptionTables() this->ap.addFinalCheck([this]() { c_main->checkConfiguration(); }); // add_help is defined in auto_job_help.hh add_help(this->ap); - // Special case: ignore -- at the top level. This undocumented - // behavior is for backward compatibility; it was unintentionally - // the case prior to 10.6, and some users were relying on it. + // Special case: ignore -- at the top level. This undocumented behavior is for backward + // compatibility; it was unintentionally the case prior to 10.6, and some users were relying on + // it. this->ap.selectMainOptionTable(); this->ap.addBare("--", []() {}); } @@ -254,8 +254,7 @@ ArgParser::argPagesPositional(std::string const& arg) range_p = this->accumulated_args.at(1).c_str(); } - // See if the user omitted the range entirely, in which case we - // assume "1-z". + // See if the user omitted the range entirely, in which case we assume "1-z". std::string next_file; if (range_p == nullptr) { if (arg.empty()) { diff --git a/libqpdf/QPDFJob_config.cc b/libqpdf/QPDFJob_config.cc index 7c275f20..e847bcd4 100644 --- a/libqpdf/QPDFJob_config.cc +++ b/libqpdf/QPDFJob_config.cc @@ -25,18 +25,14 @@ QPDFJob::Config* QPDFJob::Config::emptyInput() { if (o.m->infilename == nullptr) { - // Various places in QPDFJob.cc know that the empty string for - // infile means empty. We set it to something other than a - // null pointer as an indication that some input source has - // been specified. This approach means that passing "" as - // the argument to inputFile in job JSON, or equivalently - // using "" as a positional command-line argument would be the - // same as --empty. This probably isn't worth blocking or - // coding around. + // Various places in QPDFJob.cc know that the empty string for infile means empty. We set it + // to something other than a null pointer as an indication that some input source has been + // specified. This approach means that passing "" as the argument to inputFile in job JSON, + // or equivalently using "" as a positional command-line argument would be the same as + // --empty. This probably isn't worth blocking or coding around. o.m->infilename = QUtil::make_shared_cstr(""); } else { - usage("empty input can't be used" - " since input file has already been given"); + usage("empty input can't be used since input file has already been given"); } return this; } @@ -58,8 +54,7 @@ QPDFJob::Config::replaceInput() if ((o.m->outfilename == nullptr) && (!o.m->replace_input)) { o.m->replace_input = true; } else { - usage("replace-input can't be used" - " since output file has already been given"); + usage("replace-input can't be used since output file has already been given"); } return this; } @@ -298,8 +293,7 @@ QPDFJob::Config::jsonOutput(std::string const& parameter) o.m->json_output = true; json(parameter); if (!o.m->json_stream_data_set) { - // No need to set json_stream_data_set -- that indicates - // explicit use of --json-stream-data. + // No need to set json_stream_data_set -- that indicates explicit use of --json-stream-data. o.m->json_stream_data = qpdf_sj_inline; } if (!o.m->decode_level_set) { diff --git a/libqpdf/QPDFJob_json.cc b/libqpdf/QPDFJob_json.cc index 126f9a13..92488df1 100644 --- a/libqpdf/QPDFJob_json.cc +++ b/libqpdf/QPDFJob_json.cc @@ -30,27 +30,20 @@ namespace typedef std::function param_handler_t; typedef std::function json_handler_t; - // The code that calls these methods is automatically - // generated by generate_auto_job. This describes how we - // implement what it does. We keep a stack of handlers in - // json_handlers. The top of the stack is the "current" json - // handler, intially for the top-level object. Whenever we - // encounter a scalar, we add a handler using addBare, - // addParameter, or addChoices. Whenever we encounter a - // dictionary, we first add the dictionary handlers. Then we - // walk into the dictionary and, for each key, we register a - // dict key handler and push it to the stack, then do the same - // process for the key's value. Then we pop the key handler - // off the stack. When we encounter an array, we add the array - // handlers, push an item handler to the stack, call - // recursively for the array's single item (as this is what is - // expected in a schema), and pop the item handler. Note that - // we don't pop dictionary start/end handlers. The dictionary - // handlers and the key handlers are at the same level in - // JSONHandler. This logic is subtle and took several tries to - // get right. It's best understood by carefully understanding - // the behavior of JSONHandler, the JSON schema, and the code - // in generate_auto_job. + // The code that calls these methods is automatically generated by generate_auto_job. This + // describes how we implement what it does. We keep a stack of handlers in json_handlers. + // The top of the stack is the "current" json handler, intially for the top-level object. + // Whenever we encounter a scalar, we add a handler using addBare, addParameter, or + // addChoices. Whenever we encounter a dictionary, we first add the dictionary handlers. + // Then we walk into the dictionary and, for each key, we register a dict key handler and + // push it to the stack, then do the same process for the key's value. Then we pop the key + // handler off the stack. When we encounter an array, we add the array handlers, push an + // item handler to the stack, call recursively for the array's single item (as this is what + // is expected in a schema), and pop the item handler. Note that we don't pop dictionary + // start/end handlers. The dictionary handlers and the key handlers are at the same level in + // JSONHandler. This logic is subtle and took several tries to get right. It's best + // understood by carefully understanding the behavior of JSONHandler, the JSON schema, and + // the code in generate_auto_job. void addBare(bare_handler_t); void addParameter(param_handler_t); @@ -261,9 +254,8 @@ Handlers::setupReplaceInput() void Handlers::beginEncrypt(JSON j) { - // This method is only called if the overall JSON structure - // matches the schema, so we already know that keys that are - // present have the right types. + // This method is only called if the overall JSON structure matches the schema, so we already + // know that keys that are present have the right types. int key_len = 0; std::string user_password; std::string owner_password; @@ -284,14 +276,13 @@ Handlers::beginEncrypt(JSON j) }); if (key_len == 0) { QTC::TC("qpdf", "QPDFJob json encrypt no key length"); - usage("exactly one of 40bit, 128bit, or 256bit must be given;" - " an empty dictionary may be supplied for one of them" - " to set the key length without imposing any restrictions"); + usage("exactly one of 40bit, 128bit, or 256bit must be given; an empty dictionary may be " + "supplied for one of them to set the key length without imposing any restrictions"); } if (!(user_password_seen && owner_password_seen)) { QTC::TC("qpdf", "QPDFJob json encrypt missing password"); - usage("the user and owner password are both required; use the empty" - " string for the user password if you don't want a password"); + usage("the user and owner password are both required; use the empty string for the user " + "password if you don't want a password"); } this->c_enc = c_main->encrypt(key_len, user_password, owner_password); } diff --git a/libqpdf/QPDFNameTreeObjectHelper.cc b/libqpdf/QPDFNameTreeObjectHelper.cc index bfe67ecc..5a9992fb 100644 --- a/libqpdf/QPDFNameTreeObjectHelper.cc +++ b/libqpdf/QPDFNameTreeObjectHelper.cc @@ -36,9 +36,8 @@ static NameTreeDetails name_tree_details; QPDFNameTreeObjectHelper::~QPDFNameTreeObjectHelper() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer. For this specific class, see github issue - // #745. + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer. For this specific + // class, see github issue #745. } QPDFNameTreeObjectHelper::Members::Members(QPDFObjectHandle& oh, QPDF& q, bool auto_repair) : diff --git a/libqpdf/QPDFNumberTreeObjectHelper.cc b/libqpdf/QPDFNumberTreeObjectHelper.cc index f35158d5..95cee9c8 100644 --- a/libqpdf/QPDFNumberTreeObjectHelper.cc +++ b/libqpdf/QPDFNumberTreeObjectHelper.cc @@ -37,9 +37,8 @@ static NumberTreeDetails number_tree_details; QPDFNumberTreeObjectHelper::~QPDFNumberTreeObjectHelper() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer. For this specific class, see github issue - // #745. + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer. For this specific + // class, see github issue #745. } QPDFNumberTreeObjectHelper::Members::Members(QPDFObjectHandle& oh, QPDF& q, bool auto_repair) : diff --git a/libqpdf/QPDFObjGen.cc b/libqpdf/QPDFObjGen.cc index 8e5bd178..f3b19f6c 100644 --- a/libqpdf/QPDFObjGen.cc +++ b/libqpdf/QPDFObjGen.cc @@ -27,8 +27,8 @@ QPDFObjGen::set::add(QPDFObjectHandle const& oh) if (auto* ptr = oh.getObjectPtr()) { return add(ptr->getObjGen()); } else { - throw std::logic_error("attempt to retrieve QPDFObjGen from " - "uninitialized QPDFObjectHandle"); + throw std::logic_error( + "attempt to retrieve QPDFObjGen from uninitialized QPDFObjectHandle"); return false; } } @@ -39,8 +39,8 @@ QPDFObjGen::set::add(QPDFObjectHelper const& helper) if (auto* ptr = helper.getObjectHandle().getObjectPtr()) { return add(ptr->getObjGen()); } else { - throw std::logic_error("attempt to retrieve QPDFObjGen from " - "uninitialized QPDFObjectHandle"); + throw std::logic_error( + "attempt to retrieve QPDFObjGen from uninitialized QPDFObjectHandle"); return false; } } @@ -51,8 +51,8 @@ QPDFObjGen::set::erase(QPDFObjectHandle const& oh) if (auto* ptr = oh.getObjectPtr()) { erase(ptr->getObjGen()); } else { - throw std::logic_error("attempt to retrieve QPDFObjGen from " - "uninitialized QPDFObjectHandle"); + throw std::logic_error( + "attempt to retrieve QPDFObjGen from uninitialized QPDFObjectHandle"); } } @@ -62,7 +62,7 @@ QPDFObjGen::set::erase(QPDFObjectHelper const& helper) if (auto* ptr = helper.getObjectHandle().getObjectPtr()) { erase(ptr->getObjGen()); } else { - throw std::logic_error("attempt to retrieve QPDFObjGen from " - "uninitialized QPDFObjectHandle"); + throw std::logic_error( + "attempt to retrieve QPDFObjGen from uninitialized QPDFObjectHandle"); } } diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index fa5e52e8..3797ad12 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -229,11 +229,9 @@ QPDFObjectHandle::isSameObjectAs(QPDFObjectHandle const& rhs) const void QPDFObjectHandle::disconnect() { - // Recursively remove association with any QPDF object. This - // method may only be called during final destruction. - // QPDF::~QPDF() calls it for indirect objects using the object - // pointer itself, so we don't do that here. Other objects call it - // through this method. + // Recursively remove association with any QPDF object. This method may only be called during + // final destruction. QPDF::~QPDF() calls it for indirect objects using the object pointer + // itself, so we don't do that here. Other objects call it through this method. if (!isIndirect()) { this->obj->disconnect(); } @@ -1783,10 +1781,9 @@ QPDFObjectHandle::parseContentStream_data( tokenizer.allowEOF(); bool empty = false; while (QIntC::to_size(input->tell()) < stream_length) { - // Read a token and seek to the beginning. The offset we get - // from this process is the beginning of the next - // non-ignorable (space, comment) token. This way, the offset - // and don't including ignorable content. + // Read a token and seek to the beginning. The offset we get from this process is the + // beginning of the next non-ignorable (space, comment) token. This way, the offset and + // don't including ignorable content. tokenizer.readToken(input, "content", true); qpdf_offset_t offset = input->getLastOffset(); input->seek(offset, SEEK_SET); diff --git a/libqpdf/QPDFObjectHelper.cc b/libqpdf/QPDFObjectHelper.cc index 3696dc03..eb7de06e 100644 --- a/libqpdf/QPDFObjectHelper.cc +++ b/libqpdf/QPDFObjectHelper.cc @@ -2,6 +2,5 @@ QPDFObjectHelper::~QPDFObjectHelper() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/QPDFOutlineObjectHelper.cc b/libqpdf/QPDFOutlineObjectHelper.cc index 37e2c0d2..3b5db47a 100644 --- a/libqpdf/QPDFOutlineObjectHelper.cc +++ b/libqpdf/QPDFOutlineObjectHelper.cc @@ -14,8 +14,8 @@ QPDFOutlineObjectHelper::QPDFOutlineObjectHelper( m(new Members(dh)) { if (depth > 50) { - // Not exercised in test suite, but was tested manually by - // temporarily changing max depth to 1. + // Not exercised in test suite, but was tested manually by temporarily changing max depth + // to 1. return; } if (QPDFOutlineDocumentHelper::Accessor::checkSeen(m->dh, this->oh.getObjGen())) { diff --git a/libqpdf/QPDFPageDocumentHelper.cc b/libqpdf/QPDFPageDocumentHelper.cc index 06ec5ff7..3811d7dd 100644 --- a/libqpdf/QPDFPageDocumentHelper.cc +++ b/libqpdf/QPDFPageDocumentHelper.cc @@ -59,8 +59,8 @@ QPDFPageDocumentHelper::flattenAnnotations(int required_flags, int forbidden_fla if (afdh.getNeedAppearances()) { this->qpdf.getRoot() .getKey("/AcroForm") - .warnIfPossible("document does not have updated appearance streams," - " so form fields will not be flattened"); + .warnIfPossible("document does not have updated appearance streams, so form fields " + "will not be flattened"); } for (auto& ph: getAllPages()) { QPDFObjectHandle resources = ph.getAttribute("/Resources", true); @@ -126,11 +126,10 @@ QPDFPageDocumentHelper::flattenAnnotationsForPage( } new_content += content; } else if (process) { - // If an annotation has no appearance stream, just drop - // the annotation when flattening. This can happen for - // unchecked checkboxes and radio buttons, popup windows - // associated with comments that aren't visible, and other - // types of annotations that aren't visible. + // If an annotation has no appearance stream, just drop the annotation when flattening. + // This can happen for unchecked checkboxes and radio buttons, popup windows associated + // with comments that aren't visible, and other types of annotations that aren't + // visible. QTC::TC("qpdf", "QPDFPageDocumentHelper ignore annotation with no appearance"); } else { new_annots.push_back(aoh.getObjectHandle()); diff --git a/libqpdf/QPDFPageLabelDocumentHelper.cc b/libqpdf/QPDFPageLabelDocumentHelper.cc index 4a9b456f..d94c41fd 100644 --- a/libqpdf/QPDFPageLabelDocumentHelper.cc +++ b/libqpdf/QPDFPageLabelDocumentHelper.cc @@ -57,19 +57,17 @@ QPDFPageLabelDocumentHelper::getLabelsForPageRange( long long new_start_idx, std::vector& new_labels) { - // Start off with a suitable label for the first page. For every - // remaining page, if that page has an explicit entry, copy it. - // Otherwise, let the subsequent page just sequence from the prior - // entry. If there is no entry for the first page, fabricate one - // that would match how the page would look in a new file in which - // it also didn't have an explicit label. + // Start off with a suitable label for the first page. For every remaining page, if that page + // has an explicit entry, copy it. Otherwise, let the subsequent page just sequence from the + // prior entry. If there is no entry for the first page, fabricate one that would match how the + // page would look in a new file in which it also didn't have an explicit label. QPDFObjectHandle label = getLabelForPage(start_idx); if (label.isNull()) { label = QPDFObjectHandle::newDictionary(); label.replaceKey("/St", QPDFObjectHandle::newInteger(1 + new_start_idx)); } - // See if the new label is redundant based on the previous entry - // in the vector. If so, don't add it. + // See if the new label is redundant based on the previous entry in the vector. If so, don't add + // it. size_t size = new_labels.size(); bool skip_first = false; if (size >= 2) { diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc index 782a0c49..94ce07b9 100644 --- a/libqpdf/QPDFWriter.cc +++ b/libqpdf/QPDFWriter.cc @@ -28,8 +28,7 @@ QPDFWriter::ProgressReporter::~ProgressReporter() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } QPDFWriter::FunctionProgressReporter::FunctionProgressReporter(std::function handler) : @@ -39,8 +38,7 @@ QPDFWriter::FunctionProgressReporter::FunctionProgressReporter(std::function 3) { - // Bit 10 is deprecated and should always be set. This used - // to mean accessibility. There is no way to disable - // accessibility with R > 3. + // Bit 10 is deprecated and should always be set. This used to mean accessibility. There + // is no way to disable accessibility with R > 3. bits_to_clear.erase(10); } @@ -669,12 +664,10 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf) m->encrypt_metadata = encrypt.getKey("/EncryptMetadata").getBoolValue(); } if (V >= 4) { - // When copying encryption parameters, use AES even if the - // original file did not. Acrobat doesn't create files - // with V >= 4 that don't use AES, and the logic of - // figuring out whether AES is used or not is complicated - // with /StmF, /StrF, and /EFF all potentially having - // different values. + // When copying encryption parameters, use AES even if the original file did not. + // Acrobat doesn't create files with V >= 4 that don't use AES, and the logic of + // figuring out whether AES is used or not is complicated with /StmF, /StrF, and /EFF + // all potentially having different values. m->encrypt_use_aes = true; } QTC::TC("qpdf", "QPDFWriter copy encrypt metadata", m->encrypt_metadata ? 0 : 1); @@ -757,11 +750,9 @@ QPDFWriter::parseVersion(std::string const& version, int& major, int& minor) con } std::string tmp = std::to_string(major) + "." + std::to_string(minor); if (tmp != version) { - // The version number in the input is probably invalid. This - // happens with some files that are designed to exercise bugs, - // such as files in the fuzzer corpus. Unfortunately - // QPDFWriter doesn't have a way to give a warning, so we just - // ignore this case. + // The version number in the input is probably invalid. This happens with some files that + // are designed to exercise bugs, such as files in the fuzzer corpus. Unfortunately + // QPDFWriter doesn't have a way to give a warning, so we just ignore this case. } } @@ -826,15 +817,13 @@ QPDFWriter::setEncryptionParametersInternal( m->encryption_dictionary["/EncryptMetadata"] = "false"; } if ((V == 4) || (V == 5)) { - // The spec says the value for the crypt filter key can be - // anything, and xpdf seems to agree. However, Adobe Reader - // won't open our files unless we use /StdCF. + // The spec says the value for the crypt filter key can be anything, and xpdf seems to + // agree. However, Adobe Reader won't open our files unless we use /StdCF. m->encryption_dictionary["/StmF"] = "/StdCF"; m->encryption_dictionary["/StrF"] = "/StdCF"; std::string method = (m->encrypt_use_aes ? ((V < 5) ? "/AESV2" : "/AESV3") : "/V2"); - // The PDF spec says the /Length key is optional, but the PDF - // previewer on some versions of MacOS won't open encrypted - // files without it. + // The PDF spec says the /Length key is optional, but the PDF previewer on some versions of + // MacOS won't open encrypted files without it. m->encryption_dictionary["/CF"] = "<< /StdCF << /AuthEvent /DocOpen /CFM " + method + " /Length " + std::string((V < 5) ? "16" : "32") + " >> >>"; } @@ -950,12 +939,10 @@ QPDFWriter::PipelinePopper::~PipelinePopper() qpdf_assert_debug(qw->m->pipeline_stack.size() >= 2); qw->m->pipeline->finish(); qpdf_assert_debug(dynamic_cast(qw->m->pipeline_stack.back()) == qw->m->pipeline); - // It might be possible for this assertion to fail if - // writeLinearized exits by exception when deterministic ID, but I - // don't think so. As of this writing, this is the only case in - // which two dynamically allocated PipelinePopper objects ever - // exist at the same time, so the assertion will fail if they get - // popped out of order from automatic destruction. + // It might be possible for this assertion to fail if writeLinearized exits by exception when + // deterministic ID, but I don't think so. As of this writing, this is the only case in which + // two dynamically allocated PipelinePopper objects ever exist at the same time, so the + // assertion will fail if they get popped out of order from automatic destruction. qpdf_assert_debug(qw->m->pipeline->getIdentifier() == stack_id); delete qw->m->pipeline_stack.back(); qw->m->pipeline_stack.pop_back(); @@ -978,9 +965,8 @@ void QPDFWriter::adjustAESStreamLength(size_t& length) { if (m->encrypted && (!m->cur_data_key.empty()) && m->encrypt_use_aes) { - // Stream length will be padded with 1 to 16 bytes to end up - // as a multiple of 16. It will also be prepended by 16 bits - // of random data. + // Stream length will be padded with 1 to 16 bytes to end up as a multiple of 16. It will + // also be prepended by 16 bits of random data. length += 32 - (length & 0xf); } } @@ -1006,8 +992,8 @@ QPDFWriter::pushEncryptionFilter(PipelinePopper& pp) } pushPipeline(p); } - // Must call this unconditionally so we can call popPipelineStack - // to balance pushEncryptionFilter(). + // Must call this unconditionally so we can call popPipelineStack to balance + // pushEncryptionFilter(). activatePipelineStack(pp); } @@ -1031,8 +1017,7 @@ QPDFWriter::pushMD5Pipeline(PipelinePopper& pp) qpdf_assert_debug(m->pipeline->getCount() == 0); m->md5_pipeline = new Pl_MD5("qpdf md5", m->pipeline); m->md5_pipeline->persistAcrossFinish(true); - // Special case code in popPipelineStack clears m->md5_pipeline - // upon deletion. + // Special case code in popPipelineStack clears m->md5_pipeline upon deletion. pushPipeline(m->md5_pipeline); activatePipelineStack(pp); } @@ -1061,8 +1046,7 @@ QPDFWriter::openObject(int objid) void QPDFWriter::closeObject(int objid) { - // Write a newline before endobj as it makes the file easier to - // repair. + // Write a newline before endobj as it makes the file easier to repair. writeString("\nendobj\n"); writeStringQDF("\n"); m->lengths[objid] = m->pipeline->getCount() - m->xref[objid].getOffset(); @@ -1077,8 +1061,7 @@ QPDFWriter::assignCompressedObjectNumbers(QPDFObjGen const& og) return; } - // Reserve numbers for the objects that belong to this object - // stream. + // Reserve numbers for the objects that belong to this object stream. for (auto const& iter: m->object_stream_to_objects[objid]) { m->obj_renumber[iter] = m->next_objid++; } @@ -1088,26 +1071,21 @@ void QPDFWriter::enqueueObject(QPDFObjectHandle object) { if (object.isIndirect()) { - // This owner check can only be done for indirect objects. It - // is possible for a direct object to have an owning QPDF that - // is from another file if a direct QPDFObjectHandle from one - // file was insert into another file without copying. Doing - // that is safe even if the original QPDF gets destroyed, - // which just disconnects the QPDFObjectHandle from its owner. + // This owner check can only be done for indirect objects. It is possible for a direct + // object to have an owning QPDF that is from another file if a direct QPDFObjectHandle from + // one file was insert into another file without copying. Doing that is safe even if the + // original QPDF gets destroyed, which just disconnects the QPDFObjectHandle from its owner. if (object.getOwningQPDF() != &(m->pdf)) { QTC::TC("qpdf", "QPDFWriter foreign object"); - throw std::logic_error("QPDFObjectHandle from different QPDF found while writing." - " Use QPDF::copyForeignObject to add objects from" - " another file."); + throw std::logic_error("QPDFObjectHandle from different QPDF found while writing. Use " + "QPDF::copyForeignObject to add objects from another file."); } if (m->qdf_mode && object.isStreamOfType("/XRef")) { - // As a special case, do not output any extraneous XRef - // streams in QDF mode. Doing so will confuse fix-qdf, - // which expects to see only one XRef stream at the end of - // the file. This case can occur when creating a QDF from - // a file with object streams when preserving unreferenced - // objects since the old cross reference streams are not + // As a special case, do not output any extraneous XRef streams in QDF mode. Doing so + // will confuse fix-qdf, which expects to see only one XRef stream at the end of the + // file. This case can occur when creating a QDF from a file with object streams when + // preserving unreferenced objects since the old cross reference streams are not // actually referenced by object number. QTC::TC("qpdf", "QPDFWriter ignore XRef in qdf mode"); return; @@ -1117,12 +1095,10 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) if (m->obj_renumber.count(og) == 0) { if (m->object_to_object_stream.count(og)) { - // This is in an object stream. Don't process it - // here. Instead, enqueue the object stream. Object - // streams always have generation 0. + // This is in an object stream. Don't process it here. Instead, enqueue the object + // stream. Object streams always have generation 0. int stream_id = m->object_to_object_stream[og]; - // Detect loops by storing invalid object ID 0, which - // will get overwritten later. + // Detect loops by storing invalid object ID 0, which will get overwritten later. m->obj_renumber[og] = 0; enqueueObject(m->pdf.getObjectByID(stream_id, 0)); } else { @@ -1130,9 +1106,8 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) m->obj_renumber[og] = m->next_objid++; if ((og.getGen() == 0) && m->object_stream_to_objects.count(og.getObj())) { - // For linearized files, uncompressed objects go - // at end, and we take care of assigning numbers - // to them elsewhere. + // For linearized files, uncompressed objects go at end, and we take care of + // assigning numbers to them elsewhere. if (!m->linearized) { assignCompressedObjectNumbers(og); } @@ -1142,8 +1117,8 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) } } } else if (m->obj_renumber[og] == 0) { - // This can happen if a specially constructed file - // indicates that an object stream is inside itself. + // This can happen if a specially constructed file indicates that an object stream is + // inside itself. QTC::TC("qpdf", "QPDFWriter ignore self-referential object stream"); } return; @@ -1223,12 +1198,10 @@ QPDFWriter::writeTrailer( if (original_id1.empty()) { writeString("<00000000000000000000000000000000>"); } else { - // Write a string of zeroes equal in length to the - // representation of the original ID. While writing the - // original ID would have the same number of bytes, it - // would cause a change to the deterministic ID generated - // by older versions of the software that hard-coded the - // length of the ID to 16 bytes. + // Write a string of zeroes equal in length to the representation of the original ID. + // While writing the original ID would have the same number of bytes, it would cause a + // change to the deterministic ID generated by older versions of the software that + // hard-coded the length of the ID to 16 bytes. writeString("<"); size_t len = QPDF_String(original_id1).unparse(true).length() - 2; for (size_t i = 0; i < len; ++i) { @@ -1284,11 +1257,9 @@ QPDFWriter::willFilterStream( filter = false; } if (filter_on_write && m->compress_streams) { - // Don't filter if the stream is already compressed with - // FlateDecode. This way we don't make it worse if the - // original file used a better Flate algorithm, and we - // don't spend time and CPU cycles uncompressing and - // recompressing stuff. This can be overridden with + // Don't filter if the stream is already compressed with FlateDecode. This way we don't make + // it worse if the original file used a better Flate algorithm, and we don't spend time and + // CPU cycles uncompressing and recompressing stuff. This can be overridden with // setRecompressFlate(true). QPDFObjectHandle filter_obj = stream_dict.getKey("/Filter"); if ((!m->recompress_flate) && (!stream.isDataModified()) && filter_obj.isName() && @@ -1351,8 +1322,8 @@ QPDFWriter::unparseObject( if (level < 0) { throw std::logic_error("invalid level in QPDFWriter::unparseObject"); } - // For non-qdf, "indent" is a single space between tokens. - // For qdf, indent includes the preceding newline. + // For non-qdf, "indent" is a single space between tokens. For qdf, indent includes the + // preceding newline. std::string indent = " "; if (m->qdf_mode) { indent.append(static_cast(2 * level), ' '); @@ -1360,11 +1331,9 @@ QPDFWriter::unparseObject( } if (auto const tc = object.getTypeCode(); tc == ::ot_array) { - // Note: PDF spec 1.4 implementation note 121 states that - // Acrobat requires a space after the [ in the /H key of the - // linearization parameter dictionary. We'll do this - // unconditionally for all arrays because it looks nicer and - // doesn't make the files that much bigger. + // Note: PDF spec 1.4 implementation note 121 states that Acrobat requires a space after the + // [ in the /H key of the linearization parameter dictionary. We'll do this unconditionally + // for all arrays because it looks nicer and doesn't make the files that much bigger. writeString("["); for (auto const& item: object.getArrayAsVector()) { writeString(indent); @@ -1374,13 +1343,11 @@ QPDFWriter::unparseObject( writeString(indent); writeString("]"); } else if (tc == ::ot_dictionary) { - // Make a shallow copy of this object so we can modify it - // safely without affecting the original. This code has logic - // to skip certain keys in agreement with prepareFileForWrite - // and with skip_stream_parameters so that replacing them - // doesn't leave unreferenced objects in the output. We can - // use unsafeShallowCopy here because we are all we are doing - // is removing or replacing top-level keys. + // Make a shallow copy of this object so we can modify it safely without affecting the + // original. This code has logic to skip certain keys in agreement with prepareFileForWrite + // and with skip_stream_parameters so that replacing them doesn't leave unreferenced objects + // in the output. We can use unsafeShallowCopy here because we are all we are doing is + // removing or replacing top-level keys. object = object.unsafeShallowCopy(); // Handle special cases for specific dictionaries. @@ -1400,9 +1367,8 @@ QPDFWriter::unparseObject( // - If it has other things, keep those and remove ADBE // - We have no extensions: no action required // - // Before writing, we guarantee that /Extensions, if present, - // is direct through the ADBE dictionary, so we can modify in - // place. + // Before writing, we guarantee that /Extensions, if present, is direct through the ADBE + // dictionary, so we can modify in place. const bool is_root = (old_og == m->root_og); bool have_extensions_other = false; @@ -1431,8 +1397,7 @@ QPDFWriter::unparseObject( if (is_root) { if (need_extensions_adbe) { if (!(have_extensions_other || have_extensions_adbe)) { - // We need Extensions and don't have it. Create - // it here. + // We need Extensions and don't have it. Create it here. QTC::TC("qpdf", "QPDFWriter create Extensions", m->qdf_mode ? 0 : 1); extensions = object.replaceKeyAndGetNew( "/Extensions", QPDFObjectHandle::newDictionary()); @@ -1488,8 +1453,8 @@ QPDFWriter::unparseObject( object.removeKey("/Filter"); object.removeKey("/DecodeParms"); } else { - // Make sure, no matter what else we have, that we - // don't have /Crypt in the output filters. + // Make sure, no matter what else we have, that we don't have /Crypt in the output + // filters. QPDFObjectHandle filter = object.getKey("/Filter"); QPDFObjectHandle decode_parms = object.getKey("/DecodeParms"); if (filter.isOrHasName("/Crypt")) { @@ -1506,12 +1471,10 @@ QPDFWriter::unparseObject( } } if (idx >= 0) { - // If filter is an array, then the code in - // QPDF_Stream has already verified that - // DecodeParms and Filters are arrays of - // the same length, but if they weren't - // for some reason, eraseItem does type - // and bounds checking. + // If filter is an array, then the code in QPDF_Stream has already + // verified that DecodeParms and Filters are arrays of the same length, + // but if they weren't for some reason, eraseItem does type and bounds + // checking. QTC::TC("qpdf", "QPDFWriter remove Crypt"); filter.eraseItem(idx); decode_parms.eraseItem(idx); @@ -1659,8 +1622,8 @@ QPDFWriter::writeObjectStreamOffsets(std::vector& offsets, int fi void QPDFWriter::writeObjectStream(QPDFObjectHandle object) { - // Note: object might be null if this is a place-holder for an - // object stream that we are generating from scratch. + // Note: object might be null if this is a place-holder for an object stream that we are + // generating from scratch. QPDFObjGen old_og = object.getObjGen(); qpdf_assert_debug(old_og.getGen() == 0); @@ -1670,8 +1633,8 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) std::vector offsets; qpdf_offset_t first = 0; - // Generate stream itself. We have to do this in two passes so we - // can calculate offsets in the first pass. + // Generate stream itself. We have to do this in two passes so we can calculate offsets in the + // first pass. std::shared_ptr stream_buffer; int first_obj = -1; bool compressed = false; @@ -1687,8 +1650,7 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) iter -= first; } - // Take one pass at writing pairs of numbers so we can get - // their size information + // Take one pass at writing pairs of numbers so we can get their size information { PipelinePopper pp_discard(this); pushDiscardFilter(pp_discard); @@ -1721,11 +1683,9 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) std::to_string(count)); if (!m->suppress_original_object_ids) { writeString("; original object ID: " + std::to_string(obj.getObj())); - // For compatibility, only write the generation if - // non-zero. While object streams only allow - // objects with generation 0, if we are generating - // object streams, the old object could have a - // non-zero generation. + // For compatibility, only write the generation if non-zero. While object + // streams only allow objects with generation 0, if we are generating object + // streams, the old object could have a non-zero generation. if (obj.getGen() != 0) { QTC::TC("qpdf", "QPDFWriter original obj non-zero gen"); writeString(" " + std::to_string(obj.getGen())); @@ -1735,16 +1695,14 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) } if (pass == 1) { offsets.push_back(m->pipeline->getCount()); - // To avoid double-counting objects being written in - // object streams for progress reporting, decrement in - // pass 1. + // To avoid double-counting objects being written in object streams for progress + // reporting, decrement in pass 1. indicateProgress(true, false); } QPDFObjectHandle obj_to_write = m->pdf.getObject(obj); if (obj_to_write.isStream()) { - // This condition occurred in a fuzz input. Ideally we - // should block it at at parse time, but it's not - // clear to me how to construct a case for this. + // This condition occurred in a fuzz input. Ideally we should block it at at parse + // time, but it's not clear to me how to construct a case for this. QTC::TC("qpdf", "QPDFWriter stream in ostream"); obj_to_write.warnIfPossible("stream found inside object stream; treating as null"); obj_to_write = QPDFObjectHandle::newNull(); @@ -1867,8 +1825,8 @@ QPDFWriter::getOriginalID1() void QPDFWriter::generateID() { - // Generate the ID lazily so that we can handle the user's - // preference to use static or deterministic ID generation. + // Generate the ID lazily so that we can handle the user's preference to use static or + // deterministic ID generation. if (!m->id2.empty()) { return; @@ -1900,27 +1858,22 @@ QPDFWriter::generateID() 0x00}; result = reinterpret_cast(tmp); } else { - // The PDF specification has guidelines for creating IDs, but - // it states clearly that the only thing that's really - // important is that it is very likely to be unique. We can't - // really follow the guidelines in the spec exactly because we - // haven't written the file yet. This scheme should be fine - // though. The deterministic ID case uses a digest of a - // sufficient portion of the file's contents such no two - // non-matching files would match in the subsets used for this - // computation. Note that we explicitly omit the filename from - // the digest calculation for deterministic ID so that the same - // file converted with qpdf, in that case, would have the same - // ID regardless of the output file's name. + // The PDF specification has guidelines for creating IDs, but it states clearly that the + // only thing that's really important is that it is very likely to be unique. We can't + // really follow the guidelines in the spec exactly because we haven't written the file yet. + // This scheme should be fine though. The deterministic ID case uses a digest of a + // sufficient portion of the file's contents such no two non-matching files would match in + // the subsets used for this computation. Note that we explicitly omit the filename from + // the digest calculation for deterministic ID so that the same file converted with qpdf, in + // that case, would have the same ID regardless of the output file's name. std::string seed; if (m->deterministic_id) { if (m->deterministic_id_data.empty()) { QTC::TC("qpdf", "QPDFWriter deterministic with no data"); - throw std::logic_error("INTERNAL ERROR: QPDFWriter::generateID has no" - " data for deterministic ID. This may happen if" - " deterministic ID and file encryption are requested" - " together."); + throw std::logic_error("INTERNAL ERROR: QPDFWriter::generateID has no data for " + "deterministic ID. This may happen if deterministic ID and " + "file encryption are requested together."); } seed += m->deterministic_id_data; } else { @@ -1947,9 +1900,8 @@ QPDFWriter::generateID() result = std::string(reinterpret_cast(digest), sizeof(MD5::Digest)); } - // If /ID already exists, follow the spec: use the original first - // word and generate a new second word. Otherwise, we'll use the - // generated ID for both. + // If /ID already exists, follow the spec: use the original first word and generate a new second + // word. Otherwise, we'll use the generated ID for both. m->id2 = result; // Note: keep /ID from old file even if --static-id was given. @@ -1994,16 +1946,13 @@ QPDFWriter::preserveObjectStreams() if (omap.empty()) { return; } - // Our object_to_object_stream map has to map ObjGen -> ObjGen - // since we may be generating object streams out of old objects - // that have generation numbers greater than zero. However in an - // existing PDF, all object stream objects and all objects in them - // must have generation 0 because the PDF spec does not provide - // any way to do otherwise. This code filters out objects that are - // not allowed to be in object streams. In addition to removing - // objects that were erroneously included in object streams in the - // source PDF, it also prevents unreferenced objects from being - // included. + // Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object + // streams out of old objects that have generation numbers greater than zero. However in an + // existing PDF, all object stream objects and all objects in them must have generation 0 + // because the PDF spec does not provide any way to do otherwise. This code filters out objects + // that are not allowed to be in object streams. In addition to removing objects that were + // erroneously included in object streams in the source PDF, it also prevents unreferenced + // objects from being included. std::set eligible; if (!m->preserve_unreferenced_objects) { std::vector eligible_v = QPDF::Writer::getCompressibleObjGens(m->pdf); @@ -2023,13 +1972,11 @@ QPDFWriter::preserveObjectStreams() void QPDFWriter::generateObjectStreams() { - // Basic strategy: make a list of objects that can go into an - // object stream. Then figure out how many object streams are - // needed so that we can distribute objects approximately evenly - // without having any object stream exceed 100 members. We don't - // have to worry about linearized files here -- if the file is - // linearized, we take care of excluding things that aren't - // allowed here later. + // Basic strategy: make a list of objects that can go into an object stream. Then figure out + // how many object streams are needed so that we can distribute objects approximately evenly + // without having any object stream exceed 100 members. We don't have to worry about linearized + // files here -- if the file is linearized, we take care of excluding things that aren't allowed + // here later. // This code doesn't do anything with /Extends. @@ -2052,9 +1999,8 @@ QPDFWriter::generateObjectStreams() n = 0; } if (n == 0) { - // Construct a new null object as the "original" object - // stream. The rest of the code knows that this means - // we're creating the object stream from scratch. + // Construct a new null object as the "original" object stream. The rest of the code + // knows that this means we're creating the object stream from scratch. cur_ostream = m->pdf.makeIndirectObject(QPDFObjectHandle::newNull()).getObjectID(); } m->object_to_object_stream[iter] = cur_ostream; @@ -2065,8 +2011,7 @@ QPDFWriter::generateObjectStreams() QPDFObjectHandle QPDFWriter::getTrimmedTrailer() { - // Remove keys from the trailer that necessarily have to be - // replaced when writing the file. + // Remove keys from the trailer that necessarily have to be replaced when writing the file. QPDFObjectHandle trailer = m->pdf.getTrailer().unsafeShallowCopy(); @@ -2077,8 +2022,7 @@ QPDFWriter::getTrimmedTrailer() // Remove modification information trailer.removeKey("/Prev"); - // Remove all trailer keys that potentially come from a - // cross-reference stream + // Remove all trailer keys that potentially come from a cross-reference stream trailer.removeKey("/Index"); trailer.removeKey("/W"); trailer.removeKey("/Length"); @@ -2093,8 +2037,7 @@ QPDFWriter::getTrimmedTrailer() void QPDFWriter::prepareFileForWrite() { - // Make document extension level information direct as required by - // the spec. + // Make document extension level information direct as required by the spec. m->pdf.fixDanglingReferences(); QPDFObjectHandle root = m->pdf.getRoot(); @@ -2155,8 +2098,8 @@ QPDFWriter::doWriteSetup() // Encryption has been explicitly set m->preserve_encryption = false; } else if (m->normalize_content || m->stream_decode_level || m->pclm || m->qdf_mode) { - // Encryption makes looking at contents pretty useless. If - // the user explicitly encrypted though, we still obey that. + // Encryption makes looking at contents pretty useless. If the user explicitly encrypted + // though, we still obey that. m->preserve_encryption = false; } @@ -2180,9 +2123,8 @@ QPDFWriter::doWriteSetup() } if (m->qdf_mode) { - // Generate indirect stream lengths for qdf mode since fix-qdf - // uses them for storing recomputed stream length data. - // Certain streams such as object streams, xref streams, and + // Generate indirect stream lengths for qdf mode since fix-qdf uses them for storing + // recomputed stream length data. Certain streams such as object streams, xref streams, and // hint streams always get direct stream lengths. m->direct_stream_lengths = false; } @@ -2215,11 +2157,10 @@ QPDFWriter::doWriteSetup() } if (m->linearized || m->encrypted) { - // The document catalog is not allowed to be compressed in - // linearized files either. It also appears that Adobe Reader - // 8.0.0 has a bug that prevents it from being able to handle - // encrypted files with compressed document catalogs, so we - // disable them in that case as well. + // The document catalog is not allowed to be compressed in linearized files either. It also + // appears that Adobe Reader 8.0.0 has a bug that prevents it from being able to handle + // encrypted files with compressed document catalogs, so we disable them in that case as + // well. if (m->object_to_object_stream.count(m->root_og)) { QTC::TC("qpdf", "QPDFWriter uncompressing root"); m->object_to_object_stream.erase(m->root_og); @@ -2254,9 +2195,8 @@ QPDFWriter::write() { doWriteSetup(); - // Set up progress reporting. For linearized files, we write two - // passes. events_expected is an approximation, but it's good - // enough for progress reporting, which is mostly a guess anyway. + // Set up progress reporting. For linearized files, we write two passes. events_expected is an + // approximation, but it's good enough for progress reporting, which is mostly a guess anyway. m->events_expected = QIntC::to_int(m->pdf.getObjectCount() * (m->linearized ? 2 : 1)); prepareFileForWrite(); @@ -2338,17 +2278,16 @@ QPDFWriter::writeHeader() // PCLm version writeString("\n%PCLm 1.0\n"); } else { - // This string of binary characters would not be valid UTF-8, so - // it really should be treated as binary. + // This string of binary characters would not be valid UTF-8, so it really should be treated + // as binary. writeString("\n%\xbf\xf7\xa2\xfe\n"); } writeStringQDF("%QDF-1.0\n\n"); - // Note: do not write extra header text here. Linearized PDFs - // must include the entire linearization parameter dictionary - // within the first 1024 characters of the PDF file, so for - // linearized files, we have to write extra header text after the - // linearization parameter dictionary. + // Note: do not write extra header text here. Linearized PDFs must include the entire + // linearization parameter dictionary within the first 1024 characters of the PDF file, so for + // linearized files, we have to write extra header text after the linearization parameter + // dictionary. } void @@ -2397,9 +2336,8 @@ QPDFWriter::writeHintStream(int hint_id) qpdf_offset_t QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size) { - // There are too many extra arguments to replace overloaded - // function with defaults in the header file...too much risk of - // leaving something off. + // There are too many extra arguments to replace overloaded function with defaults in the header + // file...too much risk of leaving something off. return writeXRefTable(which, first, last, size, 0, false, 0, 0, 0, 0); } @@ -2446,9 +2384,8 @@ qpdf_offset_t QPDFWriter::writeXRefStream( int objid, int max_id, qpdf_offset_t max_offset, trailer_e which, int first, int last, int size) { - // There are too many extra arguments to replace overloaded - // function with defaults in the header file...too much risk of - // leaving something off. + // There are too many extra arguments to replace overloaded function with defaults in the header + // file...too much risk of leaving something off. return writeXRefStream( objid, max_id, max_offset, which, first, last, size, 0, 0, 0, 0, false, 0); } @@ -2480,8 +2417,8 @@ QPDFWriter::writeXRefStream( unsigned int esize = 1 + f1_size + f2_size; - // Must store in xref table in advance of writing the actual data - // rather than waiting for openObject to do it. + // Must store in xref table in advance of writing the actual data rather than waiting for + // openObject to do it. m->xref[xref_id] = QPDFXRefEntry(m->pipeline->getCount()); Pipeline* p = pushPipeline(new Pl_Buffer("xref stream")); @@ -2489,9 +2426,8 @@ QPDFWriter::writeXRefStream( if ((m->compress_streams || (m->stream_decode_level == qpdf_dl_none)) && (!m->qdf_mode)) { compressed = true; if (!skip_compression) { - // Write the stream dictionary for compression but don't - // actually compress. This helps us with computation of - // padding for pass 1 of linearization. + // Write the stream dictionary for compression but don't actually compress. This helps + // us with computation of padding for pass 1 of linearization. p = pushPipeline(new Pl_Flate("compress xref", p, Pl_Flate::a_deflate)); } p = pushPipeline(new Pl_PNGFilter("pngify xref", p, Pl_PNGFilter::a_encode, esize)); @@ -2563,13 +2499,11 @@ QPDFWriter::writeXRefStream( size_t QPDFWriter::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) { - // This routine is called right after a linearization first pass - // xref stream has been written without compression. Calculate - // the amount of padding that would be required in the worst case, - // assuming the number of uncompressed bytes remains the same. - // The worst case for zlib is that the output is larger than the - // input by 6 bytes plus 5 bytes per 16K, and then we'll add 10 - // extra bytes for number length increases. + // This routine is called right after a linearization first pass xref stream has been written + // without compression. Calculate the amount of padding that would be required in the worst + // case, assuming the number of uncompressed bytes remains the same. The worst case for zlib is + // that the output is larger than the input by 6 bytes plus 5 bytes per 16K, and then we'll add + // 10 extra bytes for number length increases. return QIntC::to_size(16 + (5 * ((xref_bytes + 16383) / 16384))); } @@ -2577,17 +2511,14 @@ QPDFWriter::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) void QPDFWriter::discardGeneration(std::map const& in, std::map& out) { - // There are deep assumptions in the linearization code in QPDF - // that there is only one object with each object number; i.e., - // you can't have two objects with the same object number and - // different generations. This is a pretty safe assumption - // because Adobe Reader and Acrobat can't actually handle this - // case. There is not much if any code in QPDF outside - // linearization that assumes this, but the linearization code as - // currently implemented would do weird things if we found such a - // case. In order to avoid breaking ABI changes in QPDF, we will - // first assert that this condition holds. Then we can create new - // maps for QPDF that throw away generation numbers. + // There are deep assumptions in the linearization code in QPDF that there is only one object + // with each object number; i.e., you can't have two objects with the same object number and + // different generations. This is a pretty safe assumption because Adobe Reader and Acrobat + // can't actually handle this case. There is not much if any code in QPDF outside linearization + // that assumes this, but the linearization code as currently implemented would do weird things + // if we found such a case. In order to avoid breaking ABI changes in QPDF, we will first + // assert that this condition holds. Then we can create new maps for QPDF that throw away + // generation numbers. out.clear(); for (auto const& iter: in) { @@ -2707,25 +2638,21 @@ QPDFWriter::writeLinearized() m->next_objid = part4_first_obj; enqueuePart(part4); if (m->next_objid != after_part4) { - // This can happen with very botched files as in the fuzzer - // test. There are likely some faulty assumptions in - // calculateLinearizationData - throw std::runtime_error("error encountered after" - " writing part 4 of linearized data"); + // This can happen with very botched files as in the fuzzer test. There are likely some + // faulty assumptions in calculateLinearizationData + throw std::runtime_error("error encountered after writing part 4 of linearized data"); } m->next_objid = part6_first_obj; enqueuePart(part6); if (m->next_objid != after_part6) { - throw std::runtime_error("error encountered after" - " writing part 6 of linearized data"); + throw std::runtime_error("error encountered after writing part 6 of linearized data"); } m->next_objid = second_half_first_obj; enqueuePart(part7); enqueuePart(part8); enqueuePart(part9); if (m->next_objid != after_second_half) { - throw std::runtime_error("error encountered after" - " writing part 9 of linearized data"); + throw std::runtime_error("error encountered after writing part 9 of linearized data"); } qpdf_offset_t hint_length = 0; @@ -2754,13 +2681,11 @@ QPDFWriter::writeLinearized() writeHeader(); - // Part 2: linearization parameter dictionary. Save enough - // space to write real dictionary. 200 characters is enough - // space if all numerical values in the parameter dictionary - // that contain offsets are 20 digits long plus a few extra - // characters for safety. The entire linearization parameter - // dictionary must appear within the first 1024 characters of - // the file. + // Part 2: linearization parameter dictionary. Save enough space to write real dictionary. + // 200 characters is enough space if all numerical values in the parameter dictionary that + // contain offsets are 20 digits long plus a few extra characters for safety. The entire + // linearization parameter dictionary must appear within the first 1024 characters of the + // file. qpdf_offset_t pos = m->pipeline->getCount(); openObject(lindict_id); @@ -2772,8 +2697,7 @@ QPDFWriter::writeLinearized() writeString(" /Linearized 1 /L "); writeString(std::to_string(file_size + hint_length)); - // Implementation note 121 states that a space is - // mandatory after this open bracket. + // Implementation note 121 states that a space is mandatory after this open bracket. writeString(" /H [ "); writeString(std::to_string(m->xref[hint_id].getOffset())); writeString(" "); @@ -2793,8 +2717,8 @@ QPDFWriter::writeLinearized() writePad(QIntC::to_size(pos - m->pipeline->getCount() + pad)); writeString("\n"); - // If the user supplied any additional header text, write it - // here after the linearization parameter dictionary. + // If the user supplied any additional header text, write it here after the linearization + // parameter dictionary. writeString(m->extra_header_text); // Part 3: first page cross reference table and trailer. @@ -2807,14 +2731,11 @@ QPDFWriter::writeLinearized() if (need_xref_stream) { // Must pad here too. if (pass == 1) { - // Set first_half_max_obj_offset to a value large - // enough to force four bytes to be reserved for each - // file offset. This would provide adequate space for - // the xref stream as long as the last object in page - // 1 starts with in the first 4 GB of the file, which - // is extremely likely. In the second pass, we will - // know the actual value for this, but it's okay if - // it's smaller. + // Set first_half_max_obj_offset to a value large enough to force four bytes to be + // reserved for each file offset. This would provide adequate space for the xref + // stream as long as the last object in page 1 starts with in the first 4 GB of the + // file, which is extremely likely. In the second pass, we will know the actual + // value for this, but it's okay if it's smaller. first_half_max_obj_offset = 1 << 25; } pos = m->pipeline->getCount(); @@ -2834,13 +2755,11 @@ QPDFWriter::writeLinearized() pass); qpdf_offset_t endpos = m->pipeline->getCount(); if (pass == 1) { - // Pad so we have enough room for the real xref - // stream. + // Pad so we have enough room for the real xref stream. writePad(calculateXrefStreamPadding(endpos - pos)); first_xref_end = m->pipeline->getCount(); } else { - // Pad so that the next object starts at the same - // place as in pass 1. + // Pad so that the next object starts at the same place as in pass 1. writePad(QIntC::to_size(first_xref_end - endpos)); if (m->pipeline->getCount() != first_xref_end) { @@ -2913,9 +2832,8 @@ QPDFWriter::writeLinearized() qpdf_offset_t endpos = m->pipeline->getCount(); if (pass == 1) { - // Pad so we have enough room for the real xref - // stream. See comments for previous xref stream on - // how we calculate the padding. + // Pad so we have enough room for the real xref stream. See comments for previous + // xref stream on how we calculate the padding. writePad(calculateXrefStreamPadding(endpos - pos)); writeString("\n"); second_xref_end = m->pipeline->getCount(); @@ -2925,11 +2843,10 @@ QPDFWriter::writeLinearized() QIntC::to_size(second_xref_end + hint_length - 1 - m->pipeline->getCount())); writeString("\n"); - // If this assertion fails, maybe we didn't have - // enough padding above. + // If this assertion fails, maybe we didn't have enough padding above. if (m->pipeline->getCount() != second_xref_end + hint_length) { - throw std::logic_error("count mismatch after xref stream;" - " possible insufficient padding?"); + throw std::logic_error( + "count mismatch after xref stream; possible insufficient padding?"); } } } else { @@ -2954,8 +2871,7 @@ QPDFWriter::writeLinearized() file_size = m->pipeline->getCount(); pp_pass1 = nullptr; - // Save hint offset since it will be set to zero by - // calling openObject. + // Save hint offset since it will be set to zero by calling openObject. qpdf_offset_t hint_offset1 = m->xref[hint_id].getOffset(); // Write hint stream to a buffer @@ -3003,10 +2919,8 @@ QPDFWriter::enqueueObjectsStandard() QPDFObjectHandle trailer = getTrimmedTrailer(); enqueueObject(trailer.getKey("/Root")); - // Next place any other objects referenced from the trailer - // dictionary into the queue, handling direct objects recursively. - // Root is already there, so enqueuing it a second time is a - // no-op. + // Next place any other objects referenced from the trailer dictionary into the queue, handling + // direct objects recursively. Root is already there, so enqueuing it a second time is a no-op. for (auto const& key: trailer.getKeys()) { enqueueObject(trailer.getKey(key)); } @@ -3015,9 +2929,8 @@ QPDFWriter::enqueueObjectsStandard() void QPDFWriter::enqueueObjectsPCLm() { - // Image transform stream content for page strip images. - // Each of this new stream has to come after every page image - // strip written in the pclm file. + // Image transform stream content for page strip images. Each of this new stream has to come + // after every page image strip written in the pclm file. std::string image_transform_content = "q /image Do Q\n"; // enqueue all pages first diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc index 760db2e2..1b78e078 100644 --- a/libqpdf/QPDF_Array.cc +++ b/libqpdf/QPDF_Array.cc @@ -12,9 +12,9 @@ QPDF_Array::checkOwnership(QPDFObjectHandle const& item) const if (qpdf) { if (auto item_qpdf = obj->getQPDF()) { if (qpdf != item_qpdf) { - throw std::logic_error("Attempting to add an object from a different QPDF. " - "Use QPDF::copyForeignObject to add objects from " - "another file."); + throw std::logic_error( + "Attempting to add an object from a different QPDF. Use " + "QPDF::copyForeignObject to add objects from another file."); } } } diff --git a/libqpdf/QPDF_Dictionary.cc b/libqpdf/QPDF_Dictionary.cc index 6d259ef5..7700b81b 100644 --- a/libqpdf/QPDF_Dictionary.cc +++ b/libqpdf/QPDF_Dictionary.cc @@ -89,8 +89,7 @@ QPDF_Dictionary::hasKey(std::string const& key) QPDFObjectHandle QPDF_Dictionary::getKey(std::string const& key) { - // PDF spec says fetching a non-existent key from a dictionary - // returns the null object. + // PDF spec says fetching a non-existent key from a dictionary returns the null object. auto item = this->items.find(key); if (item != this->items.end()) { // May be a null object @@ -123,8 +122,7 @@ void QPDF_Dictionary::replaceKey(std::string const& key, QPDFObjectHandle value) { if (value.isNull()) { - // The PDF spec doesn't distinguish between keys with null - // values and missing keys. + // The PDF spec doesn't distinguish between keys with null values and missing keys. removeKey(key); } else { // add or replace value diff --git a/libqpdf/QPDF_Name.cc b/libqpdf/QPDF_Name.cc index 8e439213..4597372e 100644 --- a/libqpdf/QPDF_Name.cc +++ b/libqpdf/QPDF_Name.cc @@ -32,8 +32,7 @@ QPDF_Name::normalizeName(std::string const& name) char ch = name.at(i); // Don't use locale/ctype here; follow PDF spec guidelines. if (ch == '\0') { - // QPDFTokenizer embeds a null character to encode an - // invalid #. + // QPDFTokenizer embeds a null character to encode an invalid #. result += "#"; } else if ( ch < 33 || ch == '#' || ch == '/' || ch == '(' || ch == ')' || ch == '{' || ch == '}' || diff --git a/libqpdf/QPDF_Real.cc b/libqpdf/QPDF_Real.cc index 19b65a7e..1d954dcd 100644 --- a/libqpdf/QPDF_Real.cc +++ b/libqpdf/QPDF_Real.cc @@ -41,9 +41,8 @@ QPDF_Real::unparse() JSON QPDF_Real::getJSON(int json_version) { - // While PDF allows .x or -.x, JSON does not. Rather than - // converting from string to double and back, just handle this as a - // special case for JSON. + // While PDF allows .x or -.x, JSON does not. Rather than converting from string to double and + // back, just handle this as a special case for JSON. std::string result; if (this->val.length() == 0) { // Can't really happen... diff --git a/libqpdf/QPDF_String.cc b/libqpdf/QPDF_String.cc index 386d7672..3886b399 100644 --- a/libqpdf/QPDF_String.cc +++ b/libqpdf/QPDF_String.cc @@ -2,9 +2,8 @@ #include -// DO NOT USE ctype -- it is locale dependent for some things, and -// it's not worth the risk of including it in case it may accidentally -// be used. +// DO NOT USE ctype -- it is locale dependent for some things, and it's not worth the risk of +// including it in case it may accidentally be used. static bool is_iso_latin1_printable(char ch) @@ -62,8 +61,7 @@ QPDF_String::getJSON(int json_version) } else if (!useHexString()) { std::string test; if (QUtil::utf8_to_pdf_doc(candidate, test, '?') && (test == this->val)) { - // This is a PDF-doc string that can be losslessly encoded - // as Unicode. + // This is a PDF-doc string that can be losslessly encoded as Unicode. is_unicode = true; result = candidate; } @@ -79,9 +77,8 @@ QPDF_String::getJSON(int json_version) bool QPDF_String::useHexString() const { - // Heuristic: use the hexadecimal representation of a string if - // there are any non-printable (in PDF Doc encoding) characters or - // if too large of a proportion of the string consists of + // Heuristic: use the hexadecimal representation of a string if there are any non-printable (in + // PDF Doc encoding) characters or if too large of a proportion of the string consists of // non-ASCII characters. unsigned int non_ascii = 0; for (auto const ch: this->val) { @@ -172,8 +169,8 @@ QPDF_String::getUTF8Val() const if (QUtil::is_utf16(this->val)) { return QUtil::utf16_to_utf8(this->val); } else if (QUtil::is_explicit_utf8(this->val)) { - // PDF 2.0 allows UTF-8 strings when explicitly prefixed with - // the three-byte representation of U+FEFF. + // PDF 2.0 allows UTF-8 strings when explicitly prefixed with the three-byte representation + // of U+FEFF. return this->val.substr(3); } else { return QUtil::pdf_doc_to_utf8(this->val); diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc index 5fa3c9ca..76d6bfd5 100644 --- a/libqpdf/QUtil.cc +++ b/libqpdf/QUtil.cc @@ -296,9 +296,8 @@ template static std::string int_to_string_base_internal(T num, int base, int length) { - // Backward compatibility -- int_to_string, which calls this - // function, used to use sprintf with %0*d, so we interpret length - // such that a negative value appends spaces and a positive value + // Backward compatibility -- int_to_string, which calls this function, used to use sprintf with + // %0*d, so we interpret length such that a negative value appends spaces and a positive value // prepends zeroes. if (!((base == 8) || (base == 10) || (base == 16))) { throw std::logic_error("int_to_string_base called with unsupported base"); @@ -352,9 +351,8 @@ QUtil::uint_to_string_base(unsigned long long num, int base, int length) std::string QUtil::double_to_string(double num, int decimal_places, bool trim_trailing_zeroes) { - // Backward compatibility -- this code used to use sprintf and - // treated decimal_places <= 0 to mean to use the default, which - // was six decimal places. Starting in 10.2, we trim trailing + // Backward compatibility -- this code used to use sprintf and treated decimal_places <= 0 to + // mean to use the default, which was six decimal places. Starting in 10.2, we trim trailing // zeroes by default. if (decimal_places <= 0) { decimal_places = 6; @@ -739,8 +737,8 @@ std::string QUtil::hex_decode(std::string const& input) { std::string result; - // We know result.size() <= 0.5 * input.size() + 1. However, reserving - // string space for this upper bound has a negative impact. + // We know result.size() <= 0.5 * input.size() + 1. However, reserving string space for this + // upper bound has a negative impact. bool first = true; char decoded; for (auto ch: input) { @@ -1003,15 +1001,12 @@ QUtil::toUTF8(unsigned long uval) { std::string result; - // A UTF-8 encoding of a Unicode value is a single byte for - // Unicode values <= 127. For larger values, the first byte of - // the UTF-8 encoding has '1' as each of its n highest bits and - // '0' for its (n+1)th highest bit where n is the total number of - // bytes required. Subsequent bytes start with '10' and have the - // remaining 6 bits free for encoding. For example, an 11-bit - // Unicode value can be stored in two bytes where the first is - // 110zzzzz, the second is 10zzzzzz, and the z's represent the - // remaining bits. + // A UTF-8 encoding of a Unicode value is a single byte for Unicode values <= 127. For larger + // values, the first byte of the UTF-8 encoding has '1' as each of its n highest bits and '0' + // for its (n+1)th highest bit where n is the total number of bytes required. Subsequent bytes + // start with '10' and have the remaining 6 bits free for encoding. For example, an 11-bit + // Unicode value can be stored in two bytes where the first is 110zzzzz, the second is 10zzzzzz, + // and the z's represent the remaining bits. if (uval > 0x7fffffff) { throw std::runtime_error("bounds error in QUtil::toUTF8"); @@ -1026,8 +1021,7 @@ QUtil::toUTF8(unsigned long uval) unsigned char maxval = 0x3f; // six bits while (uval > QIntC::to_ulong(maxval)) { - // Assign low six bits plus 10000000 to lowest unused - // byte position, then shift + // Assign low six bits plus 10000000 to lowest unused byte position, then shift *cur_byte = static_cast(0x80 + (uval & 0x3f)); uval >>= 6; // Maximum that will fit in high byte now shrinks by one bit @@ -1038,8 +1032,7 @@ QUtil::toUTF8(unsigned long uval) } --cur_byte; } - // If maxval is k bits long, the high (7 - k) bits of the - // resulting byte must be high. + // If maxval is k bits long, the high (7 - k) bits of the resulting byte must be high. *cur_byte = static_cast(QIntC::to_ulong(0xff - (1 + (maxval << 1))) + uval); result += reinterpret_cast(cur_byte); @@ -1265,8 +1258,7 @@ QUtil::read_lines_from_file( if (preserve_eol) { buf->append(1, c); } else { - // Remove any carriage return that preceded the - // newline and discard the newline + // Remove any carriage return that preceded the newline and discard the newline if ((!buf->empty()) && ((*(buf->rbegin())) == '\r')) { buf->erase(buf->length() - 1); } @@ -1391,8 +1383,7 @@ QUtil::parse_numrange(char const* range, int max) p = nullptr; for (size_t i = 0; i < work.size(); i += 2) { int num = work.at(i); - // max == 0 means we don't know the max and are just - // testing for valid syntax. + // max == 0 means we don't know the max and are just testing for valid syntax. if ((max > 0) && ((num < 1) || (num > max))) { throw std::runtime_error("number " + QUtil::int_to_string(num) + " out of range"); } @@ -1519,21 +1510,18 @@ transcode_utf8(std::string const& utf8_val, std::string& result, encoding_e enco result += "\xfe\xff"; break; case e_pdfdoc: - // We need to avoid having the result start with something - // that will be interpreted as UTF-16 or UTF-8, meaning we - // can't end up with a string that starts with "fe ff", - // (UTF-16-BE) "ff fe" (UTF-16-LE, not officially part of the - // PDF spec, but recognized by most readers including qpdf), - // or "ef bb bf" (UTF-8). It's more efficient to check the - // input string to see if it will map to one of those - // sequences than to check the output string since all cases - // start with the same starting character. + // We need to avoid having the result start with something that will be interpreted as + // UTF-16 or UTF-8, meaning we can't end up with a string that starts with "fe ff", + // (UTF-16-BE) "ff fe" (UTF-16-LE, not officially part of the PDF spec, but recognized by + // most readers including qpdf), or "ef bb bf" (UTF-8). It's more efficient to check the + // input string to see if it will map to one of those sequences than to check the output + // string since all cases start with the same starting character. if ((len >= 4) && (utf8_val[0] == '\xc3')) { static std::string fe_ff("\xbe\xc3\xbf"); static std::string ff_fe("\xbf\xc3\xbe"); static std::string ef_bb_bf("\xaf\xc2\xbb\xc2\xbf"); - // C++-20 has starts_with, but when this was written, qpdf - // had a minimum supported version of C++-17. + // C++-20 has starts_with, but when this was written, qpdf had a minimum supported + // version of C++-17. if ((utf8_val.compare(1, 3, fe_ff) == 0) || (utf8_val.compare(1, 3, ff_fe) == 0) || (utf8_val.compare(1, 5, ef_bb_bf) == 0)) { result += unknown; @@ -1560,10 +1548,9 @@ transcode_utf8(std::string const& utf8_val, std::string& result, encoding_e enco if (encoding == e_utf16) { result += QUtil::toUTF16(QIntC::to_ulong(ch)); } else if ((encoding == e_pdfdoc) && (((ch >= 0x18) && (ch <= 0x1f)) || (ch == 127))) { - // PDFDocEncoding maps some low characters to Unicode, - // so if we encounter those invalid UTF-8 code points, - // map them to unknown so reversing the mapping - // doesn't change them into other characters. + // PDFDocEncoding maps some low characters to Unicode, so if we encounter those + // invalid UTF-8 code points, map them to unknown so reversing the mapping doesn't + // change them into other characters. okay = false; result.append(1, unknown); } else { @@ -1682,10 +1669,9 @@ std::string QUtil::utf16_to_utf8(std::string const& val) { std::string result; - // This code uses unsigned long and unsigned short to hold - // codepoint values. It requires unsigned long to be at least - // 32 bits and unsigned short to be at least 16 bits, but it - // will work fine if they are larger. + // This code uses unsigned long and unsigned short to hold codepoint values. It requires + // unsigned long to be at least 32 bits and unsigned short to be at least 16 bits, but it will + // work fine if they are larger. unsigned long codepoint = 0L; size_t len = val.length(); size_t start = 0; @@ -1696,14 +1682,11 @@ QUtil::utf16_to_utf8(std::string const& val) } start += 2; } - // If the string has an odd number of bytes, the last byte is - // ignored. + // If the string has an odd number of bytes, the last byte is ignored. for (size_t i = start; i + 1 < len; i += 2) { - // Convert from UTF16-BE. If we get a malformed - // codepoint, this code will generate incorrect output - // without giving a warning. Specifically, a high - // codepoint not followed by a low codepoint will be - // discarded, and a low codepoint not preceded by a high + // Convert from UTF16-BE. If we get a malformed codepoint, this code will generate + // incorrect output without giving a warning. Specifically, a high codepoint not followed + // by a low codepoint will be discarded, and a low codepoint not preceded by a high // codepoint will just get its low 10 bits output. auto msb = is_le ? i + 1 : i; auto lsb = is_le ? i : i + 1; @@ -1829,8 +1812,7 @@ QUtil::possible_repaired_encodings(std::string supplied) } std::string output; if (is_valid_utf8) { - // Maybe we were given UTF-8 but wanted one of the single-byte - // encodings. + // Maybe we were given UTF-8 but wanted one of the single-byte encodings. if (utf8_to_pdf_doc(supplied, output)) { result.push_back(output); } @@ -1841,8 +1823,7 @@ QUtil::possible_repaired_encodings(std::string supplied) result.push_back(output); } } else { - // Maybe we were given one of the single-byte encodings but - // wanted UTF-8. + // Maybe we were given one of the single-byte encodings but wanted UTF-8. std::string from_pdf_doc(pdf_doc_to_utf8(supplied)); result.push_back(from_pdf_doc); std::string from_win_ansi(win_ansi_to_utf8(supplied)); @@ -1850,8 +1831,8 @@ QUtil::possible_repaired_encodings(std::string supplied) std::string from_mac_roman(mac_roman_to_utf8(supplied)); result.push_back(from_mac_roman); - // Maybe we were given one of the other single-byte encodings - // but wanted one of the other ones. + // Maybe we were given one of the other single-byte encodings but wanted one of the other + // ones. if (utf8_to_win_ansi(from_pdf_doc, output)) { result.push_back(output); } @@ -1888,9 +1869,8 @@ static int call_main_from_wmain( bool, int argc, wchar_t const* const argv[], std::function realmain) { - // argv contains UTF-16-encoded strings with a 16-bit wchar_t. - // Convert this to UTF-8-encoded strings for compatibility with - // other systems. That way the rest of qpdf.cc can just act like + // argv contains UTF-16-encoded strings with a 16-bit wchar_t. Convert this to UTF-8-encoded + // strings for compatibility with other systems. That way the rest of qpdf.cc can just act like // arguments are UTF-8. std::vector> utf8_argv; @@ -1950,16 +1930,13 @@ QUtil::get_max_memory_usage() fprintf(stderr, "%s", buf); } - // Warning: this code uses regular expression to extract data from - // an XML string. This is generally a bad idea, but we're going to - // do it anyway because QUtil.hh warns against using this function - // for other than development/testing, and if this function fails - // to generate reasonable output during performance testing, it - // will be noticed. + // Warning: this code uses regular expression to extract data from an XML string. This is + // generally a bad idea, but we're going to do it anyway because QUtil.hh warns against using + // this function for other than development/testing, and if this function fails to generate + // reasonable output during performance testing, it will be noticed. - // This is my best guess at how to interpret malloc_info. Anyway - // it seems to provide useful information for detecting code - // changes that drastically change memory usage. + // This is my best guess at how to interpret malloc_info. Anyway it seems to provide useful + // information for detecting code changes that drastically change memory usage. size_t result = 0; try { std::cregex_iterator m_begin(buf, buf + size, tag_re); diff --git a/libqpdf/SecureRandomDataProvider.cc b/libqpdf/SecureRandomDataProvider.cc index c47c8707..64199903 100644 --- a/libqpdf/SecureRandomDataProvider.cc +++ b/libqpdf/SecureRandomDataProvider.cc @@ -89,10 +89,9 @@ SecureRandomDataProvider::provideRandomData(unsigned char* data, size_t len) # elif defined(RANDOM_DEVICE) - // Optimization: wrap the file open and close in a class so that - // the file is closed in a destructor, then make this static to - // keep the file handle open. Only do this if it can be done in a - // thread-safe fashion. + // Optimization: wrap the file open and close in a class so that the file is closed in a + // destructor, then make this static to keep the file handle open. Only do this if it can be + // done in a thread-safe fashion. FILE* f = QUtil::safe_fopen(RANDOM_DEVICE, "rb"); size_t fr = fread(data, 1, len, f); fclose(f); diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc index 05568558..fe2a608e 100644 --- a/libqpdf/qpdf-c.cc +++ b/libqpdf/qpdf-c.cc @@ -269,9 +269,8 @@ qpdf_read(qpdf_data qpdf, char const* filename, char const* password) qpdf->filename = filename; qpdf->password = password; status = trap_errors(qpdf, &call_read); - // We no longer have a good way to exercise a file with both - // warnings and errors because qpdf is getting much better at - // recovering. + // We no longer have a good way to exercise a file with both warnings and errors because qpdf is + // getting much better at recovering. QTC::TC( "qpdf", "qpdf-c called qpdf_read", @@ -806,9 +805,8 @@ template static RET trap_oh_errors(qpdf_data qpdf, std::function fallback, std::function fn) { - // Note: fallback is a function so we don't have to evaluate it - // unless needed. This is important because sometimes the fallback - // creates an object. + // Note: fallback is a function so we don't have to evaluate it unless needed. This is important + // because sometimes the fallback creates an object. RET ret; QPDF_ERROR_CODE status = trap_errors(qpdf, [&ret, fn](qpdf_data q) { ret = fn(q); }); if (status & QPDF_ERRORS) { @@ -820,9 +818,8 @@ trap_oh_errors(qpdf_data qpdf, std::function fallback, std::functionqpdf->getFilename(), "", 0, - "C API function caught an exception that it isn't" - " returning; please point the application developer" - " to ERROR HANDLING in qpdf-c.h")); + "C API function caught an exception that it isn't returning; please point the " + "application developer to ERROR HANDLING in qpdf-c.h")); qpdf->oh_error_occurred = true; } *QPDFLogger::defaultLogger()->getError() << qpdf->error->what() << "\n"; diff --git a/libqpdf/qpdf/BitStream.hh b/libqpdf/qpdf/BitStream.hh index b807f56c..329c486d 100644 --- a/libqpdf/qpdf/BitStream.hh +++ b/libqpdf/qpdf/BitStream.hh @@ -12,8 +12,7 @@ class BitStream void reset(); unsigned long long getBits(size_t nbits); long long getBitsSigned(size_t nbits); - // Only call getBitsInt when requesting a number of bits that will - // definitely fit in an int. + // Only call getBitsInt when requesting a number of bits that definitely fit in an int. int getBitsInt(size_t nbits); void skipToNextByte(); diff --git a/libqpdf/qpdf/BitWriter.hh b/libqpdf/qpdf/BitWriter.hh index 33fdd8f4..24c74162 100644 --- a/libqpdf/qpdf/BitWriter.hh +++ b/libqpdf/qpdf/BitWriter.hh @@ -10,8 +10,8 @@ class Pipeline; class BitWriter { public: - // Write bits to the pipeline. It is the caller's responsibility - // to eventually call finish on the pipeline. + // Write bits to the pipeline. It is the caller's responsibility to eventually call finish on + // the pipeline. BitWriter(Pipeline* pl); void writeBits(unsigned long long val, size_t bits); void writeBitsSigned(long long val, size_t bits); diff --git a/libqpdf/qpdf/JSONHandler.hh b/libqpdf/qpdf/JSONHandler.hh index e4a76af5..8fdcaee6 100644 --- a/libqpdf/qpdf/JSONHandler.hh +++ b/libqpdf/qpdf/JSONHandler.hh @@ -7,37 +7,32 @@ #include #include -// This class allows a sax-like walk through a JSON object with -// functionality that mostly mirrors QPDFArgParser. It is primarily -// here to facilitate automatic generation of some of the code to help -// keep QPDFJob json consistent with command-line arguments. +// This class allows a sax-like walk through a JSON object with functionality that mostly mirrors +// QPDFArgParser. It is primarily here to facilitate automatic generation of some of the code to +// help keep QPDFJob json consistent with command-line arguments. class JSONHandler { public: - // A QPDFUsage exception is thrown if there are any errors - // validating the JSON object. + // A QPDFUsage exception is thrown if there are any errors validating the JSON object. JSONHandler(); ~JSONHandler() = default; - // Based on the type of handler, expect the object to be of a - // certain type. QPDFUsage is thrown otherwise. Multiple handlers - // may be registered, which allows the object to be of various - // types. If an anyHandler is added, no other handler will be - // called. There is no "final" handler -- if the top-level is a - // dictionary or array, just use its end handler. + // Based on the type of handler, expect the object to be of a certain type. QPDFUsage is thrown + // otherwise. Multiple handlers may be registered, which allows the object to be of various + // types. If an anyHandler is added, no other handler will be called. There is no "final" + // handler -- if the top-level is a dictionary or array, just use its end handler. typedef std::function json_handler_t; typedef std::function void_handler_t; typedef std::function string_handler_t; typedef std::function bool_handler_t; - // If an any handler is added, it will be called for any value - // including null, and no other handler will be called. + // If an any handler is added, it will be called for any value including null, and no other + // handler will be called. void addAnyHandler(json_handler_t fn); - // If any of the remaining handlers are registered, each - // registered handle will be called. + // If any of the remaining handlers are registered, each registered handle will be called. void addNullHandler(void_handler_t fn); void addStringHandler(string_handler_t fn); void addNumberHandler(string_handler_t fn); diff --git a/libqpdf/qpdf/MD5.hh b/libqpdf/qpdf/MD5.hh index 977cd4b5..be97edb5 100644 --- a/libqpdf/qpdf/MD5.hh +++ b/libqpdf/qpdf/MD5.hh @@ -29,8 +29,7 @@ class MD5 // computes a raw digest void digest(Digest); - // prints the digest to stdout terminated with \r\n (primarily for - // testing) + // prints the digest to stdout terminated with \r\n (primarily for testing) void print(); // returns the digest as a hexadecimal string diff --git a/libqpdf/qpdf/NNTree.hh b/libqpdf/qpdf/NNTree.hh index 6345b105..4b5ba200 100644 --- a/libqpdf/qpdf/NNTree.hh +++ b/libqpdf/qpdf/NNTree.hh @@ -104,9 +104,8 @@ class NNTreeImpl iterator insert(QPDFObjectHandle key, QPDFObjectHandle value); bool remove(QPDFObjectHandle key, QPDFObjectHandle* value = nullptr); - // Change the split threshold for easier testing. There's no real - // reason to expose this to downstream tree helpers, but it has to - // be public so we can call it from the test suite. + // Change the split threshold for easier testing. There's no real reason to expose this to + // downstream tree helpers, but it has to be public so we can call it from the test suite. void setSplitThreshold(int split_threshold); private: diff --git a/libqpdf/qpdf/OffsetInputSource.hh b/libqpdf/qpdf/OffsetInputSource.hh index 2d506f80..f9246363 100644 --- a/libqpdf/qpdf/OffsetInputSource.hh +++ b/libqpdf/qpdf/OffsetInputSource.hh @@ -1,8 +1,8 @@ #ifndef QPDF_OFFSETINPUTSOURCE_HH #define QPDF_OFFSETINPUTSOURCE_HH -// This class implements an InputSource that proxies for an underlying -// input source but offset a specific number of bytes. +// This class implements an InputSource that proxies for an underlying input source but offset a +// specific number of bytes. #include diff --git a/libqpdf/qpdf/Pl_AES_PDF.hh b/libqpdf/qpdf/Pl_AES_PDF.hh index b3fde312..32f4c351 100644 --- a/libqpdf/qpdf/Pl_AES_PDF.hh +++ b/libqpdf/qpdf/Pl_AES_PDF.hh @@ -5,8 +5,8 @@ #include #include -// This pipeline implements AES-128 and AES-256 with CBC and block -// padding as specified in the PDF specification. +// This pipeline implements AES-128 and AES-256 with CBC and block padding as specified in the PDF +// specification. class Pl_AES_PDF: public Pipeline { diff --git a/libqpdf/qpdf/Pl_MD5.hh b/libqpdf/qpdf/Pl_MD5.hh index bd56f9c6..5763d6eb 100644 --- a/libqpdf/qpdf/Pl_MD5.hh +++ b/libqpdf/qpdf/Pl_MD5.hh @@ -1,13 +1,11 @@ #ifndef PL_MD5_HH #define PL_MD5_HH -// This pipeline sends its output to its successor unmodified. After -// calling finish, the MD5 checksum of the data that passed through -// the pipeline is available. +// This pipeline sends its output to its successor unmodified. After calling finish, the MD5 +// checksum of the data that passed through the pipeline is available. -// This pipeline is reusable; i.e., it is safe to call write() after -// calling finish(). The first call to write() after a call to -// finish() initializes a new MD5 object. +// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). The first +// call to write() after a call to finish() initializes a new MD5 object. #include #include @@ -20,15 +18,12 @@ class Pl_MD5: public Pipeline virtual void write(unsigned char const*, size_t); virtual void finish(); std::string getHexDigest(); - // Enable/disable. Disabling the pipeline causes it to become a - // pass-through. This makes it possible to stick an MD5 pipeline - // in a pipeline when it may or may not be required. Disabling it - // avoids incurring the runtime overhead of doing needless - // digest computation. + // Enable/disable. Disabling the pipeline causes it to become a pass-through. This makes it + // possible to stick an MD5 pipeline in a pipeline when it may or may not be required. Disabling + // it avoids incurring the runtime overhead of doing needless digest computation. void enable(bool enabled); - // If persistAcrossFinish is called, calls to finish do not - // finalize the underlying md5 object. In this case, the object is - // not finalized until getHexDigest() is called. + // If persistAcrossFinish is called, calls to finish do not finalize the underlying md5 object. + // In this case, the object is not finalized until getHexDigest() is called. void persistAcrossFinish(bool); private: diff --git a/libqpdf/qpdf/Pl_PNGFilter.hh b/libqpdf/qpdf/Pl_PNGFilter.hh index 7ab7bf0d..ed8e1e9c 100644 --- a/libqpdf/qpdf/Pl_PNGFilter.hh +++ b/libqpdf/qpdf/Pl_PNGFilter.hh @@ -1,11 +1,11 @@ #ifndef PL_PNGFILTER_HH #define PL_PNGFILTER_HH -// This pipeline applies or reverses the application of a PNG filter -// as described in the PNG specification. +// This pipeline applies or reverses the application of a PNG filter as described in the PNG +// specification. -// NOTE: In its current implementation, this filter always encodes -// using the "up" filter, but it decodes all the filters. +// NOTE: In its current implementation, this filter always encodes using the "up" filter, but it +// decodes all the filters. #include diff --git a/libqpdf/qpdf/Pl_SHA2.hh b/libqpdf/qpdf/Pl_SHA2.hh index 571271eb..9b3275f0 100644 --- a/libqpdf/qpdf/Pl_SHA2.hh +++ b/libqpdf/qpdf/Pl_SHA2.hh @@ -1,16 +1,13 @@ #ifndef PL_SHA2_HH #define PL_SHA2_HH -// Bits must be a supported number of bits, currently only 256, 384, -// or 512. Passing 0 as bits leaves the pipeline uncommitted, in -// which case resetBits must be called before the pipeline is used. -// If a next is provided, this pipeline sends its output to its -// successor unmodified. After calling finish, the SHA2 checksum of -// the data that passed through the pipeline is available. +// Bits must be a supported number of bits, currently only 256, 384, or 512. Passing 0 as bits +// leaves the pipeline uncommitted, in which case resetBits must be called before the pipeline is +// used. If a next is provided, this pipeline sends its output to its successor unmodified. After +// calling finish, the SHA2 checksum of the data that passed through the pipeline is available. -// This pipeline is reusable; i.e., it is safe to call write() after -// calling finish(). The first call to write() after a call to -// finish() initializes a new SHA2 object. resetBits may also be +// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). The first +// call to write() after a call to finish() initializes a new SHA2 object. resetBits may also be // called between finish and the next call to write. #include diff --git a/libqpdf/qpdf/Pl_TIFFPredictor.hh b/libqpdf/qpdf/Pl_TIFFPredictor.hh index 6bc48e72..21757593 100644 --- a/libqpdf/qpdf/Pl_TIFFPredictor.hh +++ b/libqpdf/qpdf/Pl_TIFFPredictor.hh @@ -1,8 +1,8 @@ #ifndef PL_TIFFPREDICTOR_HH #define PL_TIFFPREDICTOR_HH -// This pipeline reverses the application of a TIFF predictor as -// described in the TIFF specification. +// This pipeline reverses the application of a TIFF predictor as described in the TIFF +// specification. #include diff --git a/libqpdf/qpdf/QPDFArgParser.hh b/libqpdf/qpdf/QPDFArgParser.hh index d9e33b5a..3b22a805 100644 --- a/libqpdf/qpdf/QPDFArgParser.hh +++ b/libqpdf/qpdf/QPDFArgParser.hh @@ -9,41 +9,33 @@ #include #include -// This is not a general-purpose argument parser. It is tightly -// crafted to work with qpdf. qpdf's command-line syntax is very -// complex because of its long history, and it doesn't really follow -// any kind of normal standard for arguments, but it's important for -// backward compatibility to ensure we don't break what constitutes a -// valid command. This class handles the quirks of qpdf's argument -// parsing, bash/zsh completion, and support for @argfile to read -// arguments from a file. For the qpdf CLI, setup of QPDFArgParser is -// done mostly by automatically-generated code (one-off code for -// qpdf), though the handlers themselves are hand-coded. See -// generate_auto_job at the top of the source tree for details. +// This is not a general-purpose argument parser. It is tightly crafted to work with qpdf. qpdf's +// command-line syntax is very complex because of its long history, and it doesn't really follow any +// kind of normal standard for arguments, but it's important for backward compatibility to ensure we +// don't break what constitutes a valid command. This class handles the quirks of qpdf's argument +// parsing, bash/zsh completion, and support for @argfile to read arguments from a file. For the +// qpdf CLI, setup of QPDFArgParser is done mostly by automatically-generated code (one-off code for +// qpdf), though the handlers themselves are hand-coded. See generate_auto_job at the top of the +// source tree for details. class QPDFArgParser { public: - // progname_env is used to override argv[0] when figuring out the - // name of the executable for setting up completion. This may be - // needed if the program is invoked by a wrapper. + // progname_env is used to override argv[0] when figuring out the name of the executable for + // setting up completion. This may be needed if the program is invoked by a wrapper. QPDFArgParser(int argc, char const* const argv[], char const* progname_env); - // Calls exit(0) if a help option is given or if in completion - // mode. If there are argument parsing errors, QPDFUsage is - // thrown. + // Calls exit(0) if a help option is given or if in completion mode. If there are argument + // parsing errors, QPDFUsage is thrown. void parseArgs(); - // Return the program name as the last path element of the program - // executable. + // Return the program name as the last path element of the program executable. std::string getProgname(); - // Methods for registering arguments. QPDFArgParser starts off - // with the main option table selected. You can add handlers for - // arguments in the current option table, and you can select which - // option table is current. The help option table is special and - // contains arguments that are only valid as the first and only - // option. Named option tables are for subparsers and always start - // a series of options that end with `--`. + // Methods for registering arguments. QPDFArgParser starts off with the main option table + // selected. You can add handlers for arguments in the current option table, and you can select + // which option table is current. The help option table is special and contains arguments that + // are only valid as the first and only option. Named option tables are for subparsers and + // always start a series of options that end with `--`. typedef std::function bare_arg_handler_t; typedef std::function param_arg_handler_t; @@ -65,9 +57,8 @@ class QPDFArgParser void addChoices(std::string const& arg, param_arg_handler_t, bool required, char const** choices); - // The default behavior when an invalid choice is specified with - // an option that takes choices is to list all the choices. This - // may not be good if there are too many choices, so you can + // The default behavior when an invalid choice is specified with an option that takes choices is + // to list all the choices. This may not be good if there are too many choices, so you can // provide your own handler in this case. void addInvalidChoiceHandler(std::string const& arg, param_arg_handler_t); @@ -77,42 +68,33 @@ class QPDFArgParser // Help generation methods - // Help is available on topics and options. Options may be - // associated with topics. Users can run --help, --help=topic, or - // --help=--arg to get help. The top-level help tells the user how - // to run help and lists available topics. Help for a topic prints - // a short synopsis about the topic and lists any options that may - // be associated with the topic. Help for an option provides a - // short synopsis for that option. All help output is appended - // with a blurb (if supplied) directing the user to the full - // documentation. Help is not shown for options for which help has - // not been added. This makes it possible to have undocumented - // options for testing, backward-compatibility, etc. Also, it - // could be quite confusing to handle appropriate help for some - // inner options that may be repeated with different semantics - // inside different option tables. There is also no checking for - // whether an option that has help actually exists. In other - // words, it's up to the caller to ensure that help actually - // corresponds to the program's actual options. Rather than this - // being an intentional design decision, it is because this class - // is specifically for qpdf, qpdf generates its help and has other - // means to ensure consistency. + // Help is available on topics and options. Options may be associated with topics. Users can run + // --help, --help=topic, or --help=--arg to get help. The top-level help tells the user how + // to run help and lists available topics. Help for a topic prints a short synopsis about the + // topic and lists any options that may be associated with the topic. Help for an option + // provides a short synopsis for that option. All help output is appended with a blurb (if + // supplied) directing the user to the full documentation. Help is not shown for options for + // which help has not been added. This makes it possible to have undocumented options for + // testing, backward-compatibility, etc. Also, it could be quite confusing to handle appropriate + // help for some inner options that may be repeated with different semantics inside different + // option tables. There is also no checking for whether an option that has help actually exists. + // In other words, it's up to the caller to ensure that help actually corresponds to the + // program's actual options. Rather than this being an intentional design decision, it is + // because this class is specifically for qpdf, qpdf generates its help and has other means to + // ensure consistency. // Note about newlines: // - // short_text should fit easily after the topic/option on the same - // line and should not end with a newline. Keep it to around 40 to - // 60 characters. + // short_text should fit easily after the topic/option on the same line and should not end with + // a newline. Keep it to around 40 to 60 characters. // - // long_text and footer should end with a single newline. They can - // have embedded newlines. Keep lines to under 80 columns. + // long_text and footer should end with a single newline. They can have embedded newlines. Keep + // lines to under 80 columns. // - // QPDFArgParser does reformat the text, but it may add blank - // lines in some situations. Following the above conventions will - // keep the help looking uniform. + // QPDFArgParser does reformat the text, but it may add blank lines in some situations. + // Following the above conventions will keep the help looking uniform. - // If provided, this footer is appended to all help, separated by - // a blank line. + // If provided, this footer is appended to all help, separated by a blank line. void addHelpFooter(std::string const&); // Add a help topic along with the text for that topic @@ -126,14 +108,12 @@ class QPDFArgParser std::string const& short_text, std::string const& long_text); - // Return the help text for a topic or option. Passing a null - // pointer returns the top-level help information. Passing an - // unknown value returns a string directing the user to run the + // Return the help text for a topic or option. Passing a null pointer returns the top-level help + // information. Passing an unknown value returns a string directing the user to run the // top-level --help option. std::string getHelp(std::string const& topic_or_option); - // Convenience methods for adding member functions of a class as - // handlers. + // Convenience methods for adding member functions of a class as handlers. template static bare_arg_handler_t bindBare(void (T::*f)(), T* o) @@ -147,21 +127,19 @@ class QPDFArgParser return std::bind(std::mem_fn(f), o, std::placeholders::_1); } - // When processing arguments, indicate how many arguments remain - // after the one whose handler is being called. + // When processing arguments, indicate how many arguments remain after the one whose handler is + // being called. int argsLeft() const; // Indicate whether we are in completion mode. bool isCompleting() const; - // Insert a completion during argument parsing; useful for - // customizing completion in the position argument handler. Should - // only be used in completion mode. + // Insert a completion during argument parsing; useful for customizing completion in the + // position argument handler. Should only be used in completion mode. void insertCompletion(std::string const&); - // Throw a Usage exception with the given message. In completion - // mode, this just exits to prevent errors from partial commands - // or other error messages from messing up completion. + // Throw a Usage exception with the given message. In completion mode, this just exits to + // prevent errors from partial commands or other error messages from messing up completion. void usage(std::string const& message); private: diff --git a/libqpdf/qpdf/QPDFCrypto_gnutls.hh b/libqpdf/qpdf/QPDFCrypto_gnutls.hh index efec1bbf..00f25857 100644 --- a/libqpdf/qpdf/QPDFCrypto_gnutls.hh +++ b/libqpdf/qpdf/QPDFCrypto_gnutls.hh @@ -4,8 +4,8 @@ #include #include -// gnutls headers must be last to prevent them from interfering with -// other headers. gnutls.h has to be included first. +// gnutls headers must be last to prevent them from interfering with other headers. gnutls.h has to +// be included first. #include // This comment prevents clang-format from putting crypto.h before gnutls.h #include diff --git a/libqpdf/qpdf/QPDFObject_private.hh b/libqpdf/qpdf/QPDFObject_private.hh index bbd6ccf1..5e87c215 100644 --- a/libqpdf/qpdf/QPDFObject_private.hh +++ b/libqpdf/qpdf/QPDFObject_private.hh @@ -1,9 +1,8 @@ #ifndef QPDFOBJECT_HH #define QPDFOBJECT_HH -// NOTE: This file is called QPDFObject_private.hh instead of -// QPDFObject.hh because of include/qpdf/QPDFObject.hh. See comments -// there for an explanation. +// NOTE: This file is called QPDFObject_private.hh instead of QPDFObject.hh because of +// include/qpdf/QPDFObject.hh. See comments there for an explanation. #include #include @@ -51,8 +50,7 @@ class QPDFObject return value->type_code; } - // Return a string literal that describes the type, useful for - // debugging and testing + // Return a string literal that describes the type, useful for debugging and testing char const* getTypeName() const { @@ -146,14 +144,12 @@ class QPDFObject void disconnect() { - // Disconnect an object from its owning QPDF. This is called - // by QPDF's destructor. + // Disconnect an object from its owning QPDF. This is called by QPDF's destructor. value->disconnect(); value->qpdf = nullptr; value->og = QPDFObjGen(); } - // Mark an object as destroyed. Used by QPDF's destructor for its - // indirect objects. + // Mark an object as destroyed. Used by QPDF's destructor for its indirect objects. void destroy(); bool diff --git a/libqpdf/qpdf/QPDF_Dictionary.hh b/libqpdf/qpdf/QPDF_Dictionary.hh index bf3dfb2d..da38db7a 100644 --- a/libqpdf/qpdf/QPDF_Dictionary.hh +++ b/libqpdf/qpdf/QPDF_Dictionary.hh @@ -19,16 +19,15 @@ class QPDF_Dictionary: public QPDFValue virtual JSON getJSON(int json_version); virtual void disconnect(); - // hasKey() and getKeys() treat keys with null values as if they - // aren't there. getKey() returns null for the value of a - // non-existent key. This is as per the PDF spec. + // hasKey() and getKeys() treat keys with null values as if they aren't there. getKey() returns + // null for the value of a non-existent key. This is as per the PDF spec. bool hasKey(std::string const&); QPDFObjectHandle getKey(std::string const&); std::set getKeys(); std::map const& getAsMap() const; - // If value is null, remove key; otherwise, replace the value of - // key, adding it if it does not exist. + // If value is null, remove key; otherwise, replace the value of key, adding it if it does not + // exist. void replaceKey(std::string const& key, QPDFObjectHandle value); // Remove key, doing nothing if key does not exist void removeKey(std::string const& key); diff --git a/libqpdf/qpdf/RC4.hh b/libqpdf/qpdf/RC4.hh index 257e6980..08bde7a3 100644 --- a/libqpdf/qpdf/RC4.hh +++ b/libqpdf/qpdf/RC4.hh @@ -11,8 +11,7 @@ class RC4 // key_len of -1 means treat key_data as a null-terminated string RC4(unsigned char const* key_data, int key_len = -1); - // It is safe to pass the same pointer to in_data and out_data to - // encrypt/decrypt in place + // It is safe to pass the same pointer to in_data and out_data to encrypt/decrypt in place void process(unsigned char const* in_data, size_t len, unsigned char* out_data); private: