mirror of
				https://github.com/michaelrsweet/pdfio.git
				synced 2025-10-31 10:26:22 +01:00 
			
		
		
		
	Implement pdfioDictIterateKeys API (Issue #31)
This commit is contained in:
		| @@ -6,6 +6,7 @@ v1.1.0 (Month DD, YYYY) | |||||||
| ----------------------- | ----------------------- | ||||||
|  |  | ||||||
| - Added `pdfioFileCreateTemporary` function (Issue #29) | - Added `pdfioFileCreateTemporary` function (Issue #29) | ||||||
|  | - Added `pdfioDictIterateKeys` function (Issue #31) | ||||||
|  |  | ||||||
|  |  | ||||||
| v1.0.1 (March 2, 2022) | v1.0.1 (March 2, 2022) | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								doc/pdfio.3
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								doc/pdfio.3
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| .TH pdfio 3 "pdf read/write library" "2022-05-15" "pdf read/write library" | .TH pdfio 3 "pdf read/write library" "2022-06-27" "pdf read/write library" | ||||||
| .SH NAME | .SH NAME | ||||||
| pdfio \- pdf read/write library | pdfio \- pdf read/write library | ||||||
| .SH Introduction | .SH Introduction | ||||||
| @@ -1950,6 +1950,31 @@ pdfio_valtype_t  pdfioDictGetType ( | |||||||
|     const char *key |     const char *key | ||||||
| ); | ); | ||||||
| .fi | .fi | ||||||
|  | .SS pdfioDictIterateKeys | ||||||
|  | Iterate the keys in a dictionary. | ||||||
|  | .PP | ||||||
|  | .nf | ||||||
|  | void pdfioDictIterateKeys ( | ||||||
|  |     pdfio_dict_t *dict, | ||||||
|  |     pdfio_dict_cb_t cb, | ||||||
|  |     void *cb_data | ||||||
|  | ); | ||||||
|  | .fi | ||||||
|  | .PP | ||||||
|  | This function iterates the keys in a dictionary, calling the supplied | ||||||
|  | function "cb": | ||||||
|  | .PP | ||||||
|  | .nf | ||||||
|  |     bool | ||||||
|  |     my_dict_cb(pdfio_dict_t *dict, const char *key, void *cb_data) | ||||||
|  |     { | ||||||
|  |     ... "key" contains the dictionary key ... | ||||||
|  |     ... return true to continue or false to stop ... | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | .fi | ||||||
|  | The iteration continues as long as the callback returns \fBtrue\fR or all keys | ||||||
|  | have been iterated. | ||||||
| .SS pdfioDictSetArray | .SS pdfioDictSetArray | ||||||
| Set a key array in a dictionary. | Set a key array in a dictionary. | ||||||
| .PP | .PP | ||||||
| @@ -2889,6 +2914,12 @@ Standard color spaces | |||||||
| .nf | .nf | ||||||
| typedef enum pdfio_cs_e pdfio_cs_t; | typedef enum pdfio_cs_e pdfio_cs_t; | ||||||
| .fi | .fi | ||||||
|  | .SS pdfio_dict_cb_t | ||||||
|  | Dictionary iterator callback | ||||||
|  | .PP | ||||||
|  | .nf | ||||||
|  | typedef bool(*)(pdfio_dict_t *dict, const char *key, void *cb_data) pdfio_dict_cb_t; | ||||||
|  | .fi | ||||||
| .SS pdfio_dict_t | .SS pdfio_dict_t | ||||||
| Key/value dictionary | Key/value dictionary | ||||||
| .PP | .PP | ||||||
|   | |||||||
| @@ -360,6 +360,7 @@ span.string { | |||||||
| <li><a href="#pdfioDictGetRect">pdfioDictGetRect</a></li> | <li><a href="#pdfioDictGetRect">pdfioDictGetRect</a></li> | ||||||
| <li><a href="#pdfioDictGetString">pdfioDictGetString</a></li> | <li><a href="#pdfioDictGetString">pdfioDictGetString</a></li> | ||||||
| <li><a href="#pdfioDictGetType">pdfioDictGetType</a></li> | <li><a href="#pdfioDictGetType">pdfioDictGetType</a></li> | ||||||
|  | <li><a href="#pdfioDictIterateKeys">pdfioDictIterateKeys</a></li> | ||||||
| <li><a href="#pdfioDictSetArray">pdfioDictSetArray</a></li> | <li><a href="#pdfioDictSetArray">pdfioDictSetArray</a></li> | ||||||
| <li><a href="#pdfioDictSetBinary">pdfioDictSetBinary</a></li> | <li><a href="#pdfioDictSetBinary">pdfioDictSetBinary</a></li> | ||||||
| <li><a href="#pdfioDictSetBoolean">pdfioDictSetBoolean</a></li> | <li><a href="#pdfioDictSetBoolean">pdfioDictSetBoolean</a></li> | ||||||
| @@ -443,6 +444,7 @@ span.string { | |||||||
| <li><a href="#TYPES">Data Types</a><ul class="subcontents"> | <li><a href="#TYPES">Data Types</a><ul class="subcontents"> | ||||||
| <li><a href="#pdfio_array_t">pdfio_array_t</a></li> | <li><a href="#pdfio_array_t">pdfio_array_t</a></li> | ||||||
| <li><a href="#pdfio_cs_t">pdfio_cs_t</a></li> | <li><a href="#pdfio_cs_t">pdfio_cs_t</a></li> | ||||||
|  | <li><a href="#pdfio_dict_cb_t">pdfio_dict_cb_t</a></li> | ||||||
| <li><a href="#pdfio_dict_t">pdfio_dict_t</a></li> | <li><a href="#pdfio_dict_t">pdfio_dict_t</a></li> | ||||||
| <li><a href="#pdfio_encryption_t">pdfio_encryption_t</a></li> | <li><a href="#pdfio_encryption_t">pdfio_encryption_t</a></li> | ||||||
| <li><a href="#pdfio_error_cb_t">pdfio_error_cb_t</a></li> | <li><a href="#pdfio_error_cb_t">pdfio_error_cb_t</a></li> | ||||||
| @@ -2262,6 +2264,33 @@ const char *pdfioDictGetString(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict, c | |||||||
| </tbody></table> | </tbody></table> | ||||||
| <h4 class="returnvalue">Return Value</h4> | <h4 class="returnvalue">Return Value</h4> | ||||||
| <p class="description">Value type</p> | <p class="description">Value type</p> | ||||||
|  | <h3 class="function"><a id="pdfioDictIterateKeys">pdfioDictIterateKeys</a></h3> | ||||||
|  | <p class="description">Iterate the keys in a dictionary.</p> | ||||||
|  | <p class="code"> | ||||||
|  | void pdfioDictIterateKeys(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict, <a href="#pdfio_dict_cb_t">pdfio_dict_cb_t</a> cb, void *cb_data);</p> | ||||||
|  | <h4 class="parameters">Parameters</h4> | ||||||
|  | <table class="list"><tbody> | ||||||
|  | <tr><th>dict</th> | ||||||
|  | <td class="description">Dictionary</td></tr> | ||||||
|  | <tr><th>cb</th> | ||||||
|  | <td class="description">Callback function</td></tr> | ||||||
|  | <tr><th>cb_data</th> | ||||||
|  | <td class="description">Callback data</td></tr> | ||||||
|  | </tbody></table> | ||||||
|  | <h4 class="discussion">Discussion</h4> | ||||||
|  | <p class="discussion">This function iterates the keys in a dictionary, calling the supplied | ||||||
|  | function "cb": | ||||||
|  |  | ||||||
|  | <pre> | ||||||
|  | bool | ||||||
|  | my_dict_cb(pdfio_dict_t *dict, const char *key, void *cb_data) | ||||||
|  | { | ||||||
|  | ... "key" contains the dictionary key ... | ||||||
|  | ... return true to continue or false to stop ... | ||||||
|  | } | ||||||
|  | </pre> | ||||||
|  | The iteration continues as long as the callback returns <code>true</code> or all keys | ||||||
|  | have been iterated.</p> | ||||||
| <h3 class="function"><a id="pdfioDictSetArray">pdfioDictSetArray</a></h3> | <h3 class="function"><a id="pdfioDictSetArray">pdfioDictSetArray</a></h3> | ||||||
| <p class="description">Set a key array in a dictionary.</p> | <p class="description">Set a key array in a dictionary.</p> | ||||||
| <p class="code"> | <p class="code"> | ||||||
| @@ -3514,6 +3543,11 @@ typedef struct _pdfio_array_s pdfio_array_t; | |||||||
| <p class="code"> | <p class="code"> | ||||||
| typedef enum <a href="#pdfio_cs_e">pdfio_cs_e</a> pdfio_cs_t; | typedef enum <a href="#pdfio_cs_e">pdfio_cs_e</a> pdfio_cs_t; | ||||||
| </p> | </p> | ||||||
|  | <h3 class="typedef"><a id="pdfio_dict_cb_t">pdfio_dict_cb_t</a></h3> | ||||||
|  | <p class="description">Dictionary iterator callback</p> | ||||||
|  | <p class="code"> | ||||||
|  | typedef bool (*pdfio_dict_cb_t)(<a href="#pdfio_dict_t">pdfio_dict_t</a> *dict, const char *key, void *cb_data); | ||||||
|  | </p> | ||||||
| <h3 class="typedef"><a id="pdfio_dict_t">pdfio_dict_t</a></h3> | <h3 class="typedef"><a id="pdfio_dict_t">pdfio_dict_t</a></h3> | ||||||
| <p class="description">Key/value dictionary</p> | <p class="description">Key/value dictionary</p> | ||||||
| <p class="code"> | <p class="code"> | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								pdfio-dict.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								pdfio-dict.c
									
									
									
									
									
								
							| @@ -464,6 +464,47 @@ _pdfioDictGetValue(pdfio_dict_t *dict,	// I - Dictionary | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // | ||||||
|  | // 'pdfioDictIterateKeys()' - Iterate the keys in a dictionary. | ||||||
|  | // | ||||||
|  | // This function iterates the keys in a dictionary, calling the supplied | ||||||
|  | // function "cb": | ||||||
|  | // | ||||||
|  | // ``` | ||||||
|  | // bool | ||||||
|  | // my_dict_cb(pdfio_dict_t *dict, const char *key, void *cb_data) | ||||||
|  | // { | ||||||
|  | // ... "key" contains the dictionary key ... | ||||||
|  | // ... return true to continue or false to stop ... | ||||||
|  | // } | ||||||
|  | // ``` | ||||||
|  | // | ||||||
|  | // The iteration continues as long as the callback returns `true` or all keys | ||||||
|  | // have been iterated. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | void | ||||||
|  | pdfioDictIterateKeys( | ||||||
|  |     pdfio_dict_t    *dict,		// I - Dictionary | ||||||
|  |     pdfio_dict_cb_t cb,			// I - Callback function | ||||||
|  |     void            *cb_data)		// I - Callback data | ||||||
|  | { | ||||||
|  |   size_t	i;			// Looping var | ||||||
|  |   _pdfio_pair_t	*pair;			// Current pair | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   // Range check input... | ||||||
|  |   if (!dict || !cb) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   for (i = dict->num_pairs, pair = dict->pairs; i > 0; i --, pair ++) | ||||||
|  |   { | ||||||
|  |     if (!(cb)(dict, pair->key, cb_data)) | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| // | // | ||||||
| // '_pdfioDictRead()' - Read a dictionary from a PDF file. | // '_pdfioDictRead()' - Read a dictionary from a PDF file. | ||||||
| // | // | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								pdfio.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								pdfio.h
									
									
									
									
									
								
							| @@ -55,6 +55,8 @@ typedef struct _pdfio_array_s pdfio_array_t; | |||||||
| 					// Array of PDF values | 					// Array of PDF values | ||||||
| typedef struct _pdfio_dict_s pdfio_dict_t; | typedef struct _pdfio_dict_s pdfio_dict_t; | ||||||
| 					// Key/value dictionary | 					// Key/value dictionary | ||||||
|  | typedef bool (*pdfio_dict_cb_t)(pdfio_dict_t *dict, const char *key, void *cb_data); | ||||||
|  | 					// Dictionary iterator callback | ||||||
| typedef struct _pdfio_file_s pdfio_file_t; | typedef struct _pdfio_file_s pdfio_file_t; | ||||||
| 					// PDF file | 					// PDF file | ||||||
| typedef bool (*pdfio_error_cb_t)(pdfio_file_t *pdf, const char *message, void *data); | typedef bool (*pdfio_error_cb_t)(pdfio_file_t *pdf, const char *message, void *data); | ||||||
| @@ -165,6 +167,7 @@ extern pdfio_obj_t	*pdfioDictGetObj(pdfio_dict_t *dict, const char *key) _PDFIO_ | |||||||
| extern pdfio_rect_t	*pdfioDictGetRect(pdfio_dict_t *dict, const char *key, pdfio_rect_t *rect) _PDFIO_PUBLIC; | extern pdfio_rect_t	*pdfioDictGetRect(pdfio_dict_t *dict, const char *key, pdfio_rect_t *rect) _PDFIO_PUBLIC; | ||||||
| extern const char	*pdfioDictGetString(pdfio_dict_t *dict, const char *key) _PDFIO_PUBLIC; | extern const char	*pdfioDictGetString(pdfio_dict_t *dict, const char *key) _PDFIO_PUBLIC; | ||||||
| extern pdfio_valtype_t	pdfioDictGetType(pdfio_dict_t *dict, const char *key) _PDFIO_PUBLIC; | extern pdfio_valtype_t	pdfioDictGetType(pdfio_dict_t *dict, const char *key) _PDFIO_PUBLIC; | ||||||
|  | extern void		pdfioDictIterateKeys(pdfio_dict_t *dict, pdfio_dict_cb_t cb, void *cb_data) _PDFIO_PUBLIC; | ||||||
| extern bool		pdfioDictSetArray(pdfio_dict_t *dict, const char *key, pdfio_array_t *value) _PDFIO_PUBLIC; | extern bool		pdfioDictSetArray(pdfio_dict_t *dict, const char *key, pdfio_array_t *value) _PDFIO_PUBLIC; | ||||||
| extern bool		pdfioDictSetBinary(pdfio_dict_t *dict, const char *key, const unsigned char *value, size_t valuelen) _PDFIO_PUBLIC; | extern bool		pdfioDictSetBinary(pdfio_dict_t *dict, const char *key, const unsigned char *value, size_t valuelen) _PDFIO_PUBLIC; | ||||||
| extern bool		pdfioDictSetBoolean(pdfio_dict_t *dict, const char *key, bool value) _PDFIO_PUBLIC; | extern bool		pdfioDictSetBoolean(pdfio_dict_t *dict, const char *key, bool value) _PDFIO_PUBLIC; | ||||||
|   | |||||||
							
								
								
									
										59
									
								
								testpdfio.c
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								testpdfio.c
									
									
									
									
									
								
							| @@ -34,6 +34,7 @@ static int	do_test_file(const char *filename, int objnum, bool verbose); | |||||||
| static int	do_unit_tests(void); | static int	do_unit_tests(void); | ||||||
| static int	draw_image(pdfio_stream_t *st, const char *name, double x, double y, double w, double h, const char *label); | static int	draw_image(pdfio_stream_t *st, const char *name, double x, double y, double w, double h, const char *label); | ||||||
| static bool	error_cb(pdfio_file_t *pdf, const char *message, bool *error); | static bool	error_cb(pdfio_file_t *pdf, const char *message, bool *error); | ||||||
|  | static bool	iterate_cb(pdfio_dict_t *dict, const char *key, void *cb_data); | ||||||
| static ssize_t	output_cb(int *fd, const void *buffer, size_t bytes); | static ssize_t	output_cb(int *fd, const void *buffer, size_t bytes); | ||||||
| static const char *password_cb(void *data, const char *filename); | static const char *password_cb(void *data, const char *filename); | ||||||
| static int	read_unit_file(const char *filename, size_t num_pages, size_t first_image, bool is_output); | static int	read_unit_file(const char *filename, size_t num_pages, size_t first_image, bool is_output); | ||||||
| @@ -507,6 +508,8 @@ do_unit_tests(void) | |||||||
|   size_t		first_image,	// First image object |   size_t		first_image,	// First image object | ||||||
| 			num_pages;	// Number of pages written | 			num_pages;	// Number of pages written | ||||||
|   char			temppdf[1024];	// Temporary PDF file |   char			temppdf[1024];	// Temporary PDF file | ||||||
|  |   pdfio_dict_t		*dict;		// Test dictionary | ||||||
|  |   int			count = 0;	// Number of key/value pairs | ||||||
|   static const char	*complex_dict =	// Complex dictionary value |   static const char	*complex_dict =	// Complex dictionary value | ||||||
|     "<</Annots 5457 0 R/Contents 5469 0 R/CropBox[0 0 595.4 842]/Group 725 0 R" |     "<</Annots 5457 0 R/Contents 5469 0 R/CropBox[0 0 595.4 842]/Group 725 0 R" | ||||||
|     "/MediaBox[0 0 595.4 842]/Parent 23513 0 R/Resources<</ColorSpace<<" |     "/MediaBox[0 0 595.4 842]/Parent 23513 0 R/Resources<</ColorSpace<<" | ||||||
| @@ -968,6 +971,41 @@ do_unit_tests(void) | |||||||
|  |  | ||||||
|   // TODO: Test for known values in this test file. |   // TODO: Test for known values in this test file. | ||||||
|  |  | ||||||
|  |   // Test dictionary APIs | ||||||
|  |   fputs("pdfioDictCreate: ", stdout); | ||||||
|  |   if ((dict = pdfioDictCreate(inpdf)) != NULL) | ||||||
|  |   { | ||||||
|  |     puts("PASS"); | ||||||
|  |  | ||||||
|  |     fputs("pdfioDictSet*: ", stdout); | ||||||
|  |     if (pdfioDictSetBoolean(dict, "Boolean", true) && pdfioDictSetName(dict, "Name", "Name") && pdfioDictSetNumber(dict, "Number", 42.0) && pdfioDictSetString(dict, "String", "String")) | ||||||
|  |     { | ||||||
|  |       puts("PASS"); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       puts("FAIL"); | ||||||
|  |       return (1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fputs("pdfioDictIterateKeys: ", stdout); | ||||||
|  |     pdfioDictIterateKeys(dict, iterate_cb, &count); | ||||||
|  |     if (count == 4) | ||||||
|  |     { | ||||||
|  |       puts("PASS"); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |       printf("FAIL (got %d, expected 4)\n", count); | ||||||
|  |       return (1); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     puts("FAIL"); | ||||||
|  |     return (1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // Test the value parsers for edge cases... |   // Test the value parsers for edge cases... | ||||||
|   fputs("_pdfioValueRead(complex_dict): ", stdout); |   fputs("_pdfioValueRead(complex_dict): ", stdout); | ||||||
|   s = complex_dict; |   s = complex_dict; | ||||||
| @@ -1212,6 +1250,27 @@ error_cb(pdfio_file_t *pdf,		// I  - PDF file | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // | ||||||
|  | // 'iterate_cb()' - Test pdfioDictIterateKeys function. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | static bool				// O - `true` to continue, `false` to stop | ||||||
|  | iterate_cb(pdfio_dict_t *dict,		// I - Dictionary | ||||||
|  |            const char   *key,		// I - Key | ||||||
|  |            void         *cb_data)	// I - Callback data | ||||||
|  | { | ||||||
|  |   int	*count = (int *)cb_data;	// Pointer to counter | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   if (!dict || !key || !cb_data) | ||||||
|  |     return (false); | ||||||
|  |  | ||||||
|  |   (*count)++; | ||||||
|  |  | ||||||
|  |   return (true); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| // | // | ||||||
| // 'output_cb()' - Write output to a file. | // 'output_cb()' - Write output to a file. | ||||||
| // | // | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user