Fixes regarding to comments in ag/2839267
1. use struct {} to instantiate privacy fields for efficiency reason
2. use vector<uint8_t>* instead of vector<uint8_t>& to indicate the
caller knows the value gets changed.
3. binary search privay policy for sections
Bug: 65595927
Test: unit test covers
Change-Id: Ic58c2f607465d1a7f10352b9a38c3d8b1a5cf352
diff --git a/Android.bp b/Android.bp
index 33acffa..72ea24c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -42,6 +42,7 @@
"core/proto/android/os/kernelwake.proto",
"core/proto/android/os/procrank.proto",
"core/proto/android/service/graphicsstats.proto",
+ "libs/incident/proto/android/privacy.proto",
],
shared: {
enabled: false,
diff --git a/cmds/incidentd/src/EncodedBuffer.cpp b/cmds/incidentd/src/EncodedBuffer.cpp
index 3d20548..e8f2c11 100644
--- a/cmds/incidentd/src/EncodedBuffer.cpp
+++ b/cmds/incidentd/src/EncodedBuffer.cpp
@@ -27,15 +27,15 @@
* Return the number of bytes of the varint.
*/
static uint32_t
-read_raw_varint(FdBuffer::iterator& it)
+read_raw_varint(FdBuffer::iterator* it)
{
uint32_t val = 0;
int i = 0;
bool hasNext = true;
while (hasNext) {
- hasNext = ((*it & 0x80) != 0);
- val += (*it & 0x7F) << (7*i);
- it++;
+ hasNext = ((**it & 0x80) != 0);
+ val += (**it & 0x7F) << (7*i);
+ (*it)++;
i++;
}
return val;
@@ -46,21 +46,21 @@
* If skip is set to true, no data will be written to buf. Return number of bytes written.
*/
static size_t
-write_field_or_skip(FdBuffer::iterator &iterator, vector<uint8_t> &buf, uint8_t wireType, bool skip)
+write_field_or_skip(FdBuffer::iterator* iter, vector<uint8_t>* buf, uint8_t wireType, bool skip)
{
- FdBuffer::iterator snapshot = iterator.snapshot();
+ FdBuffer::iterator snapshot = iter->snapshot();
size_t bytesToWrite = 0;
uint32_t varint = 0;
switch (wireType) {
case WIRE_TYPE_VARINT:
- varint = read_raw_varint(iterator);
+ varint = read_raw_varint(iter);
if(!skip) return write_raw_varint(buf, varint);
break;
case WIRE_TYPE_FIXED64:
bytesToWrite = 8;
break;
case WIRE_TYPE_LENGTH_DELIMITED:
- bytesToWrite = read_raw_varint(iterator);
+ bytesToWrite = read_raw_varint(iter);
if(!skip) write_raw_varint(buf, bytesToWrite);
break;
case WIRE_TYPE_FIXED32:
@@ -68,14 +68,14 @@
break;
}
if (skip) {
- iterator += bytesToWrite;
+ *iter += bytesToWrite;
} else {
for (size_t i=0; i<bytesToWrite; i++) {
- buf.push_back(*iterator);
- iterator++;
+ buf->push_back(**iter);
+ (*iter)++;
}
}
- return skip ? 0 : iterator - snapshot;
+ return skip ? 0 : *iter - snapshot;
}
/**
@@ -86,30 +86,30 @@
* After exit with NO_ERROR, iterator points to the next protobuf field's head.
*/
static status_t
-stripField(FdBuffer::iterator &iterator, vector<uint8_t> &buf, const Privacy* parentPolicy, const PrivacySpec& spec)
+stripField(FdBuffer::iterator* iter, vector<uint8_t>* buf, const Privacy* parentPolicy, const PrivacySpec& spec)
{
- if (iterator.outOfBound() || parentPolicy == NULL) return BAD_VALUE;
+ if (iter->outOfBound() || parentPolicy == NULL) return BAD_VALUE;
- uint32_t varint = read_raw_varint(iterator);
+ uint32_t varint = read_raw_varint(iter);
uint8_t wireType = read_wire_type(varint);
uint32_t fieldId = read_field_id(varint);
const Privacy* policy = parentPolicy->lookup(fieldId);
if (policy == NULL || !policy->IsMessageType() || !policy->HasChildren()) {
bool skip = !spec.CheckPremission(policy);
- size_t amt = buf.size();
+ size_t amt = buf->size();
if (!skip) amt += write_header(buf, fieldId, wireType);
- amt += write_field_or_skip(iterator, buf, wireType, skip); // point to head of next field
- return buf.size() != amt ? BAD_VALUE : NO_ERROR;
+ amt += write_field_or_skip(iter, buf, wireType, skip); // point to head of next field
+ return buf->size() != amt ? BAD_VALUE : NO_ERROR;
}
// current field is message type and its sub-fields have extra privacy policies
deque<vector<uint8_t>> q;
- uint32_t msgSize = read_raw_varint(iterator);
+ uint32_t msgSize = read_raw_varint(iter);
size_t finalSize = 0;
- FdBuffer::iterator start = iterator.snapshot();
- while ((iterator - start) != (int)msgSize) {
+ FdBuffer::iterator start = iter->snapshot();
+ while ((*iter - start) != (int)msgSize) {
vector<uint8_t> v;
- status_t err = stripField(iterator, v, policy, spec);
+ status_t err = stripField(iter, &v, policy, spec);
if (err != NO_ERROR) return err;
if (v.empty()) continue;
q.push_back(v);
@@ -118,11 +118,11 @@
write_header(buf, fieldId, wireType);
write_raw_varint(buf, finalSize);
- buf.reserve(finalSize);
+ buf->reserve(finalSize); // reserve the size of the field
while (!q.empty()) {
vector<uint8_t> subField = q.front();
for (vector<uint8_t>::iterator it = subField.begin(); it != subField.end(); it++) {
- buf.push_back(*it);
+ buf->push_back(*it);
}
q.pop_front();
}
@@ -156,7 +156,7 @@
field.reserve(BUFFER_SIZE);
while (it != mFdBuffer.end()) {
- status_t err = stripField(it, field, mPolicy, spec);
+ status_t err = stripField(&it, &field, mPolicy, spec);
if (err != NO_ERROR) return err;
if (field.size() > BUFFER_SIZE) { // rotate to another chunk if buffer size exceeds
mBuffers.push_back(field);
diff --git a/cmds/incidentd/src/Privacy.cpp b/cmds/incidentd/src/Privacy.cpp
index dbab548..e7969e7 100644
--- a/cmds/incidentd/src/Privacy.cpp
+++ b/cmds/incidentd/src/Privacy.cpp
@@ -16,6 +16,8 @@
#include "Privacy.h"
+#include <stdlib.h>
+
// DESTINATION enum value
const uint8_t DEST_LOCAL = 0;
const uint8_t DEST_EXPLICIT = 1;
@@ -25,33 +27,6 @@
const uint8_t TYPE_STRING = 9;
const uint8_t TYPE_MESSAGE = 11;
-Privacy::Privacy(uint32_t field_id, uint8_t type, uint8_t dest)
- : field_id(field_id),
- type(type),
- children(NULL),
- dest(dest),
- patterns(NULL)
-{
-}
-
-Privacy::Privacy(uint32_t field_id, const Privacy** children)
- : field_id(field_id),
- type(TYPE_MESSAGE),
- children(children),
- dest(DEST_DEFAULT_VALUE), // this will be ignored
- patterns(NULL)
-{
-}
-
-Privacy::Privacy(uint32_t field_id, uint8_t dest, const char** patterns)
- : field_id(field_id),
- type(TYPE_STRING),
- children(NULL),
- dest(dest),
- patterns(patterns)
-{
-}
-
bool
Privacy::IsMessageType() const { return type == TYPE_MESSAGE; }
diff --git a/cmds/incidentd/src/Privacy.h b/cmds/incidentd/src/Privacy.h
index c56ba9b8..7f1977e 100644
--- a/cmds/incidentd/src/Privacy.h
+++ b/cmds/incidentd/src/Privacy.h
@@ -30,17 +30,13 @@
uint32_t field_id;
uint8_t type;
// ignore parent's privacy flags if children are set, NULL-terminated
- const Privacy** children;
+ Privacy** children;
// the following fields are identitical to
// frameworks/base/libs/incident/proto/android/privacy.proto
uint8_t dest;
const char** patterns; // only set when type is string
- Privacy(uint32_t field_id, uint8_t type, uint8_t dest); // generic constructor
- Privacy(uint32_t field_id, const Privacy** children); // used for message type
- Privacy(uint32_t field_id, uint8_t dest, const char** patterns); // used for string type
-
bool IsMessageType() const;
bool IsStringType() const;
bool HasChildren() const;
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 6f052de..166fef0 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -97,13 +97,19 @@
static const Privacy*
get_privacy_of_section(int id)
{
- if (id < 0) return NULL;
- int i=0;
- while (PRIVACY_POLICY_LIST[i] != NULL) {
- const Privacy* p = PRIVACY_POLICY_LIST[i];
- if (p->field_id == (uint32_t)id) return p;
- if (p->field_id > (uint32_t)id) return NULL;
- i++;
+ int l = 0;
+ int r = PRIVACY_POLICY_COUNT - 1;
+ while (l <= r) {
+ int mid = (l + r) >> 1;
+ const Privacy* p = PRIVACY_POLICY_LIST[mid];
+
+ if (p->field_id < (uint32_t)id) {
+ l = mid + 1;
+ } else if (p->field_id > (uint32_t)id) {
+ r = mid - 1;
+ } else {
+ return p;
+ }
}
return NULL;
}
diff --git a/cmds/incidentd/src/protobuf.cpp b/cmds/incidentd/src/protobuf.cpp
index 05de831..4fffec1 100644
--- a/cmds/incidentd/src/protobuf.cpp
+++ b/cmds/incidentd/src/protobuf.cpp
@@ -50,23 +50,23 @@
}
size_t
-write_raw_varint(vector<uint8_t> &buf, uint32_t val)
+write_raw_varint(vector<uint8_t>* buf, uint32_t val)
{
size_t size = 0;
while (true) {
size++;
if ((val & ~0x7F) == 0) {
- buf.push_back((uint8_t) val);
+ buf->push_back((uint8_t) val);
return size;
} else {
- buf.push_back((uint8_t)((val & 0x7F) | 0x80));
+ buf->push_back((uint8_t)((val & 0x7F) | 0x80));
val >>= 7;
}
}
}
size_t
-write_header(vector<uint8_t> &buf, uint32_t fieldId, uint8_t wireType)
+write_header(vector<uint8_t>* buf, uint32_t fieldId, uint8_t wireType)
{
return write_raw_varint(buf, (fieldId << 3) | wireType);
}
\ No newline at end of file
diff --git a/cmds/incidentd/src/protobuf.h b/cmds/incidentd/src/protobuf.h
index fb0d69d..263c864 100644
--- a/cmds/incidentd/src/protobuf.h
+++ b/cmds/incidentd/src/protobuf.h
@@ -53,12 +53,12 @@
/**
* Write a varint into a vector. Return the size of the varint.
*/
-size_t write_raw_varint(vector<uint8_t> &buf, uint32_t val);
+size_t write_raw_varint(vector<uint8_t>* buf, uint32_t val);
/**
* Write a protobuf header. Return the size of the header.
*/
-size_t write_header(vector<uint8_t> &buf, uint32_t fieldId, uint8_t wireType);
+size_t write_header(vector<uint8_t>* buf, uint32_t fieldId, uint8_t wireType);
enum {
// IncidentProto.header
diff --git a/cmds/incidentd/src/section_list.h b/cmds/incidentd/src/section_list.h
index 4d9efd7..da82b00 100644
--- a/cmds/incidentd/src/section_list.h
+++ b/cmds/incidentd/src/section_list.h
@@ -22,15 +22,17 @@
/**
* This is the mapping of section IDs to the commands that are run to get those commands.
- * The section IDs are guaranteed in ascending order
+ * The section IDs are guaranteed in ascending order, NULL-terminated.
*/
extern const Section* SECTION_LIST[];
/**
* This is the mapping of section IDs to each section's privacy policy.
- * The section IDs are guaranteed in ascending order
+ * The section IDs are guaranteed in ascending order, not NULL-terminated since size is provided.
*/
extern const Privacy* PRIVACY_POLICY_LIST[];
+extern const int PRIVACY_POLICY_COUNT;
+
#endif // SECTION_LIST_H
diff --git a/cmds/incidentd/tests/EncodedBuffer_test.cpp b/cmds/incidentd/tests/EncodedBuffer_test.cpp
index c51520b..98c39bd 100644
--- a/cmds/incidentd/tests/EncodedBuffer_test.cpp
+++ b/cmds/incidentd/tests/EncodedBuffer_test.cpp
@@ -42,6 +42,38 @@
const string FIX32_FIELD_4 = "\x25\xff\xff\xff\xff"; // -1
const string MESSAGE_FIELD_5 = "\x2a\x10" + VARINT_FIELD_1 + STRING_FIELD_2;
+static Privacy* create_privacy(uint32_t field_id, uint8_t type, uint8_t dest) {
+ struct Privacy* p = (struct Privacy*)malloc(sizeof(struct Privacy));
+ p->field_id = field_id;
+ p->type = type;
+ p->children = NULL;
+ p->dest = dest;
+ p->patterns = NULL;
+ return p;
+}
+
+static Privacy* create_message_privacy(uint32_t field_id, Privacy** children)
+{
+ struct Privacy* p = (struct Privacy*)malloc(sizeof(struct Privacy));
+ p->field_id = field_id;
+ p->type = MESSAGE_TYPE;
+ p->children = children;
+ p->dest = EXPLICIT;
+ p->patterns = NULL;
+ return p;
+}
+
+static Privacy* create_string_privacy(uint32_t field_id, uint8_t dest, const char** patterns)
+{
+ struct Privacy* p = (struct Privacy*)malloc(sizeof(struct Privacy));
+ p->field_id = field_id;
+ p->type = STRING_TYPE;
+ p->children = NULL;
+ p->dest = dest;
+ p->patterns = patterns;
+ return p;
+}
+
class EncodedBufferTest : public Test {
public:
virtual void SetUp() override {
@@ -78,7 +110,7 @@
}
va_end(args);
list[size] = NULL;
- assertStrip(dest, expected, new Privacy(300, const_cast<const Privacy**>(list)));
+ assertStrip(dest, expected, create_message_privacy(300, list));
}
FdBuffer buffer;
@@ -88,62 +120,62 @@
TEST_F(EncodedBufferTest, NullFieldPolicy) {
writeToFdBuffer(STRING_FIELD_0);
- assertStrip(EXPLICIT, STRING_FIELD_0, new Privacy(300, NULL));
+ assertStrip(EXPLICIT, STRING_FIELD_0, create_string_privacy(300, AUTOMATIC, NULL));
}
TEST_F(EncodedBufferTest, StripSpecNotAllowed) {
writeToFdBuffer(STRING_FIELD_0);
- assertStripByFields(AUTOMATIC, "", 1, new Privacy(0, STRING_TYPE, EXPLICIT));
+ assertStripByFields(AUTOMATIC, "", 1, create_privacy(0, STRING_TYPE, EXPLICIT));
}
TEST_F(EncodedBufferTest, StripVarintField) {
writeToFdBuffer(VARINT_FIELD_1);
- assertStripByFields(EXPLICIT, "", 1, new Privacy(1, OTHER_TYPE, LOCAL));
+ assertStripByFields(EXPLICIT, "", 1, create_privacy(1, OTHER_TYPE, LOCAL));
}
TEST_F(EncodedBufferTest, StripLengthDelimitedField_String) {
writeToFdBuffer(STRING_FIELD_2);
- assertStripByFields(EXPLICIT, "", 1, new Privacy(2, STRING_TYPE, LOCAL));
+ assertStripByFields(EXPLICIT, "", 1, create_privacy(2, STRING_TYPE, LOCAL));
}
TEST_F(EncodedBufferTest, StripFixed64Field) {
writeToFdBuffer(FIX64_FIELD_3);
- assertStripByFields(EXPLICIT, "", 1, new Privacy(3, OTHER_TYPE, LOCAL));
+ assertStripByFields(EXPLICIT, "", 1, create_privacy(3, OTHER_TYPE, LOCAL));
}
TEST_F(EncodedBufferTest, StripFixed32Field) {
writeToFdBuffer(FIX32_FIELD_4);
- assertStripByFields(EXPLICIT, "", 1, new Privacy(4, OTHER_TYPE, LOCAL));
+ assertStripByFields(EXPLICIT, "", 1, create_privacy(4, OTHER_TYPE, LOCAL));
}
TEST_F(EncodedBufferTest, StripLengthDelimitedField_Message) {
writeToFdBuffer(MESSAGE_FIELD_5);
- assertStripByFields(EXPLICIT, "", 1, new Privacy(5, MESSAGE_TYPE, LOCAL));
+ assertStripByFields(EXPLICIT, "", 1, create_privacy(5, MESSAGE_TYPE, LOCAL));
}
TEST_F(EncodedBufferTest, NoStripVarintField) {
writeToFdBuffer(VARINT_FIELD_1);
- assertStripByFields(EXPLICIT, VARINT_FIELD_1, 1, new Privacy(1, OTHER_TYPE, AUTOMATIC));
+ assertStripByFields(EXPLICIT, VARINT_FIELD_1, 1, create_privacy(1, OTHER_TYPE, AUTOMATIC));
}
TEST_F(EncodedBufferTest, NoStripLengthDelimitedField_String) {
writeToFdBuffer(STRING_FIELD_2);
- assertStripByFields(EXPLICIT, STRING_FIELD_2, 1, new Privacy(2, STRING_TYPE, AUTOMATIC));
+ assertStripByFields(EXPLICIT, STRING_FIELD_2, 1, create_privacy(2, STRING_TYPE, AUTOMATIC));
}
TEST_F(EncodedBufferTest, NoStripFixed64Field) {
writeToFdBuffer(FIX64_FIELD_3);
- assertStripByFields(EXPLICIT, FIX64_FIELD_3, 1, new Privacy(3, OTHER_TYPE, AUTOMATIC));
+ assertStripByFields(EXPLICIT, FIX64_FIELD_3, 1, create_privacy(3, OTHER_TYPE, AUTOMATIC));
}
TEST_F(EncodedBufferTest, NoStripFixed32Field) {
writeToFdBuffer(FIX32_FIELD_4);
- assertStripByFields(EXPLICIT, FIX32_FIELD_4, 1, new Privacy(4, OTHER_TYPE, AUTOMATIC));
+ assertStripByFields(EXPLICIT, FIX32_FIELD_4, 1, create_privacy(4, OTHER_TYPE, AUTOMATIC));
}
TEST_F(EncodedBufferTest, NoStripLengthDelimitedField_Message) {
writeToFdBuffer(MESSAGE_FIELD_5);
- assertStripByFields(EXPLICIT, MESSAGE_FIELD_5, 1, new Privacy(5, MESSAGE_TYPE, AUTOMATIC));
+ assertStripByFields(EXPLICIT, MESSAGE_FIELD_5, 1, create_privacy(5, MESSAGE_TYPE, AUTOMATIC));
}
TEST_F(EncodedBufferTest, StripVarintAndString) {
@@ -151,7 +183,7 @@
+ FIX64_FIELD_3 + FIX32_FIELD_4);
string expected = STRING_FIELD_0 + FIX64_FIELD_3 + FIX32_FIELD_4;
assertStripByFields(EXPLICIT, expected, 2,
- new Privacy(1, OTHER_TYPE, LOCAL), new Privacy(2, STRING_TYPE, LOCAL));
+ create_privacy(1, OTHER_TYPE, LOCAL), create_privacy(2, STRING_TYPE, LOCAL));
}
TEST_F(EncodedBufferTest, StripVarintAndFixed64) {
@@ -159,28 +191,28 @@
+ FIX64_FIELD_3 + FIX32_FIELD_4);
string expected = STRING_FIELD_0 + STRING_FIELD_2 + FIX32_FIELD_4;
assertStripByFields(EXPLICIT, expected, 2,
- new Privacy(1, OTHER_TYPE, LOCAL), new Privacy(3, OTHER_TYPE, LOCAL));
+ create_privacy(1, OTHER_TYPE, LOCAL), create_privacy(3, OTHER_TYPE, LOCAL));
}
TEST_F(EncodedBufferTest, StripVarintInNestedMessage) {
writeToFdBuffer(STRING_FIELD_0 + MESSAGE_FIELD_5);
- const Privacy* list[] = { new Privacy(1, OTHER_TYPE, LOCAL), NULL };
+ Privacy* list[] = { create_privacy(1, OTHER_TYPE, LOCAL), NULL };
string expected = STRING_FIELD_0 + "\x2a\xd" + STRING_FIELD_2;
- assertStripByFields(EXPLICIT, expected, 1, new Privacy(5, list));
+ assertStripByFields(EXPLICIT, expected, 1, create_message_privacy(5, list));
}
TEST_F(EncodedBufferTest, StripFix64AndVarintInNestedMessage) {
writeToFdBuffer(STRING_FIELD_0 + FIX64_FIELD_3 + MESSAGE_FIELD_5);
- const Privacy* list[] = { new Privacy(1, OTHER_TYPE, LOCAL), NULL };
+ Privacy* list[] = { create_privacy(1, OTHER_TYPE, LOCAL), NULL };
string expected = STRING_FIELD_0 + "\x2a\xd" + STRING_FIELD_2;
- assertStripByFields(EXPLICIT, expected, 2, new Privacy(3, OTHER_TYPE, LOCAL), new Privacy(5, list));
+ assertStripByFields(EXPLICIT, expected, 2, create_privacy(3, OTHER_TYPE, LOCAL), create_message_privacy(5, list));
}
TEST_F(EncodedBufferTest, ClearAndStrip) {
string data = STRING_FIELD_0 + VARINT_FIELD_1;
writeToFdBuffer(data);
- const Privacy* list[] = { new Privacy(1, OTHER_TYPE, LOCAL), NULL };
- EncodedBuffer encodedBuf(buffer, new Privacy(300, list));
+ Privacy* list[] = { create_privacy(1, OTHER_TYPE, LOCAL), NULL };
+ EncodedBuffer encodedBuf(buffer, create_message_privacy(300, list));
PrivacySpec spec1(EXPLICIT), spec2(LOCAL);
ASSERT_EQ(encodedBuf.strip(spec1), NO_ERROR);
@@ -191,17 +223,17 @@
TEST_F(EncodedBufferTest, BadDataInFdBuffer) {
writeToFdBuffer("iambaddata");
- const Privacy* list[] = { new Privacy(4, OTHER_TYPE, AUTOMATIC), NULL };
- EncodedBuffer encodedBuf(buffer, new Privacy(300, list));
+ Privacy* list[] = { create_privacy(4, OTHER_TYPE, AUTOMATIC), NULL };
+ EncodedBuffer encodedBuf(buffer, create_message_privacy(300, list));
PrivacySpec spec;
ASSERT_EQ(encodedBuf.strip(spec), BAD_VALUE);
}
TEST_F(EncodedBufferTest, BadDataInNestedMessage) {
writeToFdBuffer(STRING_FIELD_0 + MESSAGE_FIELD_5 + "aoeoe");
- const Privacy* list[] = { new Privacy(1, OTHER_TYPE, LOCAL), NULL };
- const Privacy* field5[] = { new Privacy(5, list), NULL };
- EncodedBuffer encodedBuf(buffer, new Privacy(300, field5));
+ Privacy* list[] = { create_privacy(1, OTHER_TYPE, LOCAL), NULL };
+ Privacy* field5[] = { create_message_privacy(5, list), NULL };
+ EncodedBuffer encodedBuf(buffer, create_message_privacy(300, field5));
PrivacySpec spec;
ASSERT_EQ(encodedBuf.strip(spec), BAD_VALUE);
}
diff --git a/cmds/incidentd/tests/section_list.cpp b/cmds/incidentd/tests/section_list.cpp
index 3722c72..e47b61cf 100644
--- a/cmds/incidentd/tests/section_list.cpp
+++ b/cmds/incidentd/tests/section_list.cpp
@@ -9,13 +9,20 @@
const uint8_t EXPLICIT = 1;
const uint8_t AUTOMATIC = 2;
-const Privacy* list[] = {
- new Privacy(1, 1, LOCAL),
- new Privacy(2, AUTOMATIC, (const char**)NULL),
+Privacy sub_field_1 { 1, 1, NULL, LOCAL, NULL };
+Privacy sub_field_2 { 2, 9, NULL, AUTOMATIC, NULL };
+
+Privacy* list[] = {
+ &sub_field_1,
+ &sub_field_2,
NULL };
+Privacy field_0 { 0, 11, list, EXPLICIT, NULL };
+Privacy field_1 { 1, 9, NULL, AUTOMATIC, NULL };
+
const Privacy* PRIVACY_POLICY_LIST[] = {
- new Privacy(0, list),
- new Privacy(1, 9, AUTOMATIC),
- NULL
-};
\ No newline at end of file
+ &field_0,
+ &field_1
+};
+
+const int PRIVACY_POLICY_COUNT = 2;
\ No newline at end of file
diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index 7966d88..900690c 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -135,7 +135,7 @@
if (generatePrivacyFlags(field->message_type(), field_name, msgNames) &&
isDefaultDest(field)) break;
- printf("Privacy %s(%d, %s_LIST);\n", field_name, field->number(), field_name);
+ printf("Privacy %s { %d, %d, %s_LIST, %d, NULL };\n", field_name, field->number(), field->type(), field_name, p.dest());
hasDefaultFlags[i] = false;
break;
case FieldDescriptor::TYPE_STRING:
@@ -147,12 +147,12 @@
printf(" \"%s\",\n", replaceAll(p.patterns(i), '\\', "\\\\").c_str());
}
printf(" NULL };\n");
- printf("Privacy %s(%d, %d, %s_patterns);\n", field_name, field->number(), p.dest(), field_name);
+ printf("Privacy %s { %d, %d, NULL, %d, %s_patterns };\n", field_name, field->number(), field->type(), p.dest(), field_name);
hasDefaultFlags[i] = false;
break;
default:
if (isDefaultDest(field)) break;
- printf("Privacy %s(%d, %d, %d);\n", field_name, field->number(), (int) field->type(), p.dest());
+ printf("Privacy %s { %d, %d, NULL, %d, NULL };\n", field_name, field->number(), field->type(), p.dest());
hasDefaultFlags[i] = false;
}
// add the field name to message map, true means it has default flags
@@ -166,13 +166,23 @@
if (allDefaults) return true;
emptyline();
- printf("const Privacy* %s_LIST[] = {\n", alias);
+
+ bool needConst = strcmp(alias, "PRIVACY_POLICY") == 0;
+ int policyCount = 0;
+
+ printf("%s Privacy* %s_LIST[] = {\n", needConst ? "const" : "", alias);
for (int i=0; i<descriptor->field_count(); i++) {
const FieldDescriptor* field = descriptor->field(i);
if (hasDefaultFlags[i]) continue;
printf(" &%s,\n", replaceAll(field->full_name(), '.', "__").c_str());
+ policyCount++;
}
- printf(" NULL };\n");
+ if (needConst) {
+ printf("};\n\n");
+ printf("const int PRIVACY_POLICY_COUNT = %d;\n", policyCount);
+ } else {
+ printf(" NULL };\n");
+ }
emptyline();
return false;
}
@@ -214,7 +224,8 @@
map<string, bool> messageNames;
if (generatePrivacyFlags(descriptor, "PRIVACY_POLICY", messageNames)) {
// if no privacy options set at all, define an empty list
- printf("const Privacy* PRIVACY_POLICY_LIST[] = { NULL };\n");
+ printf("const Privacy* PRIVACY_POLICY_LIST[] = {};\n");
+ printf("const int PRIVACY_POLICY_COUNT = 0;\n");
}
return true;