Hello again, attached is an updated version of the patch that:
* Improves the conversions between GooString and std::string.
* Fixes the spacing (And yes, the spacing wasn't broken. I was broken. I
just can't get my head around 2 spaces indentation with an 8 spaces tab.
Sorry for that.)
* Extends UnicodeMap to become a move-only type so that the
initialization can stay basically the same as when using GooHash storing
pointers to UnicodeMap.
Best regards, ADam.
Am 21.02.2018 um 07:13 schrieb Adam Reichold:
> Hello again,
>
> Am 21.02.2018 um 00:31 schrieb Albert Astals Cid:
>> El dimarts, 20 de febrer de 2018, a les 8:58:24 CET, Adam Reichold va
>> escriure:
>>> Hello again,
>>>
>>> Am 18.02.2018 um 23:23 schrieb Adam Reichold:
>>>> Am 18.02.2018 um 23:08 schrieb Albert Astals Cid:
>>>>> El diumenge, 18 de febrer de 2018, a les 16:55:37 CET, Adam Reichold va
>>>>>
>>>>> escriure:
>>>>>> Hello,
>>>>>>
>>>>>> the attached patch replaced Poppler's internal hash table implementation
>>>>>> GooHash by std::unordered_map found in the C++ standard library since
>>>>>> C++11. This continues Poppler's slow drift towards standard library
>>>>>> containers and removes one of the home-grown data structures with the
>>>>>> main goals of reducing code size and improving the long term
>>>>>> maintainability of the code base.
>>>>>
>>>>> Do you have any benchmarks on "rendering" speed and code size?
>>>>
>>>> Sorry, not at hand. I will try to prepare them during the week.
>>>
>>> I did run Splash rendering benchmarks of this branch against master with
>>> the result of rendering the circa 2400 documents of the TeXLive
>>> documentation present on my machine being:
>>
>> I'm wondering if those 2400 documents are diverse enough, which they may not
>> be given they are all coming from "the same place".
>
> They seem pretty diverse w.r.t. content, some being text heavy and some
> graphics rich. But I guess they are definitely not diverse technically
> as all are prepared using TeX itself.
>
> The main problem on my side is that I have failed to find my DVD copy of
> the Poppler regtest document collection until now. :-\ In any case, I am
> reasonably confident on the zero sum result since GooHash does not seem
> to live in any performance critical code path.
>
>>>
>>> Cumulative run time:
>>> Result: 90.95 min ∓ 1.1 %
>>> Reference: 91.57 min ∓ 1.2 %
>>> Deviation: -0.0 %
>>> Cumulative memory usage:
>>> Result: 37.2 MB ∓ 0.7 %
>>> Reference: 37.0 MB ∓ 0.7 %
>>> Deviation: +0.0 %
>>>
>>> (Where result is this patch and the reference is master.) (The
>>> measurement was taken using the perftest script which I proposed here
>>> some time ago for which I'll attach the patch again for reproduceability.)
>>
>> Did you really attach this before? i really don't remember it :D
>
> This was a very long-winded thread ending on 2016-01-01 centered around
> the regtest framework. It went from custom driver using QTest's
> benchmark functionality to custom backend in the regtest framework to
> separate Python script. The script still has problems to reliably
> measure really short things like running "pdftotext" for which a custom
> C++ driver might be needed, but for long-running stuff like "pdftoppm",
> the results seem reasonable.
>
>> Anyhow it seems the change is mostly a zero-sum runtime wise.
>
> Indeed. (Although thinking really really long term, I think a Poppler
> that is using std::vector, std::string and friends everywhere, could
> loose a lot of distributed fat in the form of a lot of memory
> indirections and benefit from the highly optimized standard library. But
> it just is not a single patch thing to reap any of these benefits.)
>
>> Which bring us to the code side. First i know it sucks but your spacing is
>> broken, please check the whole patch
>>
>> - nameToGID->removeInt(macGlyphNames[j]);
>> - nameToGID->add(new GooString(macGlyphNames[j]), i);
>> + nameToGID[macGlyphNames[j]] = i;
>>
>> i could fix it, but it's better (for me) if you do :D
>
> Definitely for me to fix. The main problem is that the spacing in those
> files was already broken and I am unsure whether I should fix the
> surrounding spacing even if I am not touching it otherwise. Due to that,
> there sometimes is no correct way in the current patch. If you do not
> say otherwise, I will try to make at least the touched blocks of code
> consistent.
>
>> Now onto the code,
>>
>> const auto emplaceRangeMap = [&](const char* encodingName, GBool
>> unicodeOut,
>> UnicodeMapRange* ranges, int len) {
>> residentUnicodeMaps.emplace(
>> std::piecewise_construct,
>> std::forward_as_tuple(encodingName),
>> std::forward_as_tuple(encodingName, unicodeOut, ranges, len)
>> );
>> };
>>
>> It's the first time in my life i see std::piecewise_construct and
>> std::forward_as_tuple, yes that probably makes me a bad C++ developer, but
>> given there's lots of us around, it doesn't make me happy now i don't
>> understand what the code does.
>
> The problem is that most internal Poppler types lack proper construction
> and assignment operators, hence I need to work harder to construct those
> UnicodeMap instances in-place inside the map (GooHash just stored a
> pointer to it, so there was no problem.)
>
> The whole piecewise_construct and forward_as_tuple dance just ensures,
> that those parameters to emplace are properly grouped before being
> unpacked to become the parameters of std::string and UnicodeMap
> construction again. If UnicodeMap was movable, this would probably look like
>
> residentUnicodeMaps.emplace(
> encodingName,
> UnicodeMap{encodingName, unicodeOut, ranges, len}
> );
>
> If you like, I can try to make Unicode a move-only type and simplify the
> mentioned helper functions?
>
>> Then there's the benefit/risk ratio. The code using GooHash is mostly
>> rocksolid and we haven't probably touched any line in it for a long time and
>> we have probably neither written new code that uses GooHash.
>>
>> In that regard we risk breaking working code.
>>
>> The benefit is not more speed nor less memory usage as your measurements
>> show.
>>
>> Mostly the benefit is "removing code from maintainership", which i agree is
>> a
>> good thing, but as mentioned before it's some code "we mostly ignore", so
>> it's
>> not that much of a good thing.
>
> I very much agree with the risk assessment.
>
> But I also think the code will ossify (or maybe already is?) due to
> those custom data structures and the less than idiomatic C++ usage.
> Hence I think, Poppler would not just loose code, but the remaining code
> should become easier to maintain. (Of course, the piecewise_construct
> fiasco shows that this has intermediate costs. But again, I think this
> is just an incentive to provide types with the usual C++ semantics which
> should make all code using those types better.)
>
> Best regards, Adam.
>
>> So i'm hesitant of what to do. It really sounds like a nice thing to not
>> have
>> custom structures, but on the other hand it's not like they get much in the
>> way of coding.
>>
>> I'd really appreciate other people's comments on this.
>>
>> Cheers,
>> Albert
>>
>>>
>>> I'll also attach the detailed comparison, but the gist seems to be that
>>> if there are significant changes, the run time is reduced but the memory
>>> usage is increased in the majority of cases. But this does not seem to
>>> show up in the cumulative results.
>>>
>>> Best regards, Adam.
>>>
>>> P.S.: One could try to improve the memory usage by tuning the load
>>> factor or calling shrink_to_fit where appropriate. Would you like me to
>>> try to do this?
>>>
>>> P.P.S.: One obvious area for improvement would be better
>>> interoperability between GooString and std::string, i.e. not converting
>>> them as C strings so that the length information does not need to be
>>> recomputed. I will try to prepare this as a separate patch on top of
>>> this one or should I include this here?
>>>
>>> Best regards, Adam.
>>>
>>>> Concerning code size, a release build of libpoppler.so goes from
>>>>
>>>> text data bss dec hex filename
>>>>
>>>> 2464034 288852 360 2753246 2a02de libpoppler.so.73.0.0
>>>>
>>>> for the current master to
>>>>
>>>> text data bss dec hex filename
>>>>
>>>> 2482129 288756 360 2771245 2a492d libpoppler.so.73.0.0
>>>>
>>>> with the patch applied, i.e. a 0.65% increase in binary size.
>>>>
>>>>
>>>> Please note that in my original message, I was referring only to source
>>>> code size, i.e.
>>>>
>>>> git diff --stat master...remove-goo-hash
>>>>
>>>> 18 files changed, 168 insertions(+), 803 deletions(-)
>>>>
>>>>> Cheers,
>>>>>
>>>>> Albert
>>>>
>>>> Best regards, Adam.
>>>>
>>>>>> Best regards, Adam.
>>>>>
>>>>> _______________________________________________
>>>>> poppler mailing list
>>>>> [email protected]
>>>>> https://lists.freedesktop.org/mailman/listinfo/poppler
>>>>
>>>> _______________________________________________
>>>> poppler mailing list
>>>> [email protected]
>>>> https://lists.freedesktop.org/mailman/listinfo/poppler
>>
>>
>>
>>
>> _______________________________________________
>> poppler mailing list
>> [email protected]
>> https://lists.freedesktop.org/mailman/listinfo/poppler
>>
>
>
>
> _______________________________________________
> poppler mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/poppler
>
From 6760e38b10f24708be40647622774033b543585a Mon Sep 17 00:00:00 2001 From: Adam Reichold <[email protected]> Date: Tue, 20 Feb 2018 09:07:17 +0100 Subject: [PATCH 1/8] Add conversion methods between GooString and std::string. --- goo/GooString.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/goo/GooString.h b/goo/GooString.h index 49f2888e..c694de10 100644 --- a/goo/GooString.h +++ b/goo/GooString.h @@ -38,6 +38,7 @@ #include <stdarg.h> #include <stdlib.h> // for NULL +#include <string> #include "gtypes.h" #ifdef __clang__ @@ -170,6 +171,10 @@ public: // The caller owns the return value GooString *sanitizedName(GBool psmode) const; + // Conversion from and to std::string + explicit GooString(const std::string& str) : GooString(str.data(), str.size()) {} + std::string toStr() const { return std::string(getCString(), getLength()); } + private: GooString(const GooString &other); GooString& operator=(const GooString &other); -- 2.16.1 From 8d583503997f31ee5d73fe06945540f8676bb529 Mon Sep 17 00:00:00 2001 From: Adam Reichold <[email protected]> Date: Sun, 18 Feb 2018 16:10:16 +0100 Subject: [PATCH 2/8] Replace GooHash by std::unordered_map in FoFiTrueType. --- fofi/FoFiTrueType.cc | 38 ++++++++++++++------------------------ fofi/FoFiTrueType.h | 7 ++++--- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/fofi/FoFiTrueType.cc b/fofi/FoFiTrueType.cc index 76299acc..807f7c7a 100644 --- a/fofi/FoFiTrueType.cc +++ b/fofi/FoFiTrueType.cc @@ -43,7 +43,6 @@ #include "goo/gmem.h" #include "goo/GooLikely.h" #include "goo/GooString.h" -#include "goo/GooHash.h" #include "FoFiType1C.h" #include "FoFiTrueType.h" #include "poppler/Error.h" @@ -305,7 +304,6 @@ FoFiTrueType::FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA, int faceI nTables = 0; cmaps = nullptr; nCmaps = 0; - nameToGID = nullptr; parsedOk = gFalse; faceIndex = faceIndexA; gsubFeatureTable = 0; @@ -317,9 +315,6 @@ FoFiTrueType::FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA, int faceI FoFiTrueType::~FoFiTrueType() { gfree(tables); gfree(cmaps); - if (nameToGID) { - delete nameToGID; - } } int FoFiTrueType::getNumCmaps() { @@ -442,11 +437,12 @@ int FoFiTrueType::mapCodeToGID(int i, Guint c) { return gid; } -int FoFiTrueType::mapNameToGID(char *name) { - if (!nameToGID) { +int FoFiTrueType::mapNameToGID(char *name) const { + const auto gid = nameToGID.find(name); + if (gid == nameToGID.end()) { return 0; } - return nameToGID->lookupInt(name); + return gid->second; } GBool FoFiTrueType::getCFFBlock(char **start, int *length) { @@ -1450,7 +1446,7 @@ void FoFiTrueType::parse() { } void FoFiTrueType::readPostTable() { - GooString *name; + std::string name; int tablePos, postFmt, stringIdx, stringPos; GBool ok; int i, j, n, m; @@ -1465,12 +1461,12 @@ void FoFiTrueType::readPostTable() { goto err; } if (postFmt == 0x00010000) { - nameToGID = new GooHash(gTrue); + nameToGID.reserve(258); for (i = 0; i < 258; ++i) { - nameToGID->add(new GooString(macGlyphNames[i]), i); + nameToGID.emplace(macGlyphNames[i], i); } } else if (postFmt == 0x00020000) { - nameToGID = new GooHash(gTrue); + nameToGID.reserve(258); n = getU16BE(tablePos + 32, &ok); if (!ok) { goto err; @@ -1484,8 +1480,7 @@ void FoFiTrueType::readPostTable() { ok = gTrue; j = getU16BE(tablePos + 34 + 2*i, &ok); if (j < 258) { - nameToGID->removeInt(macGlyphNames[j]); - nameToGID->add(new GooString(macGlyphNames[j]), i); + nameToGID[macGlyphNames[j]] = i; } else { j -= 258; if (j != stringIdx) { @@ -1500,23 +1495,21 @@ void FoFiTrueType::readPostTable() { if (!ok || !checkRegion(stringPos + 1, m)) { continue; } - name = new GooString((char *)&file[stringPos + 1], m); - nameToGID->removeInt(name); - nameToGID->add(name, i); + name.assign((char *)&file[stringPos + 1], m); + nameToGID[name] = i; ++stringIdx; stringPos += 1 + m; } } } else if (postFmt == 0x00028000) { - nameToGID = new GooHash(gTrue); + nameToGID.reserve(258); for (i = 0; i < nGlyphs; ++i) { j = getU8(tablePos + 32 + i, &ok); if (!ok) { continue; } if (j < 258) { - nameToGID->removeInt(macGlyphNames[j]); - nameToGID->add(new GooString(macGlyphNames[j]), i); + nameToGID[macGlyphNames[j]] = i; } } } @@ -1524,10 +1517,7 @@ void FoFiTrueType::readPostTable() { return; err: - if (nameToGID) { - delete nameToGID; - nameToGID = nullptr; - } + nameToGID.clear(); } int FoFiTrueType::seekTable(const char *tag) { diff --git a/fofi/FoFiTrueType.h b/fofi/FoFiTrueType.h index 0c42c837..432fe4bb 100644 --- a/fofi/FoFiTrueType.h +++ b/fofi/FoFiTrueType.h @@ -32,11 +32,12 @@ #endif #include "stddef.h" +#include <unordered_map> +#include <string> #include "goo/gtypes.h" #include "FoFiBase.h" class GooString; -class GooHash; struct TrueTypeTable; struct TrueTypeCmap; @@ -82,7 +83,7 @@ public: // Returns the GID corresponding to <name> according to the post // table. Returns 0 if there is no mapping for <name> or if the // font does not have a post table. - int mapNameToGID(char *name); + int mapNameToGID(char *name) const; // Return the mapping from CIDs to GIDs, and return the number of // CIDs in *<nCIDs>. This is only useful for CID fonts. (Only @@ -199,7 +200,7 @@ private: int nGlyphs; int locaFmt; int bbox[4]; - GooHash *nameToGID; + std::unordered_map<std::string,int> nameToGID; GBool openTypeCFF; GBool parsedOk; -- 2.16.1 From 83a004b3a44d1618191a765ca49eacce6667b37b Mon Sep 17 00:00:00 2001 From: Adam Reichold <[email protected]> Date: Sun, 18 Feb 2018 16:10:59 +0100 Subject: [PATCH 3/8] Replace GooHash by std::unordered_map in GlobalParams. --- poppler/CharCodeToUnicode.cc | 8 +- poppler/CharCodeToUnicode.h | 2 +- poppler/GlobalParams.cc | 217 ++++++++++++++----------------------------- poppler/GlobalParams.h | 33 +++---- 4 files changed, 93 insertions(+), 167 deletions(-) diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc index 17df0292..a5fbe0c3 100644 --- a/poppler/CharCodeToUnicode.cc +++ b/poppler/CharCodeToUnicode.cc @@ -125,7 +125,7 @@ CharCodeToUnicode *CharCodeToUnicode::makeIdentityMapping() { return ctu; } -CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GooString *fileName, +CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(const char *fileName, GooString *collection) { FILE *f; Unicode *mapA; @@ -134,8 +134,8 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GooString *fileName, Unicode u; CharCodeToUnicode *ctu; - if (!(f = openFile(fileName->getCString(), "r"))) { - error(errIO, -1, "Couldn't open cidToUnicode file '{0:t}'", + if (!(f = openFile(fileName, "r"))) { + error(errIO, -1, "Couldn't open cidToUnicode file '{0:s}'", fileName); return nullptr; } @@ -152,7 +152,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GooString *fileName, if (sscanf(buf, "%x", &u) == 1) { mapA[mapLenA] = u; } else { - error(errSyntaxWarning, -1, "Bad line ({0:d}) in cidToUnicode file '{1:t}'", + error(errSyntaxWarning, -1, "Bad line ({0:d}) in cidToUnicode file '{1:s}'", (int)(mapLenA + 1), fileName); mapA[mapLenA] = 0; } diff --git a/poppler/CharCodeToUnicode.h b/poppler/CharCodeToUnicode.h index 13572217..54e9139f 100644 --- a/poppler/CharCodeToUnicode.h +++ b/poppler/CharCodeToUnicode.h @@ -55,7 +55,7 @@ public: // Read the CID-to-Unicode mapping for <collection> from the file // specified by <fileName>. Sets the initial reference count to 1. // Returns NULL on failure. - static CharCodeToUnicode *parseCIDToUnicode(GooString *fileName, + static CharCodeToUnicode *parseCIDToUnicode(const char *fileName, GooString *collection); // Create a Unicode-to-Unicode mapping from the file specified by diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc index 50b7eee2..8532285f 100644 --- a/poppler/GlobalParams.cc +++ b/poppler/GlobalParams.cc @@ -65,7 +65,6 @@ #include "goo/gmem.h" #include "goo/GooString.h" #include "goo/GooList.h" -#include "goo/GooHash.h" #include "goo/gfile.h" #include "Error.h" #include "NameToCharCode.h" @@ -548,9 +547,6 @@ Plugin::~Plugin() { GlobalParams::GlobalParams(const char *customPopplerDataDir) : popplerDataDir(customPopplerDataDir) { - UnicodeMap *map; - int i; - #ifdef MULTITHREADED gInitMutex(&mutex); gInitMutex(&unicodeMapCacheMutex); @@ -562,7 +558,7 @@ GlobalParams::GlobalParams(const char *customPopplerDataDir) // scan the encoding in reverse because we want the lowest-numbered // index for each char name ('space' is encoded twice) macRomanReverseMap = new NameToCharCode(); - for (i = 255; i >= 0; --i) { + for (int i = 255; i >= 0; --i) { if (macRomanEncoding[i]) { macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i); } @@ -573,13 +569,7 @@ GlobalParams::GlobalParams(const char *customPopplerDataDir) #endif nameToUnicodeZapfDingbats = new NameToCharCode(); nameToUnicodeText = new NameToCharCode(); - cidToUnicodes = new GooHash(gTrue); - unicodeToUnicodes = new GooHash(gTrue); - residentUnicodeMaps = new GooHash(); - unicodeMaps = new GooHash(gTrue); - cMapDirs = new GooHash(gTrue); toUnicodeDirs = new GooList(); - fontFiles = new GooHash(gTrue); sysFonts = new SysFontList(); psExpandSmaller = gFalse; psShrinkLarger = gTrue; @@ -612,31 +602,39 @@ GlobalParams::GlobalParams(const char *customPopplerDataDir) #endif // set up the initial nameToUnicode tables - for (i = 0; nameToUnicodeZapfDingbatsTab[i].name; ++i) { + for (int i = 0; nameToUnicodeZapfDingbatsTab[i].name; ++i) { nameToUnicodeZapfDingbats->add(nameToUnicodeZapfDingbatsTab[i].name, nameToUnicodeZapfDingbatsTab[i].u); } - for (i = 0; nameToUnicodeTextTab[i].name; ++i) { + for (int i = 0; nameToUnicodeTextTab[i].name; ++i) { nameToUnicodeText->add(nameToUnicodeTextTab[i].name, nameToUnicodeTextTab[i].u); } // set up the residentUnicodeMaps table - map = new UnicodeMap("Latin1", gFalse, - latin1UnicodeMapRanges, latin1UnicodeMapLen); - residentUnicodeMaps->add(map->getEncodingName(), map); - map = new UnicodeMap("ASCII7", gFalse, - ascii7UnicodeMapRanges, ascii7UnicodeMapLen); - residentUnicodeMaps->add(map->getEncodingName(), map); - map = new UnicodeMap("Symbol", gFalse, - symbolUnicodeMapRanges, symbolUnicodeMapLen); - residentUnicodeMaps->add(map->getEncodingName(), map); - map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges, - zapfDingbatsUnicodeMapLen); - residentUnicodeMaps->add(map->getEncodingName(), map); - map = new UnicodeMap("UTF-8", gTrue, &mapUTF8); - residentUnicodeMaps->add(map->getEncodingName(), map); - map = new UnicodeMap("UTF-16", gTrue, &mapUTF16); - residentUnicodeMaps->add(map->getEncodingName(), map); + + const auto emplaceRangeMap = [&](const char* encodingName, GBool unicodeOut, UnicodeMapRange* ranges, int len) { + residentUnicodeMaps.emplace( + std::piecewise_construct, + std::forward_as_tuple(encodingName), + std::forward_as_tuple(encodingName, unicodeOut, ranges, len) + ); + }; + + const auto emplaceFuncMap = [&](const char* encodingName, GBool unicodeOut, UnicodeMapFunc func) { + residentUnicodeMaps.emplace( + std::piecewise_construct, + std::forward_as_tuple(encodingName), + std::forward_as_tuple(encodingName, unicodeOut, func) + ); + }; + + residentUnicodeMaps.reserve(6); + emplaceRangeMap("Latin1", gFalse, latin1UnicodeMapRanges, latin1UnicodeMapLen); + emplaceRangeMap("ASCII7", gFalse, ascii7UnicodeMapRanges, ascii7UnicodeMapLen); + emplaceRangeMap("Symbol", gFalse, symbolUnicodeMapRanges, symbolUnicodeMapLen); + emplaceRangeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges, zapfDingbatsUnicodeMapLen); + emplaceFuncMap("UTF-8", gTrue, &mapUTF8); + emplaceFuncMap("UTF-16", gTrue, &mapUTF16); scanEncodingDirs(); } @@ -717,34 +715,16 @@ void GlobalParams::parseNameToUnicode(GooString *name) { fclose(f); } -void GlobalParams::addCIDToUnicode(GooString *collection, - GooString *fileName) { - GooString *old; - - if ((old = (GooString *)cidToUnicodes->remove(collection))) { - delete old; - } - cidToUnicodes->add(collection->copy(), fileName->copy()); +void GlobalParams::addCIDToUnicode(GooString *collection, GooString *fileName) { + cidToUnicodes[collection->toStr()] = fileName->toStr(); } -void GlobalParams::addUnicodeMap(GooString *encodingName, GooString *fileName) -{ - GooString *old; - - if ((old = (GooString *)unicodeMaps->remove(encodingName))) { - delete old; - } - unicodeMaps->add(encodingName->copy(), fileName->copy()); +void GlobalParams::addUnicodeMap(GooString *encodingName, GooString *fileName) { + unicodeMaps[encodingName->toStr()] = fileName->toStr(); } void GlobalParams::addCMapDir(GooString *collection, GooString *dir) { - GooList *list; - - if (!(list = (GooList *)cMapDirs->lookup(collection))) { - list = new GooList(); - cMapDirs->add(collection->copy(), list); - } - list->append(dir->copy()); + cMapDirs.emplace(collection->toStr(), dir->toStr()); } GBool GlobalParams::parseYesNo2(const char *token, GBool *flag) { @@ -765,28 +745,13 @@ GlobalParams::~GlobalParams() { delete nameToUnicodeZapfDingbats; delete nameToUnicodeText; - deleteGooHash(cidToUnicodes, GooString); - deleteGooHash(unicodeToUnicodes, GooString); - deleteGooHash(residentUnicodeMaps, UnicodeMap); - deleteGooHash(unicodeMaps, GooString); deleteGooList(toUnicodeDirs, GooString); - deleteGooHash(fontFiles, GooString); #ifdef _WIN32 deleteGooHash(substFiles, GooString); #endif delete sysFonts; delete textEncoding; - GooHashIter *iter; - GooString *key; - cMapDirs->startIter(&iter); - void *val; - while (cMapDirs->getNext(&iter, &key, &val)) { - GooList* list = (GooList*)val; - deleteGooList(list, GooString); - } - delete cMapDirs; - delete cidToUnicodeCache; delete unicodeToUnicodeCache; delete unicodeMapCache; @@ -827,55 +792,48 @@ Unicode GlobalParams::mapNameToUnicodeText(const char *charName) { } UnicodeMap *GlobalParams::getResidentUnicodeMap(GooString *encodingName) { - UnicodeMap *map; + UnicodeMap *map = nullptr; lockGlobalParams; - map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName); - unlockGlobalParams; - if (map) { + const auto unicodeMap = residentUnicodeMaps.find(encodingName->toStr()); + if (unicodeMap != residentUnicodeMaps.end()) { + map = &unicodeMap->second; map->incRefCnt(); } + unlockGlobalParams; + return map; } FILE *GlobalParams::getUnicodeMapFile(GooString *encodingName) { - GooString *fileName; - FILE *f; + FILE *file = nullptr; lockGlobalParams; - if ((fileName = (GooString *)unicodeMaps->lookup(encodingName))) { - f = openFile(fileName->getCString(), "r"); - } else { - f = nullptr; + const auto unicodeMap = unicodeMaps.find(encodingName->toStr()); + if (unicodeMap != unicodeMaps.end()) { + file = openFile(unicodeMap->second.c_str(), "r"); } unlockGlobalParams; - return f; + + return file; } FILE *GlobalParams::findCMapFile(GooString *collection, GooString *cMapName) { - GooList *list; - GooString *dir; - GooString *fileName; - FILE *f; - int i; + FILE *file = nullptr; lockGlobalParams; - if (!(list = (GooList *)cMapDirs->lookup(collection))) { - unlockGlobalParams; - return nullptr; - } - for (i = 0; i < list->getLength(); ++i) { - dir = (GooString *)list->get(i); - fileName = appendToPath(dir->copy(), cMapName->getCString()); - f = openFile(fileName->getCString(), "r"); - delete fileName; - if (f) { - unlockGlobalParams; - return f; + const auto cMapDirs = this->cMapDirs.equal_range(collection->toStr()); + for (auto cMapDir = cMapDirs.first; cMapDir != cMapDirs.second; ++cMapDir) { + auto* const path = new GooString(cMapDir->second); + appendToPath(path, cMapName->getCString()); + file = openFile(path->getCString(), "r"); + delete path; + if (file) { + break; } } unlockGlobalParams; - return nullptr; + return file; } FILE *GlobalParams::findToUnicodeFile(GooString *name) { @@ -1072,17 +1030,16 @@ static FcPattern *buildFcPattern(GfxFont *font, GooString *base14Name) #endif GooString *GlobalParams::findFontFile(GooString *fontName) { - GooString *path; + GooString *path = nullptr; setupBaseFonts(nullptr); lockGlobalParams; - if ((path = (GooString *)fontFiles->lookup(fontName))) { - path = path->copy(); - unlockGlobalParams; - return path; + const auto fontFile = fontFiles.find(fontName->toStr()); + if (fontFile != fontFiles.end()) { + path = new GooString(fontFile->second); } unlockGlobalParams; - return nullptr; + return path; } /* if you can't or don't want to use Fontconfig, you need to implement @@ -1090,7 +1047,7 @@ GooString *GlobalParams::findFontFile(GooString *fontName) { */ #ifdef WITH_FONTCONFIGURATION_FONTCONFIG // not needed for fontconfig -void GlobalParams::setupBaseFonts(char *dir) { +void GlobalParams::setupBaseFonts(char *) { } GooString *GlobalParams::findBase14FontFile(GooString *base14Name, GfxFont *font) { @@ -1453,40 +1410,15 @@ GBool GlobalParams::getErrQuiet() { } CharCodeToUnicode *GlobalParams::getCIDToUnicode(GooString *collection) { - GooString *fileName; CharCodeToUnicode *ctu; lockGlobalParams; if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) { - if ((fileName = (GooString *)cidToUnicodes->lookup(collection)) && - (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) { - cidToUnicodeCache->add(ctu); - } - } - unlockGlobalParams; - return ctu; -} - -CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GooString *fontName) { - lockGlobalParams; - GooHashIter *iter; - unicodeToUnicodes->startIter(&iter); - GooString *fileName = nullptr; - GooString *fontPattern; - void *val; - while (!fileName && unicodeToUnicodes->getNext(&iter, &fontPattern, &val)) { - if (strstr(fontName->getCString(), fontPattern->getCString())) { - unicodeToUnicodes->killIter(&iter); - fileName = (GooString*)val; - } - } - CharCodeToUnicode *ctu = nullptr; - if (fileName) { - ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName); - if (!ctu) { - ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName); - if (ctu) - unicodeToUnicodeCache->add(ctu); + const auto cidToUnicode = cidToUnicodes.find(collection->toStr()); + if (cidToUnicode != cidToUnicodes.end()) { + if((ctu = CharCodeToUnicode::parseCIDToUnicode(cidToUnicode->second.c_str(), collection))) { + cidToUnicodeCache->add(ctu); + } } } unlockGlobalParams; @@ -1523,20 +1455,13 @@ UnicodeMap *GlobalParams::getTextEncoding() { GooList *GlobalParams::getEncodingNames() { - GooList *result = new GooList; - GooHashIter *iter; - GooString *key; - void *val; - residentUnicodeMaps->startIter(&iter); - while (residentUnicodeMaps->getNext(&iter, &key, &val)) { - result->append(key); + auto* const result = new GooList; + for (const auto& unicodeMap : residentUnicodeMaps) { + result->append(new GooString(unicodeMap.first)); } - residentUnicodeMaps->killIter(&iter); - unicodeMaps->startIter(&iter); - while (unicodeMaps->getNext(&iter, &key, &val)) { - result->append(key); + for (const auto& unicodeMap : unicodeMaps) { + result->append(new GooString(unicodeMap.first)); } - unicodeMaps->killIter(&iter); return result; } @@ -1546,7 +1471,7 @@ GooList *GlobalParams::getEncodingNames() void GlobalParams::addFontFile(GooString *fontName, GooString *path) { lockGlobalParams; - fontFiles->add(fontName, path); + fontFiles[fontName->toStr()] = path->toStr(); unlockGlobalParams; } diff --git a/poppler/GlobalParams.h b/poppler/GlobalParams.h index e3d660cf..09a39814 100644 --- a/poppler/GlobalParams.h +++ b/poppler/GlobalParams.h @@ -44,6 +44,9 @@ #include <stdio.h> #include "goo/gtypes.h" #include "CharTypes.h" +#include "UnicodeMap.h" +#include <unordered_map> +#include <string> #ifdef MULTITHREADED #include "goo/GooMutex.h" @@ -51,11 +54,9 @@ class GooString; class GooList; -class GooHash; class NameToCharCode; class CharCodeToUnicode; class CharCodeToUnicodeCache; -class UnicodeMap; class UnicodeMapCache; class CMap; class CMapCache; @@ -147,7 +148,7 @@ public: GBool getErrQuiet(); CharCodeToUnicode *getCIDToUnicode(GooString *collection); - CharCodeToUnicode *getUnicodeToUnicode(GooString *fontName); + CharCodeToUnicode *getUnicodeToUnicode(GooString *) { return nullptr; } UnicodeMap *getUnicodeMap(GooString *encodingName); CMap *getCMap(GooString *collection, GooString *cMapName, Stream *stream = NULL); UnicodeMap *getTextEncoding(); @@ -199,24 +200,24 @@ private: nameToUnicodeZapfDingbats; NameToCharCode * // mapping from char name to Unicode for text nameToUnicodeText; // extraction - GooHash *cidToUnicodes; // files for mappings from char collections - // to Unicode, indexed by collection name - // [GooString] - GooHash *unicodeToUnicodes; // files for Unicode-to-Unicode mappings, - // indexed by font name pattern [GooString] - GooHash *residentUnicodeMaps; // mappings from Unicode to char codes, - // indexed by encoding name [UnicodeMap] - GooHash *unicodeMaps; // files for mappings from Unicode to char - // codes, indexed by encoding name [GooString] - GooHash *cMapDirs; // list of CMap dirs, indexed by collection - // name [GooList[GooString]] + // files for mappings from char collections + // to Unicode, indexed by collection name + std::unordered_map<std::string, std::string> cidToUnicodes; + // mappings from Unicode to char codes, + // indexed by encoding name + std::unordered_map<std::string, UnicodeMap> residentUnicodeMaps; + // files for mappings from Unicode to char + // codes, indexed by encoding name + std::unordered_map<std::string, std::string> unicodeMaps; + // list of CMap dirs, indexed by collection + std::unordered_multimap<std::string, std::string> cMapDirs; GooList *toUnicodeDirs; // list of ToUnicode CMap dirs [GooString] GBool baseFontsInitialized; #ifdef _WIN32 GooHash *substFiles; // windows font substitutes (for CID fonts) #endif - GooHash *fontFiles; // font files: font name mapped to path - // [GString] + // font files: font name mapped to path + std::unordered_map<std::string, std::string> fontFiles; SysFontList *sysFonts; // system fonts GBool psExpandSmaller; // expand smaller pages to fill paper GBool psShrinkLarger; // shrink larger pages to fit paper -- 2.16.1 From b1ab993bb5fb424f115121daf5228d23cc277107 Mon Sep 17 00:00:00 2001 From: Adam Reichold <[email protected]> Date: Sun, 18 Feb 2018 16:11:29 +0100 Subject: [PATCH 4/8] Replace GooHash by std::unordered_map in OutputDev. --- poppler/Gfx.cc | 19 +++---------------- poppler/OutputDev.cc | 14 +++----------- poppler/OutputDev.h | 14 ++++++++------ poppler/PSOutputDev.h | 2 +- poppler/ProfileData.cc | 9 --------- poppler/ProfileData.h | 24 +++++++++--------------- test/pdf-inspector.cc | 16 ++++------------ 7 files changed, 28 insertions(+), 70 deletions(-) diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index 4f6c33f8..0d7b072e 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -59,7 +59,6 @@ #include <memory> #include "goo/gmem.h" #include "goo/GooTimer.h" -#include "goo/GooHash.h" #include "GlobalParams.h" #include "CharTypes.h" #include "Object.h" @@ -739,21 +738,9 @@ void Gfx::go(GBool topLevel) { // Update the profile information if (unlikely(profileCommands)) { - GooHash *hash; - - hash = out->getProfileHash (); - if (hash) { - GooString *cmd_g; - ProfileData *data_p; - - cmd_g = new GooString (obj.getCmd()); - data_p = (ProfileData *)hash->lookup (cmd_g); - if (data_p == nullptr) { - data_p = new ProfileData(); - hash->add (cmd_g, data_p); - } - - data_p->addElement(timer->getElapsed ()); + if (auto* const hash = out->getProfileHash()) { + auto& data = (*hash)[obj.getCmd()]; + data.addElement(timer->getElapsed()); } delete timer; } diff --git a/poppler/OutputDev.cc b/poppler/OutputDev.cc index 8afa7052..fe09bd3d 100644 --- a/poppler/OutputDev.cc +++ b/poppler/OutputDev.cc @@ -36,7 +36,6 @@ #include "Stream.h" #include "GfxState.h" #include "OutputDev.h" -#include "goo/GooHash.h" //------------------------------------------------------------------------ // OutputDev @@ -179,18 +178,11 @@ void OutputDev::opiEnd(GfxState *state, Dict *opiDict) { #endif void OutputDev::startProfile() { - if (profileHash) - delete profileHash; - - profileHash = new GooHash (true); + profileHash.reset(new std::unordered_map<std::string, ProfileData>); } -GooHash *OutputDev::endProfile() { - GooHash *profile = profileHash; - - profileHash = nullptr; - - return profile; +std::unique_ptr<std::unordered_map<std::string, ProfileData>> OutputDev::endProfile() { + return std::move(profileHash); } #ifdef USE_CMS diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h index aca84cda..7e29b0f9 100644 --- a/poppler/OutputDev.h +++ b/poppler/OutputDev.h @@ -42,10 +42,13 @@ #include "CharTypes.h" #include "Object.h" #include "PopplerCache.h" +#include "ProfileData.h" +#include <memory> +#include <unordered_map> +#include <string> class Annot; class Dict; -class GooHash; class GooString; class GfxState; class Gfx; @@ -79,7 +82,6 @@ public: : iccColorSpaceCache(5) #endif { - profileHash = nullptr; } // Destructor. @@ -327,9 +329,9 @@ public: virtual void psXObject(Stream * /*psStream*/, Stream * /*level1Stream*/) {} //----- Profiling - virtual void startProfile(); - virtual GooHash *getProfileHash() {return profileHash; } - virtual GooHash *endProfile(); + void startProfile(); + std::unordered_map<std::string, ProfileData>* getProfileHash() const { return profileHash.get(); } + std::unique_ptr<std::unordered_map<std::string, ProfileData>> endProfile(); //----- transparency groups and soft masks virtual GBool checkTransparencyGroup(GfxState * /*state*/, GBool /*knockout*/) { return gTrue; } @@ -359,7 +361,7 @@ private: double defCTM[6]; // default coordinate transform matrix double defICTM[6]; // inverse of default CTM - GooHash *profileHash; + std::unique_ptr<std::unordered_map<std::string, ProfileData>> profileHash; #ifdef USE_CMS PopplerCache iccColorSpaceCache; diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h index 330b81b3..4ec2cdd7 100644 --- a/poppler/PSOutputDev.h +++ b/poppler/PSOutputDev.h @@ -47,7 +47,7 @@ #include <map> #include <vector> -class GHooash; +class GooHash; class PDFDoc; class XRef; class Function; diff --git a/poppler/ProfileData.cc b/poppler/ProfileData.cc index a0c44747..1044913c 100644 --- a/poppler/ProfileData.cc +++ b/poppler/ProfileData.cc @@ -12,21 +12,12 @@ #pragma implementation #endif -#include <stdlib.h> -#include <stddef.h> #include "ProfileData.h" //------------------------------------------------------------------------ // ProfileData //------------------------------------------------------------------------ -ProfileData::ProfileData() { - count = 0; - total = 0.0; - min = 0.0; - max = 0.0; -} - void ProfileData::addElement (double elapsed) { if (count == 0) { diff --git a/poppler/ProfileData.h b/poppler/ProfileData.h index 418ee010..30b9a484 100644 --- a/poppler/ProfileData.h +++ b/poppler/ProfileData.h @@ -19,23 +19,17 @@ class ProfileData { public: - - // Constructor. - ProfileData (); - - // Destructor. - ~ProfileData() {} - void addElement (double elapsed); - int getCount () { return count; } - double getTotal () { return total; } - double getMin () { return max; } - double getMax () { return max; } + + int getCount () const { return count; } + double getTotal () const { return total; } + double getMin () const { return max; } + double getMax () const { return max; } private: - int count; // size of <elems> array - double total; // number of elements in array - double min; // reference count - double max; // reference count + int count = 0; // size of <elems> array + double total = 0.0; // number of elements in array + double min = 0.0; // reference count + double max = 0.0; // reference count }; #endif diff --git a/test/pdf-inspector.cc b/test/pdf-inspector.cc index d672add1..a1015aaf 100644 --- a/test/pdf-inspector.cc +++ b/test/pdf-inspector.cc @@ -13,7 +13,6 @@ #endif #include <goo/gmem.h> -#include <goo/GooHash.h> #include <goo/GooTimer.h> #include <splash/SplashTypes.h> #include <splash/SplashBitmap.h> @@ -214,10 +213,6 @@ PdfInspector::on_analyze_clicked (GtkWidget *widget, PdfInspector *inspector) void PdfInspector::analyze_page (int page) { - GooHashIter *iter; - GooHash *hash; - GooString *key; - void *p; GtkWidget *label; char *text; cairo_t *cr; @@ -245,24 +240,21 @@ PdfInspector::analyze_page (int page) g_free (text); // Individual times; - hash = output->endProfile (); - hash->startIter(&iter); - while (hash->getNext(&iter, &key, &p)) + auto hash = output->endProfile (); + for (const auto& kvp : *hash) { GtkTreeIter tree_iter; - ProfileData *data_p = (ProfileData *) p; + const auto* const data_p = &kvp.second; gtk_list_store_append (GTK_LIST_STORE (model), &tree_iter); gtk_list_store_set (GTK_LIST_STORE (model), &tree_iter, - OP_STRING, key->getCString(), + OP_STRING, kvp.first.c_str (), OP_COUNT, data_p->getCount (), OP_TOTAL, data_p->getTotal (), OP_MIN, data_p->getMin (), OP_MAX, data_p->getMax (), -1); } - hash->killIter(&iter); - deleteGooHash (hash, ProfileData); } void -- 2.16.1 From d3344acd72bd75fbdaefbae52de9116c6c241f9a Mon Sep 17 00:00:00 2001 From: Adam Reichold <[email protected]> Date: Sun, 18 Feb 2018 16:11:55 +0100 Subject: [PATCH 5/8] Replace GooHash by std::unordered_map in PSOutputDev. --- poppler/PSOutputDev.cc | 30 ++++++++++-------------------- poppler/PSOutputDev.h | 8 +++++--- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc index 2f55557c..ca3a55b5 100644 --- a/poppler/PSOutputDev.cc +++ b/poppler/PSOutputDev.cc @@ -52,7 +52,6 @@ #include <algorithm> #include "goo/GooString.h" #include "goo/GooList.h" -#include "goo/GooHash.h" #include "poppler-config.h" #include "GlobalParams.h" #include "Object.h" @@ -1107,8 +1106,6 @@ PSOutputDev::PSOutputDev(const char *fileName, PDFDoc *doc, customCodeCbkData = customCodeCbkDataA; fontIDs = nullptr; - fontNames = new GooHash(gTrue); - fontMaxValidGlyph = new GooHash(gTrue); t1FontNames = nullptr; font8Info = nullptr; font16Enc = nullptr; @@ -1176,8 +1173,6 @@ PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA, customCodeCbkData = customCodeCbkDataA; fontIDs = nullptr; - fontNames = new GooHash(gTrue); - fontMaxValidGlyph = new GooHash(gTrue); t1FontNames = nullptr; font8Info = nullptr; font16Enc = nullptr; @@ -1408,7 +1403,7 @@ void PSOutputDev::postInit() fontIDLen = 0; fontIDs = (Ref *)gmallocn(fontIDSize, sizeof(Ref)); for (i = 0; i < 14; ++i) { - fontNames->add(new GooString(psBase14SubstFonts[i].psName), 1); + fontNames.emplace(psBase14SubstFonts[i].psName); } t1FontNameSize = 64; t1FontNameLen = 0; @@ -1498,8 +1493,6 @@ PSOutputDev::~PSOutputDev() { if (fontIDs) { gfree(fontIDs); } - delete fontNames; - delete fontMaxValidGlyph; if (t1FontNames) { for (i = 0; i < t1FontNameLen; ++i) { delete t1FontNames[i].psName; @@ -2128,10 +2121,9 @@ void PSOutputDev::setupEmbeddedType1Font(Ref *id, GooString *psName) { GBool writePadding = gTrue; // check if font is already embedded - if (fontNames->lookupInt(psName)) { + if (!fontNames.emplace(psName->toStr()).second) { return; } - fontNames->add(psName->copy(), 1); // get the font stream and info Object obj1, obj2, obj3; @@ -2307,10 +2299,9 @@ void PSOutputDev::setupExternalType1Font(GooString *fileName, GooString *psName) FILE *fontFile; int c; - if (fontNames->lookupInt(psName)) { + if (!fontNames.emplace(psName->toStr()).second) { return; } - fontNames->add(psName->copy(), 1); // beginning comment writePSFmt("%%BeginResource: font {0:t}\n", psName); @@ -2546,8 +2537,9 @@ void PSOutputDev::setupExternalTrueTypeFont(GfxFont *font, GooString *fileName, void PSOutputDev::updateFontMaxValidGlyph(GfxFont *font, int maxValidGlyph) { if (maxValidGlyph >= 0 && font->getName()) { - if (maxValidGlyph > fontMaxValidGlyph->lookupInt(font->getName())) { - fontMaxValidGlyph->replace(font->getName()->copy(), maxValidGlyph); + auto& fontMaxValidGlyph = this->fontMaxValidGlyph[font->getName()->toStr()]; + if (fontMaxValidGlyph < maxValidGlyph) { + fontMaxValidGlyph = maxValidGlyph; } } } @@ -2871,16 +2863,14 @@ GooString *PSOutputDev::makePSFontName(GfxFont *font, Ref *id) { if ((s = font->getEmbeddedFontName())) { psName = filterPSName(s); - if (!fontNames->lookupInt(psName)) { - fontNames->add(psName->copy(), 1); + if (fontNames.emplace(psName->toStr()).second) { return psName; } delete psName; } if ((s = font->getName())) { psName = filterPSName(s); - if (!fontNames->lookupInt(psName)) { - fontNames->add(psName->copy(), 1); + if (fontNames.emplace(psName->toStr()).second) { return psName; } delete psName; @@ -2895,7 +2885,7 @@ GooString *PSOutputDev::makePSFontName(GfxFont *font, Ref *id) { psName->append('_')->append(s); delete s; } - fontNames->add(psName->copy(), 1); + fontNames.emplace(psName->toStr()); return psName; } @@ -5041,7 +5031,7 @@ void PSOutputDev::drawString(GfxState *state, GooString *s) { if (!(font = state->getFont())) { return; } - maxGlyphInt = (font->getName()? fontMaxValidGlyph->lookupInt(font->getName()): 0); + maxGlyphInt = (font->getName() ? fontMaxValidGlyph[font->getName()->toStr()] : 0); if (maxGlyphInt < 0) maxGlyphInt = 0; maxGlyph = (CharCode) maxGlyphInt; wMode = font->getWMode(); diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h index 4ec2cdd7..98ac9c98 100644 --- a/poppler/PSOutputDev.h +++ b/poppler/PSOutputDev.h @@ -46,8 +46,10 @@ #include <set> #include <map> #include <vector> +#include <unordered_set> +#include <unordered_map> +#include <string> -class GooHash; class PDFDoc; class XRef; class Function; @@ -474,8 +476,8 @@ private: int fontIDLen; // number of entries in fontIDs array int fontIDSize; // size of fontIDs array std::set<int> resourceIDs; // list of object IDs of objects containing Resources we've already set up - GooHash *fontNames; // all used font names - GooHash *fontMaxValidGlyph; // max valid glyph of each font + std::unordered_set<std::string> fontNames; // all used font names + std::unordered_map<std::string, int> fontMaxValidGlyph; // max valid glyph of each font PST1FontName *t1FontNames; // font names for Type 1/1C fonts int t1FontNameLen; // number of entries in t1FontNames array int t1FontNameSize; // size of t1FontNames array -- 2.16.1 From 850e3293bc7de7a08b1d308aec2307d80e31eaf1 Mon Sep 17 00:00:00 2001 From: Adam Reichold <[email protected]> Date: Sun, 18 Feb 2018 16:23:36 +0100 Subject: [PATCH 6/8] Also replace the Win32-specific usage of GooHash by std::unordered_map on a best-effort basis. --- poppler/GlobalParams.cc | 6 ------ poppler/GlobalParams.h | 3 ++- poppler/GlobalParamsWin.cc | 23 +++++++++++------------ 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc index 8532285f..c119f9df 100644 --- a/poppler/GlobalParams.cc +++ b/poppler/GlobalParams.cc @@ -564,9 +564,6 @@ GlobalParams::GlobalParams(const char *customPopplerDataDir) } } -#ifdef _WIN32 - substFiles = new GooHash(gTrue); -#endif nameToUnicodeZapfDingbats = new NameToCharCode(); nameToUnicodeText = new NameToCharCode(); toUnicodeDirs = new GooList(); @@ -746,9 +743,6 @@ GlobalParams::~GlobalParams() { delete nameToUnicodeZapfDingbats; delete nameToUnicodeText; deleteGooList(toUnicodeDirs, GooString); -#ifdef _WIN32 - deleteGooHash(substFiles, GooString); -#endif delete sysFonts; delete textEncoding; diff --git a/poppler/GlobalParams.h b/poppler/GlobalParams.h index 09a39814..69435bfc 100644 --- a/poppler/GlobalParams.h +++ b/poppler/GlobalParams.h @@ -214,7 +214,8 @@ private: GooList *toUnicodeDirs; // list of ToUnicode CMap dirs [GooString] GBool baseFontsInitialized; #ifdef _WIN32 - GooHash *substFiles; // windows font substitutes (for CID fonts) + // windows font substitutes (for CID fonts) + std::unordered_map<std::string, std::string> substFiles; #endif // font files: font name mapped to path std::unordered_map<std::string, std::string> fontFiles; diff --git a/poppler/GlobalParamsWin.cc b/poppler/GlobalParamsWin.cc index 1734f6eb..725709e9 100644 --- a/poppler/GlobalParamsWin.cc +++ b/poppler/GlobalParamsWin.cc @@ -37,7 +37,6 @@ description for all fonts available in Windows. That's how MuPDF works. #include "goo/gmem.h" #include "goo/GooString.h" #include "goo/GooList.h" -#include "goo/GooHash.h" #include "goo/gfile.h" #include "Error.h" #include "NameToCharCode.h" @@ -479,7 +478,7 @@ void GlobalParams::setupBaseFonts(char * dir) addFontFile(new GooString(obj1.getName()), obj3.getString()->copy()); // Aliases } else if (obj2.isName()) { - substFiles->add(new GooString(obj1.getName()), new GooString(obj2.getName())); + substFiles.emplace(obj1.getName(), obj2.getName()); } } obj1 = parser->getObj(); @@ -496,8 +495,8 @@ void GlobalParams::setupBaseFonts(char * dir) } } -static const char *findSubstituteName(GfxFont *font, GooHash *fontFiles, - GooHash *substFiles, +static const char *findSubstituteName(GfxFont *font, const std::unordered_map<std::string, std::string>& fontFiles, + const std::unordered_map<std::string, std::string>& substFiles, const char *origName) { assert(origName); @@ -514,10 +513,10 @@ static const char *findSubstituteName(GfxFont *font, GooHash *fontFiles, name2->del(n - 11, 11); n -= 11; } - GooString *substName = (GooString *)substFiles->lookup(name2); - if (substName != nullptr) { + const auto substFile = substFiles.find(name2->getCString()); + if (substFile != substFiles.end()) { delete name2; - return substName->getCString(); + return substFile->second.c_str(); } /* TODO: try to at least guess bold/italic/bolditalic from the name */ @@ -537,10 +536,10 @@ static const char *findSubstituteName(GfxFont *font, GooHash *fontFiles, else if ( !collection->cmp("Adobe-Korea1") ) name3 = DEFAULT_CID_FONT_AK1_MSWIN; - if (name3 && fontFiles->lookup(name3)) + if (name3 && fontFiles.count(name3) != 0) return name3; - if (fontFiles->lookup(DEFAULT_CID_FONT_MSWIN)) + if (fontFiles.count(DEFAULT_CID_FONT_MSWIN) != 0) return DEFAULT_CID_FONT_MSWIN; } return DEFAULT_SUBSTITUTE_FONT; @@ -572,10 +571,10 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font, GooString *substFontName = new GooString(findSubstituteName(font, fontFiles, substFiles, fontName->getCString())); - GooString *path2 = nullptr; error(errSyntaxError, -1, "Couldn't find a font for '{0:t}', subst is '{1:t}'", fontName, substFontName); - if ((path2 = (GooString *)fontFiles->lookup(substFontName))) { - path = new GooString(path2); + const auto fontFile = fontFiles.find(substFontName); + if (fontFile != fontFiles.end()) { + path = new GooString(fontFile->second.c_str()); if (substituteFontName) substituteFontName->Set(path->getCString()); if (!strcasecmp(path->getCString() + path->getLength() - 4, ".ttc")) { -- 2.16.1 From 9ccbe0b871ec7022450e3776b236c7c6e2175c67 Mon Sep 17 00:00:00 2001 From: Adam Reichold <[email protected]> Date: Sun, 18 Feb 2018 16:12:19 +0100 Subject: [PATCH 7/8] Remove GooHash after replacing it by std::unordered_map. --- CMakeLists.txt | 2 - goo/GooHash.cc | 402 --------------------------------------------------------- goo/GooHash.h | 92 ------------- 3 files changed, 496 deletions(-) delete mode 100644 goo/GooHash.cc delete mode 100644 goo/GooHash.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e3d6a17..5156874b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -308,7 +308,6 @@ configure_file(poppler/poppler-config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/popple set(poppler_SRCS goo/gfile.cc goo/gmempp.cc - goo/GooHash.cc goo/GooList.cc goo/GooTimer.cc goo/GooString.cc @@ -572,7 +571,6 @@ if(ENABLE_XPDF_HEADERS) ${CMAKE_CURRENT_BINARY_DIR}/poppler/poppler-config.h DESTINATION include/poppler) install(FILES - goo/GooHash.h goo/GooList.h goo/GooTimer.h goo/GooMutex.h diff --git a/goo/GooHash.cc b/goo/GooHash.cc deleted file mode 100644 index cd39a5ae..00000000 --- a/goo/GooHash.cc +++ /dev/null @@ -1,402 +0,0 @@ -//======================================================================== -// -// GooHash.cc -// -// Copyright 2001-2003 Glyph & Cog, LLC -// -//======================================================================== - -//======================================================================== -// -// Modified under the Poppler project - http://poppler.freedesktop.org -// -// All changes made under the Poppler project to this file are licensed -// under GPL version 2 or later -// -// Copyright (C) 2017 Albert Astals Cid <[email protected]> -// -// To see a description of the changes please see the Changelog file that -// came with your tarball or type make ChangeLog if you are building from git -// -//======================================================================== - -#include <config.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include "gmem.h" -#include "GooString.h" -#include "GooHash.h" -#include "GooLikely.h" - -//------------------------------------------------------------------------ - -struct GooHashBucket { - GooString *key; - union { - void *p; - int i; - } val; - GooHashBucket *next; -}; - -struct GooHashIter { - int h; - GooHashBucket *p; -}; - -//------------------------------------------------------------------------ - -GooHash::GooHash(GBool deleteKeysA) { - int h; - - deleteKeys = deleteKeysA; - size = 7; - tab = (GooHashBucket **)gmallocn(size, sizeof(GooHashBucket *)); - for (h = 0; h < size; ++h) { - tab[h] = nullptr; - } - len = 0; -} - -GooHash::~GooHash() { - GooHashBucket *p; - int h; - - for (h = 0; h < size; ++h) { - while (tab[h]) { - p = tab[h]; - tab[h] = p->next; - if (deleteKeys) { - delete p->key; - } - delete p; - } - } - gfree(tab); -} - -void GooHash::add(GooString *key, void *val) { - GooHashBucket *p; - int h; - - // expand the table if necessary - if (len >= size) { - expand(); - } - - // add the new symbol - p = new GooHashBucket; - p->key = key; - p->val.p = val; - h = hash(key); - p->next = tab[h]; - tab[h] = p; - ++len; -} - -void GooHash::add(GooString *key, int val) { - GooHashBucket *p; - int h; - - // expand the table if necessary - if (len >= size) { - expand(); - } - - // add the new symbol - p = new GooHashBucket; - p->key = key; - p->val.i = val; - h = hash(key); - p->next = tab[h]; - tab[h] = p; - ++len; -} - -void GooHash::replace(GooString *key, void *val) { - GooHashBucket *p; - int h; - - if ((p = find(key, &h))) { - p->val.p = val; - if (deleteKeys) { - delete key; - } - } else { - add(key, val); - } -} - -void GooHash::replace(GooString *key, int val) { - GooHashBucket *p; - int h; - - if ((p = find(key, &h))) { - p->val.i = val; - if (deleteKeys) { - delete key; - } - } else { - add(key, val); - } -} - -void *GooHash::lookup(GooString *key) { - GooHashBucket *p; - int h; - - if (!(p = find(key, &h))) { - return nullptr; - } - return p->val.p; -} - -int GooHash::lookupInt(GooString *key) { - GooHashBucket *p; - int h; - - if (!(p = find(key, &h))) { - return 0; - } - return p->val.i; -} - -void *GooHash::lookup(const char *key) { - GooHashBucket *p; - int h; - - if (!(p = find(key, &h))) { - return nullptr; - } - return p->val.p; -} - -int GooHash::lookupInt(const char *key) { - GooHashBucket *p; - int h; - - if (!(p = find(key, &h))) { - return 0; - } - return p->val.i; -} - -void *GooHash::remove(GooString *key) { - GooHashBucket *p; - GooHashBucket **q; - void *val; - int h; - - if (!(p = find(key, &h))) { - return nullptr; - } - q = &tab[h]; - while (*q != p) { - q = &((*q)->next); - } - *q = p->next; - if (deleteKeys) { - delete p->key; - } - val = p->val.p; - delete p; - --len; - return val; -} - -int GooHash::removeInt(GooString *key) { - GooHashBucket *p; - GooHashBucket **q; - int val; - int h; - - if (!(p = find(key, &h))) { - return 0; - } - q = &tab[h]; - while (*q != p) { - q = &((*q)->next); - } - *q = p->next; - if (deleteKeys) { - delete p->key; - } - val = p->val.i; - delete p; - --len; - return val; -} - -void *GooHash::remove(const char *key) { - GooHashBucket *p; - GooHashBucket **q; - void *val; - int h; - - if (!(p = find(key, &h))) { - return nullptr; - } - q = &tab[h]; - while (*q != p) { - q = &((*q)->next); - } - *q = p->next; - if (deleteKeys) { - delete p->key; - } - val = p->val.p; - delete p; - --len; - return val; -} - -int GooHash::removeInt(const char *key) { - GooHashBucket *p; - GooHashBucket **q; - int val; - int h; - - if (!(p = find(key, &h))) { - return 0; - } - q = &tab[h]; - while (*q != p) { - q = &((*q)->next); - } - *q = p->next; - if (deleteKeys) { - delete p->key; - } - val = p->val.i; - delete p; - --len; - return val; -} - -void GooHash::startIter(GooHashIter **iter) { - *iter = new GooHashIter; - (*iter)->h = -1; - (*iter)->p = nullptr; -} - -GBool GooHash::getNext(GooHashIter **iter, GooString **key, void **val) { - if (!*iter) { - return gFalse; - } - if ((*iter)->p) { - (*iter)->p = (*iter)->p->next; - } - while (!(*iter)->p) { - if (++(*iter)->h == size) { - delete *iter; - *iter = nullptr; - return gFalse; - } - (*iter)->p = tab[(*iter)->h]; - } - *key = (*iter)->p->key; - *val = (*iter)->p->val.p; - return gTrue; -} - -GBool GooHash::getNext(GooHashIter **iter, GooString **key, int *val) { - if (!*iter) { - return gFalse; - } - if ((*iter)->p) { - (*iter)->p = (*iter)->p->next; - } - while (!(*iter)->p) { - if (++(*iter)->h == size) { - delete *iter; - *iter = nullptr; - return gFalse; - } - (*iter)->p = tab[(*iter)->h]; - } - *key = (*iter)->p->key; - *val = (*iter)->p->val.i; - return gTrue; -} - -void GooHash::killIter(GooHashIter **iter) { - delete *iter; - *iter = nullptr; -} - -void GooHash::expand() { - GooHashBucket **oldTab; - GooHashBucket *p; - int oldSize, h, i; - - oldSize = size; - oldTab = tab; - size = 2*size + 1; - tab = (GooHashBucket **)gmallocn(size, sizeof(GooHashBucket *)); - for (h = 0; h < size; ++h) { - tab[h] = nullptr; - } - for (i = 0; i < oldSize; ++i) { - while (oldTab[i]) { - p = oldTab[i]; - oldTab[i] = oldTab[i]->next; - h = hash(p->key); - p->next = tab[h]; - tab[h] = p; - } - } - gfree(oldTab); -} - -GooHashBucket *GooHash::find(GooString *key, int *h) { - GooHashBucket *p; - - if (unlikely(!key)) - return nullptr; - - *h = hash(key); - for (p = tab[*h]; p; p = p->next) { - if (!p->key->cmp(key)) { - return p; - } - } - return nullptr; -} - -GooHashBucket *GooHash::find(const char *key, int *h) { - GooHashBucket *p; - - *h = hash(key); - for (p = tab[*h]; p; p = p->next) { - if (!p->key->cmp(key)) { - return p; - } - } - return nullptr; -} - -int GooHash::hash(GooString *key) { - const char *p; - unsigned int h; - int i; - - h = 0; - for (p = key->getCString(), i = 0; i < key->getLength(); ++p, ++i) { - h = 17 * h + (int)(*p & 0xff); - } - return (int)(h % size); -} - -int GooHash::hash(const char *key) { - const char *p; - unsigned int h; - - h = 0; - for (p = key; *p; ++p) { - h = 17 * h + (int)(*p & 0xff); - } - return (int)(h % size); -} diff --git a/goo/GooHash.h b/goo/GooHash.h deleted file mode 100644 index eda19e31..00000000 --- a/goo/GooHash.h +++ /dev/null @@ -1,92 +0,0 @@ -//======================================================================== -// -// GooHash.h -// -// Copyright 2001-2003 Glyph & Cog, LLC -// -//======================================================================== - -//======================================================================== -// -// Modified under the Poppler project - http://poppler.freedesktop.org -// -// All changes made under the Poppler project to this file are licensed -// under GPL version 2 or later -// -// Copyright (C) 2012 Albert Astals Cid <[email protected]> -// -// To see a description of the changes please see the Changelog file that -// came with your tarball or type make ChangeLog if you are building from git -// -//======================================================================== - -#ifndef GHASH_H -#define GHASH_H - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "gtypes.h" - -class GooString; -struct GooHashBucket; -struct GooHashIter; - -//------------------------------------------------------------------------ - -class GooHash { -public: - - GooHash(GBool deleteKeysA = gFalse); - ~GooHash(); - void add(GooString *key, void *val); - void add(GooString *key, int val); - void replace(GooString *key, void *val); - void replace(GooString *key, int val); - void *lookup(GooString *key); - int lookupInt(GooString *key); - void *lookup(const char *key); - int lookupInt(const char *key); - void *remove(GooString *key); - int removeInt(GooString *key); - void *remove(const char *key); - int removeInt(const char *key); - int getLength() { return len; } - void startIter(GooHashIter **iter); - GBool getNext(GooHashIter **iter, GooString **key, void **val); - GBool getNext(GooHashIter **iter, GooString **key, int *val); - void killIter(GooHashIter **iter); - -private: - GooHash(const GooHash &other); - GooHash& operator=(const GooHash &other); - - void expand(); - GooHashBucket *find(GooString *key, int *h); - GooHashBucket *find(const char *key, int *h); - int hash(GooString *key); - int hash(const char *key); - - GBool deleteKeys; // set if key strings should be deleted - int size; // number of buckets - int len; // number of entries - GooHashBucket **tab; -}; - -#define deleteGooHash(hash, T) \ - do { \ - GooHash *_hash = (hash); \ - { \ - GooHashIter *_iter; \ - GooString *_key; \ - void *_p; \ - _hash->startIter(&_iter); \ - while (_hash->getNext(&_iter, &_key, &_p)) { \ - delete (T*)_p; \ - } \ - delete _hash; \ - } \ - } while(0) - -#endif -- 2.16.1 From db622c80d21ef15f1fdda556dc4b07bfd81bf0b4 Mon Sep 17 00:00:00 2001 From: Adam Reichold <[email protected]> Date: Wed, 21 Feb 2018 20:15:22 +0100 Subject: [PATCH 8/8] Make UnicodeMap a move-only type to simplify the initialization of residentUnicodeMaps s.t. it is closer to the GooHash-based version. --- poppler/GlobalParams.cc | 35 ++++++---------- poppler/UnicodeMap.cc | 108 +++++++++++++++++++++++++++++++++++------------- poppler/UnicodeMap.h | 15 ++++--- 3 files changed, 98 insertions(+), 60 deletions(-) diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc index c119f9df..0606a389 100644 --- a/poppler/GlobalParams.cc +++ b/poppler/GlobalParams.cc @@ -608,30 +608,19 @@ GlobalParams::GlobalParams(const char *customPopplerDataDir) } // set up the residentUnicodeMaps table - - const auto emplaceRangeMap = [&](const char* encodingName, GBool unicodeOut, UnicodeMapRange* ranges, int len) { - residentUnicodeMaps.emplace( - std::piecewise_construct, - std::forward_as_tuple(encodingName), - std::forward_as_tuple(encodingName, unicodeOut, ranges, len) - ); - }; - - const auto emplaceFuncMap = [&](const char* encodingName, GBool unicodeOut, UnicodeMapFunc func) { - residentUnicodeMaps.emplace( - std::piecewise_construct, - std::forward_as_tuple(encodingName), - std::forward_as_tuple(encodingName, unicodeOut, func) - ); - }; - residentUnicodeMaps.reserve(6); - emplaceRangeMap("Latin1", gFalse, latin1UnicodeMapRanges, latin1UnicodeMapLen); - emplaceRangeMap("ASCII7", gFalse, ascii7UnicodeMapRanges, ascii7UnicodeMapLen); - emplaceRangeMap("Symbol", gFalse, symbolUnicodeMapRanges, symbolUnicodeMapLen); - emplaceRangeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges, zapfDingbatsUnicodeMapLen); - emplaceFuncMap("UTF-8", gTrue, &mapUTF8); - emplaceFuncMap("UTF-16", gTrue, &mapUTF16); + UnicodeMap map = {"Latin1", gFalse, latin1UnicodeMapRanges, latin1UnicodeMapLen}; + residentUnicodeMaps.emplace(map.getEncodingName()->toStr(), std::move(map)); + map = {"ASCII7", gFalse, ascii7UnicodeMapRanges, ascii7UnicodeMapLen}; + residentUnicodeMaps.emplace(map.getEncodingName()->toStr(), std::move(map)); + map = {"Symbol", gFalse, symbolUnicodeMapRanges, symbolUnicodeMapLen}; + residentUnicodeMaps.emplace(map.getEncodingName()->toStr(), std::move(map)); + map = {"ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges, zapfDingbatsUnicodeMapLen}; + residentUnicodeMaps.emplace(map.getEncodingName()->toStr(), std::move(map)); + map = {"UTF-8", gTrue, &mapUTF8}; + residentUnicodeMaps.emplace(map.getEncodingName()->toStr(), std::move(map)); + map = {"UTF-16", gTrue, &mapUTF16}; + residentUnicodeMaps.emplace(map.getEncodingName()->toStr(), std::move(map)); scanEncodingDirs(); } diff --git a/poppler/UnicodeMap.cc b/poppler/UnicodeMap.cc index dabdce2a..94fbcaf4 100644 --- a/poppler/UnicodeMap.cc +++ b/poppler/UnicodeMap.cc @@ -139,9 +139,6 @@ UnicodeMap::UnicodeMap(GooString *encodingNameA) { eMaps = nullptr; eMapsLen = 0; refCnt = 1; -#ifdef MULTITHREADED - gInitMutex(&mutex); -#endif } UnicodeMap::UnicodeMap(const char *encodingNameA, GBool unicodeOutA, @@ -154,9 +151,6 @@ UnicodeMap::UnicodeMap(const char *encodingNameA, GBool unicodeOutA, eMaps = nullptr; eMapsLen = 0; refCnt = 1; -#ifdef MULTITHREADED - gInitMutex(&mutex); -#endif } UnicodeMap::UnicodeMap(const char *encodingNameA, GBool unicodeOutA, @@ -168,9 +162,6 @@ UnicodeMap::UnicodeMap(const char *encodingNameA, GBool unicodeOutA, eMaps = nullptr; eMapsLen = 0; refCnt = 1; -#ifdef MULTITHREADED - gInitMutex(&mutex); -#endif } UnicodeMap::~UnicodeMap() { @@ -181,32 +172,91 @@ UnicodeMap::~UnicodeMap() { if (eMaps) { gfree(eMaps); } -#ifdef MULTITHREADED - gDestroyMutex(&mutex); -#endif +} + +UnicodeMap::UnicodeMap(UnicodeMap &&other) noexcept + : encodingName{other.encodingName} + , kind{other.kind} + , unicodeOut{other.unicodeOut} + , len{other.len} + , eMaps{other.eMaps} + , eMapsLen{other.eMapsLen} + , refCnt{other.refCnt.load()} +{ + switch (kind) { + case unicodeMapUser: + case unicodeMapResident: + ranges = other.ranges; + other.ranges = nullptr; + break; + case unicodeMapFunc: + func = other.func; + break; + } + other.encodingName = nullptr; + other.eMaps = nullptr; +} + +UnicodeMap& UnicodeMap::operator=(UnicodeMap &&other) noexcept +{ + if (this != &other) + swap(other); + return *this; +} + +void UnicodeMap::swap(UnicodeMap &other) noexcept +{ + using std::swap; + swap(encodingName, other.encodingName); + swap(unicodeOut, other.unicodeOut); + switch (kind) { + case unicodeMapUser: + case unicodeMapResident: + switch (other.kind) { + case unicodeMapUser: + case unicodeMapResident: + swap(ranges, other.ranges); + break; + case unicodeMapFunc: + { + const auto tmp = ranges; + func = other.func; + other.ranges = tmp; + break; + } + } + break; + case unicodeMapFunc: + switch (other.kind) { + case unicodeMapUser: + case unicodeMapResident: + { + const auto tmp = func; + ranges = other.ranges; + other.func = tmp; + break; + } + case unicodeMapFunc: + swap(func, other.func); + break; + } + break; + } + swap(kind, other.kind); + swap(len, other.len); + swap(eMaps, other.eMaps); + swap(eMapsLen, other.eMapsLen); + const auto tmp = refCnt.load(); + refCnt = other.refCnt.load(); + other.refCnt = tmp; } void UnicodeMap::incRefCnt() { -#ifdef MULTITHREADED - gLockMutex(&mutex); -#endif - ++refCnt; -#ifdef MULTITHREADED - gUnlockMutex(&mutex); -#endif + refCnt.fetch_add(1); } void UnicodeMap::decRefCnt() { - GBool done; - -#ifdef MULTITHREADED - gLockMutex(&mutex); -#endif - done = --refCnt == 0; -#ifdef MULTITHREADED - gUnlockMutex(&mutex); -#endif - if (done) { + if (refCnt.fetch_sub(1) == 1) { delete this; } } diff --git a/poppler/UnicodeMap.h b/poppler/UnicodeMap.h index f3444aa5..b741ff61 100644 --- a/poppler/UnicodeMap.h +++ b/poppler/UnicodeMap.h @@ -33,10 +33,7 @@ #include "poppler-config.h" #include "goo/gtypes.h" #include "CharTypes.h" - -#ifdef MULTITHREADED -#include "goo/GooMutex.h" -#endif +#include <atomic> class GooString; @@ -75,6 +72,11 @@ public: UnicodeMap(const char *encodingNameA, GBool unicodeOutA, UnicodeMapFunc funcA); + UnicodeMap(UnicodeMap &&other) noexcept; + UnicodeMap& operator=(UnicodeMap &&other) noexcept; + + void swap(UnicodeMap& other) noexcept; + ~UnicodeMap(); UnicodeMap(const UnicodeMap &) = delete; @@ -111,10 +113,7 @@ private: int len; // (user, resident) UnicodeMapExt *eMaps; // (user) int eMapsLen; // (user) - int refCnt; -#ifdef MULTITHREADED - GooMutex mutex; -#endif + std::atomic_int refCnt; }; //------------------------------------------------------------------------ -- 2.16.1
signature.asc
Description: OpenPGP digital signature
_______________________________________________ poppler mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/poppler
