Move package info string builder to its own header
This commit is contained in:
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include <package/PackageInfo.h>
|
#include <package/PackageInfo.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -23,6 +22,7 @@
|
|||||||
#include <package/PackageInfoContentHandler.h>
|
#include <package/PackageInfoContentHandler.h>
|
||||||
|
|
||||||
#include "PackageInfoParser.h"
|
#include "PackageInfoParser.h"
|
||||||
|
#include "PackageInfoStringBuilder.h"
|
||||||
|
|
||||||
|
|
||||||
namespace BPackageKit {
|
namespace BPackageKit {
|
||||||
@@ -72,277 +72,6 @@ const char* const BPackageInfo::kSettingsFileUpdateTypes[
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - StringBuilder
|
|
||||||
|
|
||||||
|
|
||||||
struct BPackageInfo::StringBuilder {
|
|
||||||
StringBuilder()
|
|
||||||
:
|
|
||||||
fData(),
|
|
||||||
fError(B_OK),
|
|
||||||
fBasePackage()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t Error() const
|
|
||||||
{
|
|
||||||
return fError;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t GetString(BString& _string) const
|
|
||||||
{
|
|
||||||
if (fError != B_OK) {
|
|
||||||
_string = BString();
|
|
||||||
return fError;
|
|
||||||
}
|
|
||||||
|
|
||||||
_string.SetTo((const char*)fData.Buffer(), fData.BufferLength());
|
|
||||||
return (size_t)_string.Length() == fData.BufferLength()
|
|
||||||
? B_OK : B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Value>
|
|
||||||
StringBuilder& Write(const char* attribute, Value value)
|
|
||||||
{
|
|
||||||
if (_IsValueEmpty(value))
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
_Write(attribute);
|
|
||||||
_Write('\t');
|
|
||||||
_WriteValue(value);
|
|
||||||
_Write('\n');
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder& WriteFlags(const char* attribute, uint32 flags)
|
|
||||||
{
|
|
||||||
if ((flags & B_PACKAGE_FLAG_APPROVE_LICENSE) == 0
|
|
||||||
&& (flags & B_PACKAGE_FLAG_SYSTEM_PACKAGE) == 0) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
_Write(attribute);
|
|
||||||
_Write('\t');
|
|
||||||
|
|
||||||
if ((flags & B_PACKAGE_FLAG_APPROVE_LICENSE) == 0)
|
|
||||||
_Write(" approve_license");
|
|
||||||
if ((flags & B_PACKAGE_FLAG_SYSTEM_PACKAGE) == 0)
|
|
||||||
_Write(" system_package");
|
|
||||||
|
|
||||||
_Write('\n');
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder& BeginRequires(const BString& basePackage)
|
|
||||||
{
|
|
||||||
fBasePackage = basePackage;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder& EndRequires()
|
|
||||||
{
|
|
||||||
fBasePackage.Truncate(0);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void _WriteValue(const char* value)
|
|
||||||
{
|
|
||||||
_WriteMaybeQuoted(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _WriteValue(const BPackageVersion& value)
|
|
||||||
{
|
|
||||||
if (fError != B_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (value.InitCheck() != B_OK) {
|
|
||||||
fError = B_BAD_VALUE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_Write(value.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void _WriteValue(const BStringList& value)
|
|
||||||
{
|
|
||||||
int32 count = value.CountStrings();
|
|
||||||
if (count == 1) {
|
|
||||||
_WriteMaybeQuoted(value.StringAt(0));
|
|
||||||
} else {
|
|
||||||
_Write("{\n", 2);
|
|
||||||
|
|
||||||
int32 count = value.CountStrings();
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
|
||||||
_Write('\t');
|
|
||||||
_WriteMaybeQuoted(value.StringAt(i));
|
|
||||||
_Write('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
_Write('}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Value>
|
|
||||||
void _WriteValue(const BObjectList<Value>& value)
|
|
||||||
{
|
|
||||||
// Note: The fBasePackage solution is disgusting, but any attempt of
|
|
||||||
// encapsulating the stringification via templates seems to result in
|
|
||||||
// an Internal Compiler Error with gcc 2.
|
|
||||||
|
|
||||||
int32 count = value.CountItems();
|
|
||||||
if (count == 1) {
|
|
||||||
_WriteListElement(value.ItemAt(0));
|
|
||||||
} else {
|
|
||||||
_Write("{\n", 2);
|
|
||||||
|
|
||||||
int32 count = value.CountItems();
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
|
||||||
_Write('\t');
|
|
||||||
_WriteListElement(value.ItemAt(i));
|
|
||||||
_Write('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
_Write('}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Value>
|
|
||||||
void _WriteListElement(const Value* value)
|
|
||||||
{
|
|
||||||
_Write(value->ToString());
|
|
||||||
if (!fBasePackage.IsEmpty()
|
|
||||||
&& value->Name() == fBasePackage) {
|
|
||||||
_Write(" base");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _WriteListElement(const BGlobalSettingsFileInfo* value)
|
|
||||||
{
|
|
||||||
_WriteMaybeQuoted(value->Path());
|
|
||||||
if (value->IsIncluded()) {
|
|
||||||
_Write(' ');
|
|
||||||
_Write(kSettingsFileUpdateTypes[value->UpdateType()]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _WriteListElement(const BUserSettingsFileInfo* value)
|
|
||||||
{
|
|
||||||
_WriteMaybeQuoted(value->Path());
|
|
||||||
if (!value->TemplatePath().IsEmpty()) {
|
|
||||||
_Write(" template ");
|
|
||||||
_WriteMaybeQuoted(value->TemplatePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool _IsValueEmpty(const char* value)
|
|
||||||
{
|
|
||||||
return value[0] == '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool _IsValueEmpty(const BPackageVersion& value)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename List>
|
|
||||||
static inline bool _IsValueEmpty(const List& value)
|
|
||||||
{
|
|
||||||
return value.IsEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _WriteMaybeQuoted(const char* data)
|
|
||||||
{
|
|
||||||
// check whether quoting is needed
|
|
||||||
bool needsQuoting = false;
|
|
||||||
bool needsEscaping = false;
|
|
||||||
for (const char* it = data; *it != '\0'; it++) {
|
|
||||||
if (isalnum(*it) || *it == '.' || *it == '-' || *it == '_'
|
|
||||||
|| *it == ':' || *it == '+') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
needsQuoting = true;
|
|
||||||
|
|
||||||
if (*it == '\t' || *it == '\n' || *it == '"' || *it == '\\') {
|
|
||||||
needsEscaping = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!needsQuoting) {
|
|
||||||
_Write(data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need quoting
|
|
||||||
_Write('"');
|
|
||||||
|
|
||||||
// escape the string, if necessary
|
|
||||||
if (needsEscaping) {
|
|
||||||
const char* start = data;
|
|
||||||
const char* end = data;
|
|
||||||
while (*end != '\0') {
|
|
||||||
char replacement[2];
|
|
||||||
switch (*end) {
|
|
||||||
case '\t':
|
|
||||||
replacement[1] = 't';
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
replacement[1] = 'n';
|
|
||||||
break;
|
|
||||||
case '"':
|
|
||||||
case '\\':
|
|
||||||
replacement[1] = *end;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
end++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start < end)
|
|
||||||
_Write(start, end - start);
|
|
||||||
|
|
||||||
replacement[0] = '\\';
|
|
||||||
_Write(replacement, 2);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
_Write(data);
|
|
||||||
|
|
||||||
_Write('"');
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void _Write(char data)
|
|
||||||
{
|
|
||||||
_Write(&data, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void _Write(const char* data)
|
|
||||||
{
|
|
||||||
_Write(data, strlen(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void _Write(const BString& data)
|
|
||||||
{
|
|
||||||
_Write(data, data.Length());
|
|
||||||
}
|
|
||||||
|
|
||||||
void _Write(const void* data, size_t size)
|
|
||||||
{
|
|
||||||
if (fError == B_OK) {
|
|
||||||
ssize_t bytesWritten = fData.Write(data, size);
|
|
||||||
if (bytesWritten < 0)
|
|
||||||
fError = bytesWritten;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BMallocIO fData;
|
|
||||||
status_t fError;
|
|
||||||
BString fBasePackage;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - FieldName
|
// #pragma mark - FieldName
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,289 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef PACKAGE_INFO_STRING_BUILDER_H
|
||||||
|
#define PACKAGE_INFO_STRING_BUILDER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <DataIO.h>
|
||||||
|
#include <package/PackageInfo.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPackageKit {
|
||||||
|
|
||||||
|
|
||||||
|
struct BPackageInfo::StringBuilder {
|
||||||
|
StringBuilder()
|
||||||
|
:
|
||||||
|
fData(),
|
||||||
|
fError(B_OK),
|
||||||
|
fBasePackage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t Error() const
|
||||||
|
{
|
||||||
|
return fError;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t GetString(BString& _string) const
|
||||||
|
{
|
||||||
|
if (fError != B_OK) {
|
||||||
|
_string = BString();
|
||||||
|
return fError;
|
||||||
|
}
|
||||||
|
|
||||||
|
_string.SetTo((const char*)fData.Buffer(), fData.BufferLength());
|
||||||
|
return (size_t)_string.Length() == fData.BufferLength()
|
||||||
|
? B_OK : B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Value>
|
||||||
|
StringBuilder& Write(const char* attribute, Value value)
|
||||||
|
{
|
||||||
|
if (_IsValueEmpty(value))
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
_Write(attribute);
|
||||||
|
_Write('\t');
|
||||||
|
_WriteValue(value);
|
||||||
|
_Write('\n');
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder& WriteFlags(const char* attribute, uint32 flags)
|
||||||
|
{
|
||||||
|
if ((flags & B_PACKAGE_FLAG_APPROVE_LICENSE) == 0
|
||||||
|
&& (flags & B_PACKAGE_FLAG_SYSTEM_PACKAGE) == 0) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Write(attribute);
|
||||||
|
_Write('\t');
|
||||||
|
|
||||||
|
if ((flags & B_PACKAGE_FLAG_APPROVE_LICENSE) == 0)
|
||||||
|
_Write(" approve_license");
|
||||||
|
if ((flags & B_PACKAGE_FLAG_SYSTEM_PACKAGE) == 0)
|
||||||
|
_Write(" system_package");
|
||||||
|
|
||||||
|
_Write('\n');
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder& BeginRequires(const BString& basePackage)
|
||||||
|
{
|
||||||
|
fBasePackage = basePackage;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder& EndRequires()
|
||||||
|
{
|
||||||
|
fBasePackage.Truncate(0);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _WriteValue(const char* value)
|
||||||
|
{
|
||||||
|
_WriteMaybeQuoted(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _WriteValue(const BPackageVersion& value)
|
||||||
|
{
|
||||||
|
if (fError != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (value.InitCheck() != B_OK) {
|
||||||
|
fError = B_BAD_VALUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Write(value.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void _WriteValue(const BStringList& value)
|
||||||
|
{
|
||||||
|
int32 count = value.CountStrings();
|
||||||
|
if (count == 1) {
|
||||||
|
_WriteMaybeQuoted(value.StringAt(0));
|
||||||
|
} else {
|
||||||
|
_Write("{\n", 2);
|
||||||
|
|
||||||
|
int32 count = value.CountStrings();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
_Write('\t');
|
||||||
|
_WriteMaybeQuoted(value.StringAt(i));
|
||||||
|
_Write('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
_Write('}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Value>
|
||||||
|
void _WriteValue(const BObjectList<Value>& value)
|
||||||
|
{
|
||||||
|
// Note: The fBasePackage solution is disgusting, but any attempt of
|
||||||
|
// encapsulating the stringification via templates seems to result in
|
||||||
|
// an Internal Compiler Error with gcc 2.
|
||||||
|
|
||||||
|
int32 count = value.CountItems();
|
||||||
|
if (count == 1) {
|
||||||
|
_WriteListElement(value.ItemAt(0));
|
||||||
|
} else {
|
||||||
|
_Write("{\n", 2);
|
||||||
|
|
||||||
|
int32 count = value.CountItems();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
_Write('\t');
|
||||||
|
_WriteListElement(value.ItemAt(i));
|
||||||
|
_Write('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
_Write('}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Value>
|
||||||
|
void _WriteListElement(const Value* value)
|
||||||
|
{
|
||||||
|
_Write(value->ToString());
|
||||||
|
if (!fBasePackage.IsEmpty()
|
||||||
|
&& value->Name() == fBasePackage) {
|
||||||
|
_Write(" base");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _WriteListElement(const BGlobalSettingsFileInfo* value)
|
||||||
|
{
|
||||||
|
_WriteMaybeQuoted(value->Path());
|
||||||
|
if (value->IsIncluded()) {
|
||||||
|
_Write(' ');
|
||||||
|
_Write(kSettingsFileUpdateTypes[value->UpdateType()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _WriteListElement(const BUserSettingsFileInfo* value)
|
||||||
|
{
|
||||||
|
_WriteMaybeQuoted(value->Path());
|
||||||
|
if (!value->TemplatePath().IsEmpty()) {
|
||||||
|
_Write(" template ");
|
||||||
|
_WriteMaybeQuoted(value->TemplatePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool _IsValueEmpty(const char* value)
|
||||||
|
{
|
||||||
|
return value[0] == '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool _IsValueEmpty(const BPackageVersion& value)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename List>
|
||||||
|
static inline bool _IsValueEmpty(const List& value)
|
||||||
|
{
|
||||||
|
return value.IsEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _WriteMaybeQuoted(const char* data)
|
||||||
|
{
|
||||||
|
// check whether quoting is needed
|
||||||
|
bool needsQuoting = false;
|
||||||
|
bool needsEscaping = false;
|
||||||
|
for (const char* it = data; *it != '\0'; it++) {
|
||||||
|
if (isalnum(*it) || *it == '.' || *it == '-' || *it == '_'
|
||||||
|
|| *it == ':' || *it == '+') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
needsQuoting = true;
|
||||||
|
|
||||||
|
if (*it == '\t' || *it == '\n' || *it == '"' || *it == '\\') {
|
||||||
|
needsEscaping = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!needsQuoting) {
|
||||||
|
_Write(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we need quoting
|
||||||
|
_Write('"');
|
||||||
|
|
||||||
|
// escape the string, if necessary
|
||||||
|
if (needsEscaping) {
|
||||||
|
const char* start = data;
|
||||||
|
const char* end = data;
|
||||||
|
while (*end != '\0') {
|
||||||
|
char replacement[2];
|
||||||
|
switch (*end) {
|
||||||
|
case '\t':
|
||||||
|
replacement[1] = 't';
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
replacement[1] = 'n';
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
case '\\':
|
||||||
|
replacement[1] = *end;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
end++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start < end)
|
||||||
|
_Write(start, end - start);
|
||||||
|
|
||||||
|
replacement[0] = '\\';
|
||||||
|
_Write(replacement, 2);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
_Write(data);
|
||||||
|
|
||||||
|
_Write('"');
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void _Write(char data)
|
||||||
|
{
|
||||||
|
_Write(&data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void _Write(const char* data)
|
||||||
|
{
|
||||||
|
_Write(data, strlen(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void _Write(const BString& data)
|
||||||
|
{
|
||||||
|
_Write(data, data.Length());
|
||||||
|
}
|
||||||
|
|
||||||
|
void _Write(const void* data, size_t size)
|
||||||
|
{
|
||||||
|
if (fError == B_OK) {
|
||||||
|
ssize_t bytesWritten = fData.Write(data, size);
|
||||||
|
if (bytesWritten < 0)
|
||||||
|
fError = bytesWritten;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BMallocIO fData;
|
||||||
|
status_t fError;
|
||||||
|
BString fBasePackage;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace BPackageKit
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PACKAGE_INFO_STRING_BUILDER_H
|
||||||
Reference in New Issue
Block a user