Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 7b7b78c

Browse files
Ben WagnerSkia Commit-Bot
authored andcommitted
Make SkPDFUnion a better variant.
SkPDFUnion is basically a tagged union but does some odd things around unique_ptr and SkString. Clean up the implementation around these. This also fixes a number of warnings given by gcc 9. Change-Id: Iaf58b30c03f172e96a28826ddaa616bf9f655f71 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/277613 Reviewed-by: Herb Derby <[email protected]> Commit-Queue: Ben Wagner <[email protected]>
1 parent bcf5172 commit 7b7b78c

File tree

2 files changed

+71
-81
lines changed

2 files changed

+71
-81
lines changed

src/pdf/SkPDFTypes.cpp

Lines changed: 61 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -21,72 +21,76 @@
2121

2222
////////////////////////////////////////////////////////////////////////////////
2323

24-
SkPDFUnion::SkPDFUnion(Type t) : fType(t) {}
25-
SkPDFUnion::SkPDFUnion(Type t, int32_t v) : fIntValue (v), fType(t) {}
26-
SkPDFUnion::SkPDFUnion(Type t, bool v) : fBoolValue (v), fType(t) {}
27-
SkPDFUnion::SkPDFUnion(Type t, SkScalar v) : fScalarValue (v), fType(t) {}
28-
SkPDFUnion::SkPDFUnion(Type t, SkString v) : fType(t) { fSkString.init(std::move(v)); }
24+
SkPDFUnion::SkPDFUnion(Type t, int32_t v) : fIntValue (v) , fType(t) {}
25+
SkPDFUnion::SkPDFUnion(Type t, bool v) : fBoolValue (v) , fType(t) {}
26+
SkPDFUnion::SkPDFUnion(Type t, SkScalar v) : fScalarValue (v) , fType(t) {}
27+
SkPDFUnion::SkPDFUnion(Type t, const char* v) : fStaticString (v) , fType(t) {}
28+
SkPDFUnion::SkPDFUnion(Type t, SkString v) : fSkString(std::move(v)), fType(t) {}
29+
SkPDFUnion::SkPDFUnion(Type t, PDFObject v) : fObject (std::move(v)), fType(t) {}
2930

3031
SkPDFUnion::~SkPDFUnion() {
3132
switch (fType) {
3233
case Type::kNameSkS:
3334
case Type::kStringSkS:
34-
fSkString.destroy();
35+
fSkString.~SkString();
3536
return;
3637
case Type::kObject:
37-
SkASSERT(fObject);
38-
delete fObject;
38+
fObject.~PDFObject();
3939
return;
4040
default:
4141
return;
4242
}
4343
}
4444

