Here is a patch for #117, text object and ASCII concat (doc and tests are a gift :-) ).
## # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: [email protected] # target_branch: file:///home/gerel/PROJECTS/libgnupdf/trunk/ # testament_sha1: a7212288530d544b47338d3218e29a37ac1faf0b # timestamp: 2010-04-19 01:13:01 -0300 # base_revision_id: [email protected] # # Begin patch === modified file 'ChangeLog' --- ChangeLog 2010-04-18 11:13:22 +0000 +++ ChangeLog 2010-04-19 04:12:57 +0000 @@ -1,3 +1,19 @@ +2010-04-18 Gerardo E. Gidoni <[email protected]> + + Added new method pdf_text_concat_ascii() + * doc/gnupdf.texi: added its documentation. + + * src/base/pdf-text.c: added implementation. + + * src/base/pdf-text.h: likewise. + + * torture/unit/Makefile.am: test implementation. + + * torture/unit/base/text/tsuite-text.c: likewise. + + * torture/unit/base/text/pdf-text-concat-ascii.c: likewise. + + 2010-04-15 Jose E. Marchesi <[email protected]> Remove spurious blank lines before EOF in the codebase. === modified file 'doc/gnupdf.texi' --- doc/gnupdf.texi 2010-04-13 20:50:45 +0000 +++ doc/gnupdf.texi 2010-04-19 04:12:57 +0000 @@ -6573,6 +6573,39 @@ @end table @end deftypefun + +...@deftypefun pdf_status_t pdf_text_concat_ascii (pdf_text_t @var{text1}, const pdf_char_t * @var{ascii_str}) + +Concatenate the contents of text variable @var{text1} with ASCII string @var{ascii_str}, +and store the result in @var{text1}. + +...@table @strong +...@item Parameters +...@table @var +...@item text1 +The first text variable to concatenate. The contents of this variable +are modified with the output of the concatenation. +...@item ascii_str +The ascii string to concatenate. The contents of this variable +are left unchanged. +...@end table +...@item Returns +The status of the operation. +...@item Usage Example +...@example +pdf_text_t text1; +pdf_char_t * str; + +/* ...initialize `text1' and `str... */ +if (pdf_text_concat_ascii (text1, str) != PDF_OK) +...@{ + /* Manage the error */ +...@} +...@end example +...@end table +...@end deftypefun + + @deftypefun pdf_status_t pdf_text_replace (pdf_text_t @var{text}, const pdf_text_t @var{new_pattern}, const pdf_text_t @var{old_pattern}) Replace a fixed pattern in the content of a given text variable. === modified file 'src/base/pdf-text.c' --- src/base/pdf-text.c 2010-02-20 16:02:07 +0000 +++ src/base/pdf-text.c 2010-04-19 04:12:57 +0000 @@ -1024,6 +1024,52 @@ } +/* Concatenate a text variable with an ascii string */ +pdf_status_t +pdf_text_concat_ascii (pdf_text_t text1, + const pdf_char_t * ascii_str) +{ + pdf_size_t len; + + len = (pdf_size_t) strlen ((char*)ascii_str); + if (!pdf_text_is_ascii7 (ascii_str, len)) + { + return PDF_EBADDATA; + } + + /* now convert to utf32he and concatenate */ + if(len > 0) + { + pdf_char_t * newbuf; + pdf_status_t ret; + pdf_char_t *tmp_data; + pdf_size_t tmp_size; + + /* ascii string is valid utf8 */ + ret = pdf_text_utf8_to_utf32he (ascii_str, len, &tmp_data, &tmp_size); + if (ret != PDF_OK) + { + return ret; + } + + newbuf = (pdf_char_t *)pdf_realloc (text1->data, text1->size + tmp_size); + if (newbuf == NULL) + { + return PDF_ENOMEM; + } + else + { + text1->data = newbuf; + } + + memcpy (&(text1->data[text1->size]), tmp_data, tmp_size); + text1->size += tmp_size; + pdf_dealloc (tmp_data); + } + + return PDF_OK; +} + /* Default initial size of the list of replacements */ #define PDF_TEXT_ISLR 32 === modified file 'src/base/pdf-text.h' --- src/base/pdf-text.h 2010-02-20 16:02:07 +0000 +++ src/base/pdf-text.h 2010-04-19 04:12:57 +0000 @@ -282,6 +282,10 @@ const pdf_text_t text2, const pdf_bool_t override_langinfo); +/* Concatenate a text variable with an ascii string */ +pdf_status_t +pdf_text_concat_ascii (pdf_text_t text1, + const pdf_char_t * ascii_str); /* Replace a fixed pattern in the content of a given text variable */ pdf_status_t === modified file 'torture/unit/Makefile.am' --- torture/unit/Makefile.am 2010-02-19 01:03:33 +0000 +++ torture/unit/Makefile.am 2010-04-19 04:12:57 +0000 @@ -151,6 +151,7 @@ base/text/pdf-text-set-pdfdocenc.c \ base/text/pdf-text-set-unicode.c \ base/text/pdf-text-concat.c \ + base/text/pdf-text-concat-ascii.c \ base/text/pdf-text-replace.c \ base/text/pdf-text-replace-ascii.c \ base/text/pdf-text-filter.c \ === added file 'torture/unit/base/text/pdf-text-concat-ascii.c' --- torture/unit/base/text/pdf-text-concat-ascii.c 1970-01-01 00:00:00 +0000 +++ torture/unit/base/text/pdf-text-concat-ascii.c 2010-04-19 04:12:57 +0000 @@ -0,0 +1,227 @@ +/* -*- mode: C -*- + * + * File: pdf-text-concat-ascii.c + * Date: Mon Mar 10 18:30:01 2008 + * + * GNU PDF Library - Text Module - pdf_text_concat_ascii test case + * + */ + +/* Copyright (C) 2008 Free Software Foundation, Inc. */ + +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <stdio.h> +#include <string.h> +#include <pdf.h> +#include <check.h> + +/* + * Test: pdf_text_concat_ascii_001 + * Description: + * Concatenate text object and non-empty ascii string. + * Success conditions: + * 1. The call to pdf_text_concat_ascii should return PDF_OK. + * 2. The contents of the output text object must be the expected ones. + * 3. The lang/country information in the output object must remain unchanged. + */ +START_TEST(pdf_text_concat_ascii_001) +{ + pdf_char_t *output_data = NULL; + pdf_text_t text1 = NULL; + pdf_char_t * text2 = " Unix"; + pdf_char_t *country = (pdf_char_t *)"GB"; + pdf_char_t *language = (pdf_char_t *)"en"; + + /* Always INIT! Check runs each test in a different process */ + fail_if(pdf_init() != PDF_OK); + + fail_if(pdf_text_new (&text1) != PDF_OK); + + fail_if(pdf_text_set_pdfdocenc(text1, (pdf_char_t *)"GNU's not") != PDF_OK); + + fail_if(pdf_text_set_language(text1, language) != PDF_OK); + fail_if(pdf_text_set_country(text1, country) != PDF_OK); + + /* 1. The call to pdf_text_concat_ascii should return PDF_OK. */ + fail_unless(pdf_text_concat_ascii(text1, text2) == PDF_OK); + + /* 2. The contents of the output text object must be the expected ones. */ + fail_if(pdf_text_get_pdfdocenc(&output_data, text1) != PDF_OK); + fail_unless(strlen((char *)output_data) == strlen("GNU's not Unix")); + fail_unless(strcmp((char *)output_data, "GNU's not Unix") == 0); + + /* 3. The lang/country information in the output object must remain + * unchanged. */ + fail_unless(strcmp((char *)pdf_text_get_language(text1), + (char *)language) == 0); + fail_unless(strcmp((char *)pdf_text_get_country(text1), + (char *)country) == 0); + + pdf_text_destroy(text1); + pdf_dealloc(output_data); +} +END_TEST + + +/* + * Test: pdf_text_concat_ascii_002 + * Description: + * Concatenate text object without lang/country with non-empty ascii string. + * Success conditions: + * 1. The call to pdf_text_concat_ascii should return PDF_OK. + * 2. The contents of the output text object must be the expected ones. + * 3. The lang/country information in the output object must be empty. + */ +START_TEST(pdf_text_concat_ascii_002) +{ + pdf_char_t *output_data = NULL; + pdf_text_t text1 = NULL; + pdf_char_t * text2 = " Unix"; + + /* Always INIT! Check runs each test in a different process */ + fail_if(pdf_init() != PDF_OK); + + fail_if(pdf_text_new (&text1) != PDF_OK); + + fail_if(pdf_text_set_pdfdocenc(text1, (pdf_char_t *)"GNU's not") != PDF_OK); + + /* 1. The call to pdf_text_concat_ascii should return PDF_OK. */ + fail_unless(pdf_text_concat_ascii(text1, text2) == PDF_OK); + + /* 2. The contents of the output text object must be the expected ones. */ + fail_if(pdf_text_get_pdfdocenc(&output_data, text1) != PDF_OK); + fail_unless(strlen((char *)output_data) == strlen("GNU's not Unix")); + fail_unless(strcmp((char *)output_data, "GNU's not Unix") == 0); + + /* 3. The lang/country information in the output object must be empty. */ + fail_unless(strlen((char *)pdf_text_get_language(text1)) == 0); + fail_unless(strlen((char *)pdf_text_get_country(text1)) == 0); + + pdf_text_destroy(text1); + pdf_dealloc(output_data); +} +END_TEST + + +/* + * Test: pdf_text_concat_ascii_003 + * Description: + * Concatenate text object with empty string. + * Success conditions: + * 1. The call to pdf_text_concat_ascii should return PDF_OK. + * 2. The contents of the output text object should be empty. + * 3. The lang/country information in the output object must remain unchanged. + */ +START_TEST(pdf_text_concat_ascii_003) +{ + pdf_char_t *output_data = NULL; + pdf_text_t text1 = NULL; + pdf_char_t * text2 = ""; + pdf_char_t *country = (pdf_char_t *)"GB"; + pdf_char_t *language = (pdf_char_t *)"en"; + + /* Always INIT! Check runs each test in a different process */ + fail_if(pdf_init() != PDF_OK); + + fail_if(pdf_text_new (&text1) != PDF_OK); + + fail_if(pdf_text_set_pdfdocenc(text1, (pdf_char_t *)"GNU's not Unix") != PDF_OK); + fail_if(pdf_text_set_language(text1, language) != PDF_OK); + fail_if(pdf_text_set_country(text1, country) != PDF_OK); + + /* 1. The call to pdf_text_concat_ascii should return PDF_OK. */ + fail_unless(pdf_text_concat_ascii(text1, text2) == PDF_OK); + + /* 2. The contents of the output text object should be empty. */ + fail_if(pdf_text_get_pdfdocenc(&output_data, text1) != PDF_OK); + fail_unless(strlen((char *)output_data) == strlen("GNU's not Unix")); + fail_unless(strcmp((char *)output_data, "GNU's not Unix") == 0); + + /* 3. The lang/country information in the output object must remain + * unchanged. */ + fail_unless(strcmp((char *)pdf_text_get_language(text1), + (char *)language) == 0); + fail_unless(strcmp((char *)pdf_text_get_country(text1), + (char *)country) == 0); + + pdf_text_destroy(text1); + pdf_dealloc(output_data); +} +END_TEST + +/* + * Test: pdf_text_concat_ascii_004 + * Description: + * Concatenate empty text object with empty string. + * Success conditions: + * 1. The call to pdf_text_concat_ascii should return PDF_OK. + * 2. The contents of the output text object should be empty. + * 3. The lang/country information in the output object must remain unchanged. + */ +START_TEST(pdf_text_concat_ascii_004) +{ + pdf_char_t *output_data = NULL; + pdf_text_t text1 = NULL; + pdf_char_t * text2 = ""; + pdf_char_t *country = (pdf_char_t *)"GB"; + pdf_char_t *language = (pdf_char_t *)"en"; + + /* Always INIT! Check runs each test in a different process */ + fail_if(pdf_init() != PDF_OK); + + fail_if(pdf_text_new (&text1) != PDF_OK); + + fail_if(pdf_text_set_pdfdocenc(text1, (pdf_char_t *)"") != PDF_OK); + fail_if(pdf_text_set_language(text1, language) != PDF_OK); + fail_if(pdf_text_set_country(text1, country) != PDF_OK); + + /* 1. The call to pdf_text_concat_ascii should return PDF_OK. */ + fail_unless(pdf_text_concat_ascii(text1, text2) == PDF_OK); + + /* 2. The contents of the output text object should be empty. */ + fail_if(pdf_text_get_pdfdocenc(&output_data, text1) != PDF_OK); + fail_unless(strlen((char *)output_data) == 0); + + /* 3. The lang/country information in the output object must remain + * unchanged. */ + fail_unless(strcmp((char *)pdf_text_get_language(text1), + (char *)language) == 0); + fail_unless(strcmp((char *)pdf_text_get_country(text1), + (char *)country) == 0); + + pdf_text_destroy(text1); + pdf_dealloc(output_data); +} +END_TEST + + + +/* + * Test case creation function + */ +TCase * +test_pdf_text_concat_ascii (void) +{ + TCase *tc = tcase_create("pdf_text_concat_ascii"); + tcase_add_test(tc, pdf_text_concat_ascii_001); + tcase_add_test(tc, pdf_text_concat_ascii_002); + tcase_add_test(tc, pdf_text_concat_ascii_003); + tcase_add_test(tc, pdf_text_concat_ascii_004); + return tc; +} + +/* End of pdf-text-concat-ascii.c */ === modified file 'torture/unit/base/text/tsuite-text.c' --- torture/unit/base/text/tsuite-text.c 2010-02-20 16:02:07 +0000 +++ torture/unit/base/text/tsuite-text.c 2010-04-19 04:12:57 +0000 @@ -49,6 +49,7 @@ extern TCase *test_pdf_text_set_pdfdocenc (void); extern TCase *test_pdf_text_set_unicode (void); extern TCase *test_pdf_text_concat (void); +extern TCase *test_pdf_text_concat_ascii (void); extern TCase *test_pdf_text_replace (void); extern TCase *test_pdf_text_replace_ascii (void); extern TCase *test_pdf_text_filter (void); @@ -83,6 +84,7 @@ suite_add_tcase (s, test_pdf_text_set_pdfdocenc()); suite_add_tcase (s, test_pdf_text_set_unicode()); suite_add_tcase (s, test_pdf_text_concat()); + suite_add_tcase (s, test_pdf_text_concat_ascii()); suite_add_tcase (s, test_pdf_text_replace()); suite_add_tcase (s, test_pdf_text_replace_ascii()); suite_add_tcase (s, test_pdf_text_filter()); # Begin bundle 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 ### -gerel
