From b2aa54381811383d4a86fbe7b194907c33e8dcc1 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Tue, 12 May 2015 16:17:04 -0700 Subject: Make (and verify) public/ files compile under C. This involves adding some missing extern "C" { } declarations, using FPDF_ types instead of C++ types, and converting pass by reference arguments into pointers. Test this using fpdfview_embedertest for simplicity. BUG=pdfium:158 R=thestig@chromium.org Review URL: https://codereview.chromium.org/1130843003 --- fpdfsdk/src/fpdfview.cpp | 12 +- fpdfsdk/src/fpdfview_c_api_test.c | 213 ++++++++++++++++++++++++++++++++++ fpdfsdk/src/fpdfview_c_api_test.h | 20 ++++ fpdfsdk/src/fpdfview_embeddertest.cpp | 33 +++--- 4 files changed, 258 insertions(+), 20 deletions(-) create mode 100644 fpdfsdk/src/fpdfview_c_api_test.c create mode 100644 fpdfsdk/src/fpdfview_c_api_test.h (limited to 'fpdfsdk/src') diff --git a/fpdfsdk/src/fpdfview.cpp b/fpdfsdk/src/fpdfview.cpp index d977996232..637ac96abc 100644 --- a/fpdfsdk/src/fpdfview.cpp +++ b/fpdfsdk/src/fpdfview.cpp @@ -825,10 +825,10 @@ DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDestByName(FPDF_DOCUMENT document,FPDF_ return name_tree.LookupNamedDest(pDoc, name); } -DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDest(FPDF_DOCUMENT document, int index, void* buffer, long& buflen) +DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDest(FPDF_DOCUMENT document, int index, void* buffer, long* buflen) { if (!buffer) - buflen = 0; + *buflen = 0; if (!document || index < 0) return NULL; CPDF_Document* pDoc = (CPDF_Document*)document; @@ -865,12 +865,12 @@ DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDest(FPDF_DOCUMENT document, int index, CFX_ByteString utf16Name = wsName.UTF16LE_Encode(); unsigned int len = utf16Name.GetLength(); if (!buffer) { - buflen = len; - } else if (buflen >= len) { + *buflen = len; + } else if (*buflen >= len) { memcpy(buffer, utf16Name.c_str(), len); - buflen = len; + *buflen = len; } else { - buflen = -1; + *buflen = -1; } return (FPDF_DEST)pDestObj; } diff --git a/fpdfsdk/src/fpdfview_c_api_test.c b/fpdfsdk/src/fpdfview_c_api_test.c new file mode 100644 index 0000000000..3fd682d394 --- /dev/null +++ b/fpdfsdk/src/fpdfview_c_api_test.c @@ -0,0 +1,213 @@ +// Copyright 2015 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This "C" (not "C++") file ensures that the public headers compile +// and link for "C" (and not just "C++"). + +#include + +#include "fpdfview_c_api_test.h" + +#include "../../public/fpdf_dataavail.h" +#include "../../public/fpdf_doc.h" +#include "../../public/fpdf_edit.h" +#include "../../public/fpdf_ext.h" +#include "../../public/fpdf_flatten.h" +#include "../../public/fpdf_formfill.h" +#include "../../public/fpdf_fwlevent.h" +#include "../../public/fpdf_ppo.h" +#include "../../public/fpdf_progressive.h" +#include "../../public/fpdf_save.h" +#include "../../public/fpdf_searchex.h" +#include "../../public/fpdf_sysfontinfo.h" +#include "../../public/fpdf_text.h" +#include "../../public/fpdf_transformpage.h" +#include "../../public/fpdfview.h" + +// Scheme for avoiding LTO out of existence, warnings, etc. +typedef void (*fnptr)(void); // Legal generic function type for casts. +fnptr g_c_api_test_fnptr = NULL; // Extern, so can't know it doesn't change. +#define CHK(x) if ((fnptr)(x) == g_c_api_test_fnptr) return 0 + +// Function to call from gtest harness to ensure linker resolution. +int CheckPDFiumCApi() { + // fpdf_dataavail.h + CHK(FPDFAvail_Create); + CHK(FPDFAvail_Destroy); + CHK(FPDFAvail_IsDocAvail); + CHK(FPDFAvail_GetDocument); + CHK(FPDFAvail_GetFirstPageNum); + CHK(FPDFAvail_IsPageAvail); + CHK(FPDFAvail_IsFormAvail); + CHK(FPDFAvail_IsLinearized); + + // fpdf_doc.h + CHK(FPDFBookmark_GetFirstChild); + CHK(FPDFBookmark_GetNextSibling); + CHK(FPDFBookmark_GetTitle); + CHK(FPDFBookmark_Find); + CHK(FPDFBookmark_GetDest); + CHK(FPDFBookmark_GetAction); + CHK(FPDFAction_GetType); + CHK(FPDFAction_GetDest); + CHK(FPDFAction_GetURIPath); + CHK(FPDFDest_GetPageIndex); + CHK(FPDFLink_GetLinkAtPoint); + CHK(FPDFLink_GetDest); + CHK(FPDFLink_GetAction); + CHK(FPDFLink_Enumerate); + CHK(FPDFLink_GetAnnotRect); + CHK(FPDFLink_CountQuadPoints); + CHK(FPDFLink_GetQuadPoints); + CHK(FPDF_GetMetaText); + + // fpdf_edit.h + CHK(FPDF_CreateNewDocument); + CHK(FPDFPage_New); + CHK(FPDFPage_Delete); + CHK(FPDFPage_GetRotation); + CHK(FPDFPage_SetRotation); + CHK(FPDFPage_InsertObject); + CHK(FPDFPage_CountObject); + CHK(FPDFPage_GetObject); + CHK(FPDFPage_HasTransparency); + CHK(FPDFPage_GenerateContent); + CHK(FPDFPageObj_HasTransparency); + CHK(FPDFPageObj_Transform); + CHK(FPDFPage_TransformAnnots); + CHK(FPDFPageObj_NewImgeObj); + CHK(FPDFImageObj_LoadJpegFile); + CHK(FPDFImageObj_SetMatrix); + CHK(FPDFImageObj_SetBitmap); + + // fpdf_ext.h + CHK(FSDK_SetUnSpObjProcessHandler); + CHK(FPDFDoc_GetPageMode); + + // fpdf_flatten.h + CHK(FPDFPage_Flatten); + + // fpdf_fwlevent.h - no exports. + + // fpdf_formfill.h + CHK(FPDFDOC_InitFormFillEnvironment); + CHK(FPDFDOC_ExitFormFillEnvironment); + CHK(FORM_OnAfterLoadPage); + CHK(FORM_OnBeforeClosePage); + CHK(FORM_DoDocumentJSAction); + CHK(FORM_DoDocumentOpenAction); + CHK(FORM_DoDocumentAAction); + CHK(FORM_DoPageAAction); + CHK(FORM_OnMouseMove); + CHK(FORM_OnLButtonDown); + CHK(FORM_OnLButtonUp); + CHK(FORM_OnKeyDown); + CHK(FORM_OnKeyUp); + CHK(FORM_OnChar); + CHK(FORM_ForceToKillFocus); + CHK(FPDPage_HasFormFieldAtPoint); + CHK(FPDF_SetFormFieldHighlightColor); + CHK(FPDF_SetFormFieldHighlightAlpha); + CHK(FPDF_RemoveFormFieldHighlight); + CHK(FPDF_FFLDraw); + + // fpdf_ppo.h + CHK(FPDF_ImportPages); + CHK(FPDF_CopyViewerPreferences); + + // fpdf_progressive.h + CHK(FPDF_RenderPageBitmap_Start); + CHK(FPDF_RenderPage_Continue); + CHK(FPDF_RenderPage_Close); + + // fpdf_save.h + CHK(FPDF_SaveAsCopy); + CHK(FPDF_SaveWithVersion); + + // fpdf_searchex.h + CHK(FPDFText_GetCharIndexFromTextIndex); + + // fpdf_sysfontinfo.h + CHK(FPDF_GetDefaultTTFMap); + CHK(FPDF_AddInstalledFont); + CHK(FPDF_SetSystemFontInfo); + CHK(FPDF_GetDefaultSystemFontInfo); + + // fpdf_text.h + CHK(FPDFText_LoadPage); + CHK(FPDFText_ClosePage); + CHK(FPDFText_CountChars); + CHK(FPDFText_GetUnicode); + CHK(FPDFText_GetFontSize); + CHK(FPDFText_GetCharBox); + CHK(FPDFText_GetCharIndexAtPos); + CHK(FPDFText_GetText); + CHK(FPDFText_CountRects); + CHK(FPDFText_GetRect); + CHK(FPDFText_GetBoundedText); + CHK(FPDFText_FindStart); + CHK(FPDFText_FindNext); + CHK(FPDFText_FindPrev); + CHK(FPDFText_GetSchResultIndex); + CHK(FPDFText_GetSchCount); + CHK(FPDFText_FindClose); + CHK(FPDFLink_LoadWebLinks); + CHK(FPDFLink_CountWebLinks); + CHK(FPDFLink_GetURL); + CHK(FPDFLink_CountRects); + CHK(FPDFLink_GetRect); + CHK(FPDFLink_CloseWebLinks); + + // fpdf_transformpage.h + CHK(FPDFPage_SetMediaBox); + CHK(FPDFPage_SetCropBox); + CHK(FPDFPage_GetMediaBox); + CHK(FPDFPage_GetCropBox); + CHK(FPDFPage_TransFormWithClip); + CHK(FPDFPageObj_TransformClipPath); + CHK(FPDF_CreateClipPath); + CHK(FPDF_DestroyClipPath); + CHK(FPDFPage_InsertClipPath); + + // fpdfview.h + CHK(FPDF_InitLibrary); + CHK(FPDF_DestroyLibrary); + CHK(FPDF_SetSandBoxPolicy); + CHK(FPDF_LoadDocument); + CHK(FPDF_LoadMemDocument); + CHK(FPDF_LoadCustomDocument); + CHK(FPDF_GetFileVersion); + CHK(FPDF_GetLastError); + CHK(FPDF_GetDocPermissions); + CHK(FPDF_GetSecurityHandlerRevision); + CHK(FPDF_GetPageCount); + CHK(FPDF_LoadPage); + CHK(FPDF_GetPageWidth); + CHK(FPDF_GetPageHeight); + CHK(FPDF_GetPageSizeByIndex); + CHK(FPDF_RenderPageBitmap); + CHK(FPDF_ClosePage); + CHK(FPDF_CloseDocument); + CHK(FPDF_DeviceToPage); + CHK(FPDF_PageToDevice); + CHK(FPDFBitmap_Create); + CHK(FPDFBitmap_CreateEx); + CHK(FPDFBitmap_FillRect); + CHK(FPDFBitmap_GetBuffer); + CHK(FPDFBitmap_GetWidth); + CHK(FPDFBitmap_GetHeight); + CHK(FPDFBitmap_GetStride); + CHK(FPDFBitmap_Destroy); + CHK(FPDF_VIEWERREF_GetPrintScaling); + CHK(FPDF_VIEWERREF_GetNumCopies); + CHK(FPDF_VIEWERREF_GetPrintPageRange); + CHK(FPDF_VIEWERREF_GetDuplex); + CHK(FPDF_CountNamedDests); + CHK(FPDF_GetNamedDestByName); + CHK(FPDF_GetNamedDest); + + return 1; +} + +#undef CHK diff --git a/fpdfsdk/src/fpdfview_c_api_test.h b/fpdfsdk/src/fpdfview_c_api_test.h new file mode 100644 index 0000000000..755d8215c9 --- /dev/null +++ b/fpdfsdk/src/fpdfview_c_api_test.h @@ -0,0 +1,20 @@ +// Copyright 2015 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FPDFSDK_SRC_FPDFVIEW_C_API_TEST_H_ +#define FPDFSDK_SRC_FPDFVIEW_C_API_TEST_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// Function to call from gtest harness to ensure linker resolution. Returns +// 1 on success or 0 on error. +int CheckPDFiumCApi(); + +#ifdef __cplusplus +} +#endif + +#endif // FPDFSDK_SRC_FPDFVIEW_C_API_TEST_H_ diff --git a/fpdfsdk/src/fpdfview_embeddertest.cpp b/fpdfsdk/src/fpdfview_embeddertest.cpp index b8f692111a..f885aa663a 100644 --- a/fpdfsdk/src/fpdfview_embeddertest.cpp +++ b/fpdfsdk/src/fpdfview_embeddertest.cpp @@ -7,8 +7,13 @@ #include "../../public/fpdfview.h" #include "../../testing/embedder_test.h" +#include "fpdfview_c_api_test.h" #include "testing/gtest/include/gtest/gtest.h" +TEST(fpdf, CApiTest) { + EXPECT_TRUE(CheckPDFiumCApi()); +} + class FPDFViewEmbeddertest : public EmbedderTest { }; @@ -50,20 +55,20 @@ TEST_F(FPDFViewEmbeddertest, NamedDests) { // Query the size of the first item. buffer_size = 2000000; // Absurdly large, check not used for this case. - dest = FPDF_GetNamedDest(document(), 0, nullptr, buffer_size); + dest = FPDF_GetNamedDest(document(), 0, nullptr, &buffer_size); EXPECT_NE(nullptr, dest); EXPECT_EQ(12u, buffer_size); // Try to retrieve the first item with too small a buffer. buffer_size = 10; - dest = FPDF_GetNamedDest(document(), 0, fixed_buffer, buffer_size); + dest = FPDF_GetNamedDest(document(), 0, fixed_buffer, &buffer_size); EXPECT_NE(nullptr, dest); EXPECT_EQ(-1, buffer_size); // Try to retrieve the first item with correctly sized buffer. Item is // taken from Dests NameTree in named_dests.pdf. buffer_size = 12; - dest = FPDF_GetNamedDest(document(), 0, fixed_buffer, buffer_size); + dest = FPDF_GetNamedDest(document(), 0, fixed_buffer, &buffer_size); EXPECT_NE(nullptr, dest); EXPECT_EQ(12u, buffer_size); EXPECT_EQ(std::string("F\0i\0r\0s\0t\0\0\0", 12), @@ -72,7 +77,7 @@ TEST_F(FPDFViewEmbeddertest, NamedDests) { // Try to retrieve the second item with ample buffer. Item is taken // from Dests NameTree but has a sub-dictionary in named_dests.pdf. buffer_size = sizeof(fixed_buffer); - dest = FPDF_GetNamedDest(document(), 1, fixed_buffer, buffer_size); + dest = FPDF_GetNamedDest(document(), 1, fixed_buffer, &buffer_size); EXPECT_NE(nullptr, dest); EXPECT_EQ(10u, buffer_size); EXPECT_EQ(std::string("N\0e\0x\0t\0\0\0", 10), @@ -82,21 +87,21 @@ TEST_F(FPDFViewEmbeddertest, NamedDests) { // from Dests NameTree but has a bad sub-dictionary in named_dests.pdf. // in named_dests.pdf). buffer_size = sizeof(fixed_buffer); - dest = FPDF_GetNamedDest(document(), 2, fixed_buffer, buffer_size); + dest = FPDF_GetNamedDest(document(), 2, fixed_buffer, &buffer_size); EXPECT_EQ(nullptr, dest); EXPECT_EQ(sizeof(fixed_buffer), buffer_size); // unmodified. // Try to retrieve the forth item with ample buffer. Item is taken // from Dests NameTree but has a vale of the wrong type in named_dests.pdf. buffer_size = sizeof(fixed_buffer); - dest = FPDF_GetNamedDest(document(), 3, fixed_buffer, buffer_size); + dest = FPDF_GetNamedDest(document(), 3, fixed_buffer, &buffer_size); EXPECT_EQ(nullptr, dest); EXPECT_EQ(sizeof(fixed_buffer), buffer_size); // unmodified. // Try to retrieve fifth item with ample buffer. Item taken from the // old-style Dests dictionary object in named_dests.pdf. buffer_size = sizeof(fixed_buffer); - dest = FPDF_GetNamedDest(document(), 4, fixed_buffer, buffer_size); + dest = FPDF_GetNamedDest(document(), 4, fixed_buffer, &buffer_size); EXPECT_NE(nullptr, dest); EXPECT_EQ(30u, buffer_size); EXPECT_EQ( @@ -107,7 +112,7 @@ TEST_F(FPDFViewEmbeddertest, NamedDests) { // old-style Dests dictionary object but has a sub-dictionary in // named_dests.pdf. buffer_size = sizeof(fixed_buffer); - dest = FPDF_GetNamedDest(document(), 5, fixed_buffer, buffer_size); + dest = FPDF_GetNamedDest(document(), 5, fixed_buffer, &buffer_size); EXPECT_NE(nullptr, dest); EXPECT_EQ(28u, buffer_size); EXPECT_EQ( @@ -116,25 +121,25 @@ TEST_F(FPDFViewEmbeddertest, NamedDests) { // Try to retrieve non-existent item with ample buffer. buffer_size = sizeof(fixed_buffer); - dest = FPDF_GetNamedDest(document(), 6, fixed_buffer, buffer_size); + dest = FPDF_GetNamedDest(document(), 6, fixed_buffer, &buffer_size); EXPECT_EQ(nullptr, dest); EXPECT_EQ(sizeof(fixed_buffer), buffer_size); // unmodified. // Try to underflow/overflow the integer index. buffer_size = sizeof(fixed_buffer); dest = FPDF_GetNamedDest(document(), std::numeric_limits::max(), - fixed_buffer, buffer_size); + fixed_buffer, &buffer_size); EXPECT_EQ(nullptr, dest); EXPECT_EQ(sizeof(fixed_buffer), buffer_size); // unmodified. buffer_size = sizeof(fixed_buffer); dest = FPDF_GetNamedDest(document(), std::numeric_limits::min(), - fixed_buffer, buffer_size); + fixed_buffer, &buffer_size); EXPECT_EQ(nullptr, dest); EXPECT_EQ(sizeof(fixed_buffer), buffer_size); // unmodified. buffer_size = sizeof(fixed_buffer); - dest = FPDF_GetNamedDest(document(), -1, fixed_buffer, buffer_size); + dest = FPDF_GetNamedDest(document(), -1, fixed_buffer, &buffer_size); EXPECT_EQ(nullptr, dest); EXPECT_EQ(sizeof(fixed_buffer), buffer_size); // unmodified. } @@ -156,7 +161,7 @@ TEST_F(FPDFViewEmbeddertest, NamedDestsByName) { long ignore_len = 0; FPDF_DEST dest_by_index = - FPDF_GetNamedDest(document(), 0, nullptr, ignore_len); + FPDF_GetNamedDest(document(), 0, nullptr, &ignore_len); EXPECT_EQ(dest_by_index, dest); // Item from Dests dictionary. @@ -164,7 +169,7 @@ TEST_F(FPDFViewEmbeddertest, NamedDestsByName) { EXPECT_NE(nullptr, dest); ignore_len = 0; - dest_by_index = FPDF_GetNamedDest(document(), 4, nullptr, ignore_len); + dest_by_index = FPDF_GetNamedDest(document(), 4, nullptr, &ignore_len); EXPECT_EQ(dest_by_index, dest); // Bad value type for item from Dests NameTree array. -- cgit v1.2.3