45-
SkPDFUnion& SkPDFUnion::operator=(SkPDFUnion&& other) {
46-
if (this != &other) {
47-
this->~SkPDFUnion();
48-
new (this) SkPDFUnion(std::move(other));
49-
}
50-
return *this;
51-
}
52-
53-
SkPDFUnion::SkPDFUnion(SkPDFUnion&& other) {
54-
SkASSERT(this != &other);
55-
memcpy(this, &other, sizeof(*this));
56-
other.fType = Type::kDestroyed;
57-
}
45+
SkPDFUnion::SkPDFUnion(SkPDFUnion&& that) : fType(that.fType) {
46+
SkASSERT(this != &that);
5847

59-
#if 0
60-
SkPDFUnion SkPDFUnion::copy() const {
61-
SkPDFUnion u(fType);
62-
memcpy(&u, this, sizeof(u));
6348
switch (fType) {
49+
case Type::kDestroyed:
50+
break;
51+
case Type::kInt:
52+
case Type::kColorComponent:
53+
case Type::kRef:
54+
fIntValue = that.fIntValue;
55+
break;
56+
case Type::kBool:
57+
fBoolValue = that.fBoolValue;
58+
break;
59+
case Type::kColorComponentF:
60+
case Type::kScalar:
61+
fScalarValue = that.fScalarValue;
62+
break;
63+
case Type::kName:
64+
case Type::kString:
65+
fStaticString = that.fStaticString;
66+
break;
6467
case Type::kNameSkS:
6568
case Type::kStringSkS:
66-
u.fSkString.init(fSkString.get());
67-
return u;
69+
new (&fSkString) SkString(std::move(that.fSkString));
70+
break;
6871
case Type::kObject:
69-
SkRef(u.fObject);
70-
return u;
72+
new (&fObject) PDFObject(std::move(that.fObject));
73+
break;
7174
default:
72-
return u;
75+
SkDEBUGFAIL("SkPDFUnion::SkPDFUnion with bad type");
7376
}
77+
that.fType = Type::kDestroyed;
7478
}
75-
SkPDFUnion& SkPDFUnion::operator=(const SkPDFUnion& other) {
76-
return *this = other.copy();
77-
}
78-
SkPDFUnion::SkPDFUnion(const SkPDFUnion& other) {
79-
*this = other.copy();
79+
80+
SkPDFUnion& SkPDFUnion::operator=(SkPDFUnion&& that) {
81+
if (this != &that) {
82+
this->~SkPDFUnion();
83+
new (this) SkPDFUnion(std::move(that));
84+
}
85+
return *this;
8086
}
81-
#endif
8287

8388
bool SkPDFUnion::isName() const {
8489
return Type::kName == fType || Type::kNameSkS == fType;
8590
}
8691

8792
#ifdef SK_DEBUG
88-
// Most names need no escaping. Such names are handled as static
89-
// const strings.
93+
// Most names need no escaping. Such names are handled as static const strings.
9094
bool is_valid_name(const char* n) {
9195
static const char kControlChars[] = "/%()<>[]{}";
9296
while (*n) {
@@ -99,8 +103,7 @@ bool is_valid_name(const char* n) {
99103
}
100104
#endif // SK_DEBUG
101105

102-
// Given an arbitrary string, write it as a valid name (not including
103-
// leading slash).
106+
// Given an arbitrary string, write it as a valid name (not including leading slash).
104107
static void write_name_escaped(SkWStream* o, const char* name) {
105108
static const char kToEscape[] = "#/%()<>[]{}";
106109
for (const uint8_t* n = reinterpret_cast<const uint8_t*>(name); *n; ++n) {
@@ -190,10 +193,10 @@ void SkPDFUnion::emitObject(SkWStream* stream) const {
190193
return;
191194
case Type::kNameSkS:
192195
stream->writeText("/");
193-
write_name_escaped(stream, fSkString.get().c_str());
196+
write_name_escaped(stream, fSkString.c_str());
194197
return;
195198
case Type::kStringSkS:
196-
write_string(stream, fSkString.get().c_str(), fSkString.get().size());
199+
write_string(stream, fSkString.c_str(), fSkString.size());
197200
return;
198201
case Type::kObject:
199202
fObject->emitObject(stream);
@@ -208,14 +211,16 @@ void SkPDFUnion::emitObject(SkWStream* stream) const {
208211
}
209212
}
210213

211-
SkPDFUnion SkPDFUnion::Int(int32_t value) { return SkPDFUnion(Type::kInt, value); }
214+
SkPDFUnion SkPDFUnion::Int(int32_t value) {
215+
return SkPDFUnion(Type::kInt, value);
216+
}
212217

213218
SkPDFUnion SkPDFUnion::ColorComponent(uint8_t value) {
214-
return SkPDFUnion(Type::kColorComponent, (int32_t)value);
219+
return SkPDFUnion(Type::kColorComponent, SkTo<int32_t>(value));
215220
}
216221

217222
SkPDFUnion SkPDFUnion::ColorComponentF(float value) {
218-
return SkPDFUnion(Type::kColorComponentF, (SkScalar)value);
223+
return SkPDFUnion(Type::kColorComponentF, SkFloatToScalar(value));
219224
}
220225

221226
SkPDFUnion SkPDFUnion::Bool(bool value) {
@@ -227,33 +232,32 @@ SkPDFUnion SkPDFUnion::Scalar(SkScalar value) {
227232
}
228233

229234
SkPDFUnion SkPDFUnion::Name(const char* value) {
230-
SkPDFUnion u(Type::kName);
231235
SkASSERT(value);
232236
SkASSERT(is_valid_name(value));
233-
u.fStaticString = value;
234-
return u;
237+
return SkPDFUnion(Type::kName, value);
235238
}
236239

237240
SkPDFUnion SkPDFUnion::String(const char* value) {
238-
SkPDFUnion u(Type::kString);
239241
SkASSERT(value);
240-
u.fStaticString = value;
241-
return u;
242+
return SkPDFUnion(Type::kString, value);
242243
}
243244

244-
SkPDFUnion SkPDFUnion::Name(SkString s) { return SkPDFUnion(Type::kNameSkS, std::move(s)); }
245+
SkPDFUnion SkPDFUnion::Name(SkString s) {
246+
return SkPDFUnion(Type::kNameSkS, std::move(s));
247+
}
245248

246-
SkPDFUnion SkPDFUnion::String(SkString s) { return SkPDFUnion(Type::kStringSkS, std::move(s)); }
249+
SkPDFUnion SkPDFUnion::String(SkString s) {
250+
return SkPDFUnion(Type::kStringSkS, std::move(s));
251+
}
247252

248253
SkPDFUnion SkPDFUnion::Object(std::unique_ptr<SkPDFObject> objSp) {
249-
SkPDFUnion u(Type::kObject);
250254
SkASSERT(objSp.get());
251-
u.fObject = objSp.release(); // take ownership into union{}
252-
return u;
255+
return SkPDFUnion(Type::kObject, std::move(objSp));
253256
}
254257

255258
SkPDFUnion SkPDFUnion::Ref(SkPDFIndirectReference ref) {
256-
return SkASSERT(ref.fValue > 0), SkPDFUnion(Type::kRef, (int32_t)ref.fValue);
259+
SkASSERT(ref.fValue > 0);
260+
return SkPDFUnion(Type::kRef, SkTo<int32_t>(ref.fValue));
257261
}
258262

259263
////////////////////////////////////////////////////////////////////////////////

src/pdf/SkPDFUnion.h

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,6 @@
55

66
#include "src/pdf/SkPDFTypes.h"
77

8-
template <class T>
9-
class SkStorageFor {
10-
public:
11-
const T& get() const { return *reinterpret_cast<const T*>(&fStore); }
12-
T& get() { return *reinterpret_cast<T*>(&fStore); }
13-
// Up to caller to keep track of status.
14-
template<class... Args> void init(Args&&... args) {
15-
new (&this->get()) T(std::forward<Args>(args)...);
16-
}
17-
void destroy() { this->get().~T(); }
18-
private:
19-
typename std::aligned_storage<sizeof(T), alignof(T)>::type fStore;
20-
};
21-
228
// Exposed for unit testing.
239
void SkPDFWriteString(SkWStream* wStream, const char* cin, size_t len);
2410

@@ -31,10 +17,10 @@ void SkPDFWriteString(SkWStream* wStream, const char* cin, size_t len);
3117
*/
3218
class SkPDFUnion {
3319
public:
34-
// Move contstructor and assignment operator destroy the argument
20+
// Move constructor and assignment operator destroy the argument
3521
// and steal their references (if needed).
36-
SkPDFUnion(SkPDFUnion&& other);
37-
SkPDFUnion& operator=(SkPDFUnion&& other);
22+
SkPDFUnion(SkPDFUnion&&);
23+
SkPDFUnion& operator=(SkPDFUnion&&);
3824

3925
~SkPDFUnion();
4026

@@ -87,17 +73,17 @@ class SkPDFUnion {
8773
bool isName() const;
8874

8975
private:
76+
using PDFObject = std::unique_ptr<SkPDFObject>;
9077
union {
9178
int32_t fIntValue;
9279
bool fBoolValue;
9380
SkScalar fScalarValue;
9481
const char* fStaticString;
95-
SkStorageFor<SkString> fSkString;
96-
SkPDFObject* fObject;
82+
SkString fSkString;
83+
PDFObject fObject;
9784
};
9885
enum class Type : char {
99-
/** It is an error to call emitObject() or addResources() on an
100-
kDestroyed object. */
86+
/** It is an error to call emitObject() or addResources() on an kDestroyed object. */
10187
kDestroyed = 0,
10288
kInt,
10389
kColorComponent,
@@ -113,13 +99,13 @@ class SkPDFUnion {
11399
};
114100
Type fType;
115101

116-
SkPDFUnion(Type);
117102
SkPDFUnion(Type, int32_t);
118103
SkPDFUnion(Type, bool);
119104
SkPDFUnion(Type, SkScalar);
105+
SkPDFUnion(Type, const char*);
120106
SkPDFUnion(Type, SkString);
121-
// We do not now need copy constructor and copy assignment, so we
122-
// will disable this functionality.
107+
SkPDFUnion(Type, PDFObject);
108+
123109
SkPDFUnion& operator=(const SkPDFUnion&) = delete;
124110
SkPDFUnion(const SkPDFUnion&) = delete;
125111
};

0 commit comments

Comments
 (0)