GfxDeviceNColorSpace: Port to std::vector<std::string>

I was tired of having two constructors for GfxDeviceNColorSpace, both
taking GooString ** but one copying those strings and the other keeping
them for itself.

Moved to std::vector<std::string> without much fallout in the rest of
the code
diff --git a/goo/GooString.h b/goo/GooString.h
index 74e4f77..38950ae 100644
--- a/goo/GooString.h
+++ b/goo/GooString.h
@@ -17,7 +17,7 @@
 //
 // Copyright (C) 2006 Kristian Høgsberg <krh@redhat.com>
 // Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
-// Copyright (C) 2008-2010, 2012, 2014, 2017, 2018 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2008-2010, 2012, 2014, 2017-2019 Albert Astals Cid <aacid@kde.org>
 // Copyright (C) 2012-2014 Fabio D'Urso <fabiodurso@hotmail.it>
 // Copyright (C) 2013 Jason Crain <jason@aquaticape.us>
 // Copyright (C) 2015, 2018 Adam Reichold <adam.reichold@t-online.de>
@@ -164,6 +164,7 @@
 
   // Compare two strings:  -1:<  0:=  +1:>
   int cmp(const GooString *str) const { return compare(*str); }
+  int cmp(const std::string &str) const { return compare(str); }
   int cmpN(GooString *str, int n) const { return compare(0, n, *str); }
   int cmp(const char *sA) const { return compare(sA); }
   int cmpN(const char *sA, int n) const { return compare(0, n, sA); }
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 41d77ae..5a95386 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -2903,33 +2903,32 @@
 //------------------------------------------------------------------------
 
 GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA,
-					   GooString **namesA,
+					   std::vector<std::string> &&namesA,
 					   GfxColorSpace *altA,
 					   Function *funcA,
