42 HeaderItem, |
42 HeaderItem, |
43 AttributeName, |
43 AttributeName, |
44 AttributeType, |
44 AttributeType, |
45 Records, |
45 Records, |
46 Record, |
46 Record, |
47 Attribute, |
47 End, |
48 }; |
48 }; |
49 |
49 |
50 State state = State::Start; |
50 State state = State::Start; |
51 |
51 |
52 void assertTag(const Header& header, uint64_t expectedTag, TagClass expectedClass = TagClass::Universal) { |
52 void assertTag(const Header& header, uint64_t expectedTag, TagClass expectedClass = TagClass::Universal) { |
53 if (header.tagClass != expectedClass || header.tag != expectedTag) throw relpipe::writer::RelpipeWriterException(L"Unexpected tag."); // TODO: add actual vs. expected values |
53 if (header.tagClass != expectedClass || header.tag != expectedTag) throw relpipe::writer::RelpipeWriterException(L"Unexpected tag."); // TODO: add actual vs. expected values |
|
54 } |
|
55 |
|
56 State startRelation() { |
|
57 writer->startRelation(currentRelationName, currentAttributes, true); |
|
58 currentRelationName = L""; |
|
59 currentAttributes.clear(); |
|
60 return State::Records; |
|
61 } |
|
62 |
|
63 State setRelationName(std::string value) { |
|
64 currentRelationName = convertor.from_bytes(value); |
|
65 return State::Header; |
|
66 } |
|
67 |
|
68 State setAttributeName(relpipe::common::type::StringX value) { |
|
69 currentAttributes.push_back({value, relpipe::writer::TypeId::STRING}); |
|
70 return State::AttributeType; |
|
71 } |
|
72 |
|
73 State setAttributeType(relpipe::common::type::StringX value) { |
|
74 currentAttributes.back().typeId = writer->toTypeId(value); |
|
75 return State::AttributeType; |
54 } |
76 } |
55 |
77 |
56 public: |
78 public: |
57 |
79 |
58 RelpipeASN1ContentHandler(std::shared_ptr<relpipe::writer::RelationalWriter> writer, Configuration configuration) : writer(writer), configuration(configuration) { |
80 RelpipeASN1ContentHandler(std::shared_ptr<relpipe::writer::RelationalWriter> writer, Configuration configuration) : writer(writer), configuration(configuration) { |
73 if (state == State::Start) state = State::Relation; |
95 if (state == State::Start) state = State::Relation; |
74 else if (state == State::Relation) state = State::RelationName; |
96 else if (state == State::Relation) state = State::RelationName; |
75 else if (state == State::Header) state = State::HeaderItem; |
97 else if (state == State::Header) state = State::HeaderItem; |
76 else if (state == State::HeaderItem) state = State::AttributeName; |
98 else if (state == State::HeaderItem) state = State::AttributeName; |
77 else if (state == State::Records) state = State::Record; |
99 else if (state == State::Records) state = State::Record; |
78 else std::wcerr << L"writeCollectionStart(): state=" << (int) state << std::endl; // TODO: remove |
100 else throw std::logic_error("Illegal state in writeCollectionStart(): " + std::to_string((int) state)); |
79 } |
101 } |
80 |
102 |
81 void writeCollectionEnd() override { |
103 void writeCollectionEnd() override { |
82 if (state == State::Header) state = State::Records; |
104 if (state == State::AttributeType) state = State::HeaderItem; |
83 else if (state == State::AttributeType) state = State::HeaderItem; |
105 else if (state == State::HeaderItem) state = startRelation(); |
84 else if (state == State::HeaderItem) state = State::Records; |
|
85 else if (state == State::Records) state = State::Relation; |
106 else if (state == State::Records) state = State::Relation; |
86 else if (state == State::Record) state = State::Record; |
107 else if (state == State::Record) state = State::Records; |
87 else std::wcerr << L"writeCollectionEnd(): state=" << (int) state << std::endl; // TODO: remove |
108 else if (state == State::Relation) state = State::End; |
88 |
109 else throw std::logic_error("Illegal state in writeCollectionEnd(): " + std::to_string((int) state)); |
89 if (state == State::Records) { |
|
90 writer->startRelation(currentRelationName, currentAttributes, true); |
|
91 currentRelationName = L""; |
|
92 currentAttributes.clear(); |
|
93 } |
|
94 } |
110 } |
95 |
111 |
96 void writeBitString(const Header& header, std::vector<bool> value) override { |
112 void writeBitString(const Header& header, std::vector<bool> value) override { |
|
113 throw std::logic_error("Unsupported data type: BitString"); |
97 } |
114 } |
98 |
115 |
99 void writeBoolean(const Header& header, bool value) override { |
116 void writeBoolean(const Header& header, bool value) override { |
100 if (state == State::Record) writer->writeAttribute(&value, typeid (value)); |
117 if (state == State::Record) writer->writeAttribute(&value, typeid (value)); |
|
118 else throw std::logic_error("Illegal state in writeBoolean(): " + std::to_string((int) state)); |
101 } |
119 } |
102 |
120 |
103 void writeDateTime(const Header& header, DateTime value) override { |
121 void writeDateTime(const Header& header, DateTime value) override { |
|
122 throw std::logic_error("Unsupported data type: DateTime"); |
104 } |
123 } |
105 |
124 |
106 void writeInteger(const Header& header, Integer value) override { |
125 void writeInteger(const Header& header, Integer value) override { |
107 relpipe::common::type::Integer integer = value.toInt64(); |
126 relpipe::common::type::Integer integer = value.toInt64(); |
108 if (state == State::Record) writer->writeAttribute(&integer, typeid (integer)); |
127 if (state == State::Record) writer->writeAttribute(&integer, typeid (integer)); |
|
128 else throw std::logic_error("Illegal state in writeInteger(): " + std::to_string((int) state)); |
109 } |
129 } |
110 |
130 |
111 void writeNull(const Header& header) override { |
131 void writeNull(const Header& header) override { |
|
132 throw std::logic_error("Unsupported data type: Null"); |
112 } |
133 } |
113 |
134 |
114 void writeOID(const Header& header, ObjectIdentifier value) override { |
135 void writeOID(const Header& header, ObjectIdentifier value) override { |
|
136 throw std::logic_error("Unsupported data type: OID"); |
115 } |
137 } |
116 |
138 |
117 void writeOctetString(const Header& header, std::string value) override { |
139 void writeOctetString(const Header& header, std::string value) override { |
|
140 throw std::logic_error("Unsupported data type: OctetString"); |
118 } |
141 } |
119 |
142 |
120 void writeTextString(const Header& header, std::string value) override { |
143 void writeTextString(const Header& header, std::string value) override { |
121 assertTag(header, lib::UniversalType::UTF8String); |
144 assertTag(header, lib::UniversalType::UTF8String); |
122 relpipe::common::type::StringX str = convertor.from_bytes(value); |
145 relpipe::common::type::StringX str = convertor.from_bytes(value); |
123 |
146 |
124 if (state == State::RelationName) { |
147 if (state == State::RelationName) state = setRelationName(value); |
125 currentRelationName = convertor.from_bytes(value); |
148 else if (state == State::AttributeName) state = setAttributeName(str); |
126 state = State::Header; |
149 else if (state == State::AttributeType) state = setAttributeType(str); |
127 } else if (state == State::AttributeName) { |
150 else if (state == State::Record) writer->writeAttribute(&str, typeid (str)); |
128 currentAttributes.push_back({str, relpipe::writer::TypeId::STRING}); |
151 else throw std::logic_error("Illegal state in writeTextString(): " + std::to_string((int) state)); |
129 state = State::AttributeType; |
|
130 } else if (state == State::AttributeType) { |
|
131 currentAttributes.back().typeId = writer->toTypeId(str); |
|
132 } else if (state == State::Record) { |
|
133 writer->writeAttribute(&str, typeid (str)); |
|
134 } else std::wcerr << L"writeTextString(): state=" << (int) state << std::endl; // TODO: remove |
|
135 } |
152 } |
136 |
153 |
137 void writeSpecific(const Header& header, std::string value) override { |
154 void writeSpecific(const Header& header, std::string value) override { |
|
155 throw std::logic_error("Unsupported data type: Specific"); |
138 } |
156 } |
139 |
157 |
140 |
158 |
141 }; |
159 }; |
142 |
160 |