2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
5 #ifndef PACKAGE_INFO_STRING_BUILDER_H
6 #define PACKAGE_INFO_STRING_BUILDER_H
12 #include <package/PackageInfo.h>
15 namespace BPackageKit
{
18 struct BPackageInfo::StringBuilder
{
27 status_t
Error() const
32 status_t
GetString(BString
& _string
) const
39 _string
.SetTo((const char*)fData
.Buffer(), fData
.BufferLength());
40 return (size_t)_string
.Length() == fData
.BufferLength()
44 template<typename Value
>
45 StringBuilder
& Write(const char* attribute
, Value value
)
47 if (_IsValueEmpty(value
))
57 StringBuilder
& WriteFlags(const char* attribute
, uint32 flags
)
59 if ((flags
& B_PACKAGE_FLAG_APPROVE_LICENSE
) == 0
60 && (flags
& B_PACKAGE_FLAG_SYSTEM_PACKAGE
) == 0) {
67 if ((flags
& B_PACKAGE_FLAG_APPROVE_LICENSE
) == 0)
68 _Write(" approve_license");
69 if ((flags
& B_PACKAGE_FLAG_SYSTEM_PACKAGE
) == 0)
70 _Write(" system_package");
76 StringBuilder
& BeginRequires(const BString
& basePackage
)
78 fBasePackage
= basePackage
;
82 StringBuilder
& EndRequires()
84 fBasePackage
.Truncate(0);
89 void _WriteValue(const char* value
)
91 _WriteMaybeQuoted(value
);
94 void _WriteValue(const BPackageVersion
& value
)
99 if (value
.InitCheck() != B_OK
) {
100 fError
= B_BAD_VALUE
;
104 _Write(value
.ToString());
107 void _WriteValue(const BStringList
& value
)
109 int32 count
= value
.CountStrings();
111 _WriteMaybeQuoted(value
.StringAt(0));
115 int32 count
= value
.CountStrings();
116 for (int32 i
= 0; i
< count
; i
++) {
118 _WriteMaybeQuoted(value
.StringAt(i
));
126 template<typename Value
>
127 void _WriteValue(const BObjectList
<Value
>& value
)
129 // Note: The fBasePackage solution is disgusting, but any attempt of
130 // encapsulating the stringification via templates seems to result in
131 // an Internal Compiler Error with gcc 2.
135 int32 count
= value
.CountItems();
136 for (int32 i
= 0; i
< count
; i
++) {
138 _WriteListElement(value
.ItemAt(i
));
145 template<typename Value
>
146 void _WriteListElement(const Value
* value
)
148 _Write(value
->ToString());
149 if (!fBasePackage
.IsEmpty()
150 && value
->Name() == fBasePackage
) {
155 void _WriteListElement(const BGlobalWritableFileInfo
* value
)
157 _WriteMaybeQuoted(value
->Path());
158 if (value
->IsDirectory()) {
162 if (value
->IsIncluded()) {
164 _Write(kWritableFileUpdateTypes
[value
->UpdateType()]);
168 void _WriteListElement(const BUserSettingsFileInfo
* value
)
170 _WriteMaybeQuoted(value
->Path());
171 if (value
->IsDirectory()) {
172 _Write(" directory");
173 } else if (!value
->TemplatePath().IsEmpty()) {
174 _Write(" template ");
175 _WriteMaybeQuoted(value
->TemplatePath());
179 void _WriteListElement(const BUser
* value
)
181 _WriteMaybeQuoted(value
->Name());
183 if (!value
->RealName().IsEmpty()) {
184 _Write(" real-name ");
185 _WriteMaybeQuoted(value
->RealName());
188 if (!value
->Home().IsEmpty()) {
190 _WriteMaybeQuoted(value
->Home());
193 if (!value
->Shell().IsEmpty()) {
195 _WriteMaybeQuoted(value
->Shell());
198 if (!value
->Groups().IsEmpty()) {
200 BString groups
= value
->Groups().Join(" ");
201 if (groups
.IsEmpty()) {
203 fError
= B_NO_MEMORY
;
210 static inline bool _IsValueEmpty(const char* value
)
212 return value
[0] == '\0';
215 static inline bool _IsValueEmpty(const BPackageVersion
& value
)
220 template<typename List
>
221 static inline bool _IsValueEmpty(const List
& value
)
223 return value
.IsEmpty();
226 void _WriteMaybeQuoted(const char* data
)
228 // check whether quoting is needed
229 bool needsQuoting
= false;
230 bool needsEscaping
= false;
231 for (const char* it
= data
; *it
!= '\0'; it
++) {
232 if (isalnum(*it
) || *it
== '.' || *it
== '-' || *it
== '_'
233 || *it
== ':' || *it
== '+') {
239 if (*it
== '\t' || *it
== '\n' || *it
== '"' || *it
== '\\') {
240 needsEscaping
= true;
253 // escape the string, if necessary
255 const char* start
= data
;
256 const char* end
= data
;
257 while (*end
!= '\0') {
261 replacement
[1] = 't';
264 replacement
[1] = 'n';
268 replacement
[1] = *end
;
276 _Write(start
, end
- start
);
278 replacement
[0] = '\\';
279 _Write(replacement
, 2);
284 _Write(start
, end
- start
);
291 inline void _Write(char data
)
296 inline void _Write(const char* data
)
298 _Write(data
, strlen(data
));
301 inline void _Write(const BString
& data
)
303 _Write(data
, data
.Length());
306 void _Write(const void* data
, size_t size
)
308 if (fError
== B_OK
) {
309 ssize_t bytesWritten
= fData
.Write(data
, size
);
310 if (bytesWritten
< 0)
311 fError
= bytesWritten
;
318 BString fBasePackage
;
322 } // namespace BPackageKit
325 #endif // PACKAGE_INFO_STRING_BUILDER_H