-					   std::vector<GfxSeparationColorSpace*> *sepsCSA) {
-  int i;
-
-  nComps = nCompsA;
+					   std::vector<GfxSeparationColorSpace*> *sepsCSA)
+ : nComps(nCompsA)
+ , names(std::move(namesA))
+{
   alt = altA;
   func = funcA;
   sepsCS = sepsCSA;
   nonMarking = true;
   overprintMask = 0;
   mapping = nullptr;
-  for (i = 0; i < nComps; ++i) {
-    names[i] = namesA[i];
-    if (names[i]->cmp("None")) {
+  for (int i = 0; i < nComps; ++i) {
+    if (names[i].compare("None")) {
       nonMarking = false;
     }
-    if (!names[i]->cmp("Cyan")) {
+    if (!names[i].compare("Cyan")) {
       overprintMask |= 0x01;
-    } else if (!names[i]->cmp("Magenta")) {
+    } else if (!names[i].compare("Magenta")) {
       overprintMask |= 0x02;
-    } else if (!names[i]->cmp("Yellow")) {
+    } else if (!names[i].compare("Yellow")) {
       overprintMask |= 0x04;
-    } else if (!names[i]->cmp("Black")) {
+    } else if (!names[i].compare("Black")) {
       overprintMask |= 0x08;
-    } else if (!names[i]->cmp("All")) {
+    } else if (!names[i].compare("All")) {
       overprintMask = 0xffffffff;
     } else {
       overprintMask = 0x0f;
@@ -2938,33 +2937,25 @@
 }
 
 GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA,
-					   GooString **namesA,
+					   const std::vector<std::string> &namesA,
 					   GfxColorSpace *altA,
 					   Function *funcA,
 					   std::vector<GfxSeparationColorSpace*> *sepsCSA,
 					   int *mappingA,
 					   bool nonMarkingA,
-					   unsigned int overprintMaskA) {
-  int i;
-
-  nComps = nCompsA;
+					   unsigned int overprintMaskA)
+ : nComps(nCompsA)
+ , names(namesA)
+{
   alt = altA;
   func = funcA;
   sepsCS = sepsCSA;
   mapping = mappingA;
   nonMarking = nonMarkingA;
   overprintMask = overprintMaskA;
-  for (i = 0; i < nComps; ++i) {
-    names[i] = namesA[i]->copy();
-  }
 }
 
 GfxDeviceNColorSpace::~GfxDeviceNColorSpace() {
-  int i;
-
-  for (i = 0; i < nComps; ++i) {
-    delete names[i];
-  }
   delete alt;
   delete func;
   for (auto entry : *sepsCS) {
@@ -2998,11 +2989,10 @@
 //~ handle the 'None' colorant
 GfxColorSpace *GfxDeviceNColorSpace::parse(GfxResources *res, Array *arr, OutputDev *out, GfxState *state, int recursion) {
   int nCompsA;
-  GooString *namesA[gfxColorMaxComps];
+  std::vector<std::string> namesA;
   GfxColorSpace *altA;
   Function *funcA;
   Object obj1;
-  int i;
   auto separationList = new std::vector<GfxSeparationColorSpace*>();
 
   if (arr->getLength() != 4 && arr->getLength() != 5) {
@@ -3020,19 +3010,19 @@
 	  nCompsA, gfxColorMaxComps);
     nCompsA = gfxColorMaxComps;
   }
-  for (i = 0; i < nCompsA; ++i) {
+  for (int i = 0; i < nCompsA; ++i) {
     Object obj2 = obj1.arrayGet(i);
     if (!obj2.isName()) {
       error(errSyntaxWarning, -1, "Bad DeviceN color space (names)");
       nCompsA = i;
-      goto err3;
+      goto err1;
     }
-    namesA[i] = new GooString(obj2.getName());
+    namesA.emplace_back(obj2.getName());
   }
   obj1 = arr->get(2);
   if (!(altA = GfxColorSpace::parse(res, &obj1, out, state, recursion + 1))) {
     error(errSyntaxWarning, -1, "Bad DeviceN color space (alternate color space)");
-    goto err3;
+    goto err1;
   }
   obj1 = arr->get(3);
   if (!(funcA = Function::parse(&obj1))) {
@@ -3048,7 +3038,7 @@
     Object obj2 = attribs->lookup("Colorants");
     if (obj2.isDict()) {
       Dict *colorants = obj2.getDict();
-      for (i = 0; i < colorants->getLength(); i++) {
+      for (int i = 0; i < colorants->getLength(); i++) {
         Object obj3 = colorants->getVal(i);
         if (obj3.isArray()) {
 	  GfxSeparationColorSpace *cs = (GfxSeparationColorSpace*)GfxSeparationColorSpace::parse(res, obj3.getArray(), out, state, recursion);
@@ -3062,16 +3052,12 @@
       }
     }
   }
-  return new GfxDeviceNColorSpace(nCompsA, namesA, altA, funcA, separationList);
+  return new GfxDeviceNColorSpace(nCompsA, std::move(namesA), altA, funcA, separationList);
 
  err5:
   delete funcA;
  err4:
   delete altA;
- err3:
-  for (i = 0; i < nCompsA; ++i) {
-    delete namesA[i];
-  }
  err1:
   delete separationList;
   return nullptr;
@@ -3154,18 +3140,18 @@
   mapping = (int *)gmalloc(sizeof(int) * nComps);
   unsigned int newOverprintMask = 0;
   for (int i = 0; i < nComps; i++) {
-    if (!names[i]->cmp("None")) {
+    if (!names[i].compare("None")) {
       mapping[i] = -1;
-    } else if (!names[i]->cmp("Cyan")) {
+    } else if (!names[i].compare("Cyan")) {
       newOverprintMask |= 0x01;
       mapping[i] = 0;
-    } else if (!names[i]->cmp("Magenta")) {
+    } else if (!names[i].compare("Magenta")) {
       newOverprintMask |= 0x02;
       mapping[i] = 1;
-    } else if (!names[i]->cmp("Yellow")) {
+    } else if (!names[i].compare("Yellow")) {
       newOverprintMask |= 0x04;
       mapping[i] = 2;
-    } else if (!names[i]->cmp("Black")) {
+    } else if (!names[i].compare("Black")) {
       newOverprintMask |= 0x08;
       mapping[i] = 3;
     } else {
@@ -3188,7 +3174,7 @@
         if (!sepCS->getName()->cmp(names[i])) {
           if (sepFunc != nullptr && sepCS->getFunc()->hasDifferentResultSet(sepFunc)) {
             error(errSyntaxWarning, -1,
-              "Different functions found for '{0:t}', convert immediately", names[i]);
+              "Different functions found for '{0:s}', convert immediately", names[i].c_str());
             gfree(mapping);
             mapping = nullptr;
             overprintMask = 0xffffffff;
@@ -3204,7 +3190,7 @@
       if (!found) {
         if ((int)separationList->size() == maxSepComps) {
           error(errSyntaxWarning, -1,
-            "Too many ({0:d}) spots, convert '{1:t}' immediately", maxSepComps, names[i]);
+            "Too many ({0:d}) spots, convert '{1:s}' immediately", maxSepComps, names[i].c_str());
           gfree(mapping);
           mapping = nullptr;
           overprintMask = 0xffffffff;
@@ -3213,7 +3199,7 @@
         mapping[i] = separationList->size() + 4;
         newOverprintMask |= startOverprintMask;
         if (nComps == 1)
-	  separationList->push_back(new GfxSeparationColorSpace(names[i]->copy(),alt->copy(), func->copy()));
+	  separationList->push_back(new GfxSeparationColorSpace(new GooString(names[i]),alt->copy(), func->copy()));
         else {
           for (std::size_t k = 0; k < sepsCS->size(); k++) {
             GfxSeparationColorSpace *sepCS = (*sepsCS)[k];
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 88463d1..5a66a18 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -682,7 +682,7 @@
 class GfxDeviceNColorSpace: public GfxColorSpace {
 public:
 
-  GfxDeviceNColorSpace(int nCompsA, GooString **namesA,
+  GfxDeviceNColorSpace(int nCompsA, std::vector<std::string> &&namesA,
 		       GfxColorSpace *alt, Function *func, std::vector<GfxSeparationColorSpace*> *sepsCS);
   ~GfxDeviceNColorSpace();
   GfxColorSpace *copy() override;
@@ -704,19 +704,18 @@
   bool isNonMarking() const override { return nonMarking; }
 
   // DeviceN-specific access.
-  const GooString *getColorantName(int i) const { return names[i]; }
+  const std::string &getColorantName(int i) const { return names[i]; }
   GfxColorSpace *getAlt() { return alt; }
   Function *getTintTransformFunc() { return func; }
 
 private:
 
-  GfxDeviceNColorSpace(int nCompsA, GooString **namesA,
+  GfxDeviceNColorSpace(int nCompsA, const std::vector<std::string> &namesA,
 		       GfxColorSpace *alt, Function *func, std::vector<GfxSeparationColorSpace*> *sepsCSA,
 		       int *mappingA, bool nonMarkingA, unsigned int overprintMaskA);
 
-  int nComps;			// number of components
-  GooString			// colorant names
-    *names[gfxColorMaxComps];
+  const int nComps;			// number of components
+  const std::vector<std::string> names;	// colorant names
   GfxColorSpace *alt;		// alternate color space
   Function *func;		// tint transform (into alternate color space)
   bool nonMarking;
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index c7c1304..694d059 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -1766,14 +1766,14 @@
       writePS("%%DocumentCustomColors:");
       for (cc = customColors; cc; cc = cc->next) {
 	writePS(" ");
-	writePSString(cc->name);
+	writePSString(cc->name->toStr());
       }
       writePS("\n");
       writePS("%%CMYKCustomColor:\n");
       for (cc = customColors; cc; cc = cc->next) {
 	writePSFmt("%%+ {0:.4g} {1:.4g} {2:.4g} {3:.4g} ",
 		   cc->c, cc->m, cc->y, cc->k);
-	writePSString(cc->name);
+	writePSString(cc->name->toStr());
 	writePS("\n");
       }
     }
@@ -5178,7 +5178,7 @@
   }
 
   if (nChars > 0) {
-    writePSString(s2);
+    writePSString(s2->toStr());
     writePS("\n[");
     for (i = 0; i < 2 * nChars; ++i) {
       if (i > 0) {
@@ -6812,7 +6812,7 @@
   case csSeparation:
     separationCS = (GfxSeparationColorSpace *)colorSpace;
     writePS("[/Separation ");
-    writePSString(separationCS->getName());
+    writePSString(separationCS->getName()->toStr());
     writePS(" ");
     dumpColorSpaceL2(separationCS->getAlt(), false, false, false);
     writePS("\n");
@@ -6936,7 +6936,7 @@
 	Object obj4 = obj1.arrayGet(i+1);
 	if (obj3.isString() && obj4.isNum()) {
 	  writePS(" ");
-	  writePSString(obj3.getString());
+	  writePSString(obj3.getString()->toStr());
 	  writePSFmt(" {0:.6g}", obj4.getNum());
 	}
       }
@@ -7011,7 +7011,7 @@
     if (obj2.isString()) {
       writePSFmt("%ALDImageColor: {0:.4g} {1:.4g} {2:.4g} {3:.4g} ",
 		 c, m, y, k);
-      writePSString(obj2.getString());
+      writePSString(obj2.getString()->toStr());
       writePS("\n");
     }
   }
@@ -7458,14 +7458,14 @@
   va_end(args);
 }
 
-void PSOutputDev::writePSString(const GooString *s) {
+void PSOutputDev::writePSString(const std::string &s) {
   unsigned char *p;
   int n, line;
   char buf[8];
 
   writePSChar('(');
   line = 1;
-  for (p = (unsigned char *)s->c_str(), n = s->getLength(); n; ++p, --n) {
+  for (p = (unsigned char *)s.c_str(), n = s.size(); n; ++p, --n) {
     if (line >= 64) {
       writePSChar('\\');
       writePSChar('\n');
diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h
index 51f1401..44dacf8 100644
--- a/poppler/PSOutputDev.h
+++ b/poppler/PSOutputDev.h
@@ -435,7 +435,7 @@
   void writePS(const char *s);
   void writePSBuf(const char *s, int len);
   void writePSFmt(const char *fmt, ...);
-  void writePSString(const GooString *s);
+  void writePSString(const std::string &s);
   void writePSName(const char *s);
   GooString *filterPSLabel(GooString *label, bool *needParens=nullptr);
   void writePSTextLine(const GooString *s);
diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index e3fcf9c..aba4578 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -1740,13 +1740,13 @@
       GfxDeviceNColorSpace *deviceNCS = (GfxDeviceNColorSpace *)colorSpace;
       additive = mask == 0x0f && !deviceNCS->isNonMarking();
       for (i = 0; i < deviceNCS->getNComps() && additive; i++) {
-        if (deviceNCS->getColorantName(i)->cmp("Cyan") == 0) {
+        if (deviceNCS->getColorantName(i).compare("Cyan") == 0) {
           additive = false;
-        } else if (deviceNCS->getColorantName(i)->cmp("Magenta") == 0) {
+        } else if (deviceNCS->getColorantName(i).compare("Magenta") == 0) {
           additive = false;
-        } else if (deviceNCS->getColorantName(i)->cmp("Yellow") == 0) {
+        } else if (deviceNCS->getColorantName(i).compare("Yellow") == 0) {
           additive = false;
-        } else if (deviceNCS->getColorantName(i)->cmp("Black") == 0) {
+        } else if (deviceNCS->getColorantName(i).compare("Black") == 0) {
           additive = false;
         }
       }