diff --git a/groups/nts/ntsa/ntsa_host.cpp b/groups/nts/ntsa/ntsa_host.cpp index 4bed773b..f8ac11a3 100644 --- a/groups/nts/ntsa/ntsa_host.cpp +++ b/groups/nts/ntsa/ntsa_host.cpp @@ -340,5 +340,50 @@ bsl::ostream& Host::print(bsl::ostream& stream, return stream; } +const bdlat_SelectionInfo* Host::lookupSelectionInfo(int id) +{ + const int numSelections = + sizeof(SELECTION_INFO_ARRAY) / sizeof(SELECTION_INFO_ARRAY[0]); + + if (id < 0 || id >= numSelections) { + return 0; + } + + return &SELECTION_INFO_ARRAY[id]; +} + +const bdlat_SelectionInfo* Host::lookupSelectionInfo( + const char* name, + int nameLength) +{ + const bsl::size_t numSelections = + sizeof(SELECTION_INFO_ARRAY) / sizeof(SELECTION_INFO_ARRAY[0]); + + for (bsl::size_t i = 0; i < numSelections; ++i) { + const bdlat_SelectionInfo& selectionInfo = SELECTION_INFO_ARRAY[i]; + if (selectionInfo.d_nameLength == nameLength) { + const int compare = + bsl::memcmp(selectionInfo.d_name_p, name, nameLength); + if (compare == 0) { + return &selectionInfo; + } + } + } + + return 0; +} + +const char Host::CLASS_NAME[11] = "ntsa::Host"; + +// clang-format off +const bdlat_SelectionInfo Host::SELECTION_INFO_ARRAY[4] = +{ + { ntsa::HostType::e_UNDEFINED, "undefined", 9, "", 0 }, + { ntsa::HostType::e_DOMAIN_NAME, "domain", 6, "", 0 }, + { ntsa::HostType::e_IP, "ip", 2, "", 0 }, + { ntsa::HostType::e_LOCAL_NAME, "local", 5, "", 0 } +}; +// clang-format on + } // close package namespace } // close enterprise namespace diff --git a/groups/nts/ntsa/ntsa_host.h b/groups/nts/ntsa/ntsa_host.h index 1177803d..68b418fd 100644 --- a/groups/nts/ntsa/ntsa_host.h +++ b/groups/nts/ntsa/ntsa_host.h @@ -25,6 +25,9 @@ BSLS_IDENT("$Id: $") #include #include #include +#include +#include +#include #include #include #include @@ -238,6 +241,51 @@ class Host int level = 0, int spacesPerLevel = 4) const; + /// Set the value of this object to be the default for the selection + /// indicated by the specified 'id'. Return 0 on success, and non-zero + /// value otherwise (i.e., the selection is not found). + int makeSelection(int id); + + /// Set the value of this object to be the default for the selection + /// indicated by the specified 'name' of the specified 'nameLength'. + /// Return 0 on success, and non-zero value otherwise (i.e., the selection + /// is not found). + int makeSelection(const char* name, int nameLength); + + /// Return the selection ID of the current selection in the choice. + int selectionId() const; + + /// Invoke the specified 'manipulator' on the address of the modifiable + /// selection, supplying 'manipulator' with the corresponding selection + /// information structure. Return the value returned from the invocation + /// of 'manipulator' if this object has a defined selection, and -1 + /// otherwise. + template + int manipulateSelection(MANIPULATOR& manipulator); + + /// Invoke the specified 'accessor' on the non-modifiable selection, + /// supplying 'accessor' with the corresponding selection information + /// structure. Return the value returned from the invocation of 'accessor' + /// if this object has a defined selection, and -1 otherwise. + template + int accessSelection(ACCESSOR& accessor) const; + + /// Return the compiler-independant name for this class. + static const char CLASS_NAME[11]; + + /// The selection info array, indexed by selection index. + static const bdlat_SelectionInfo SELECTION_INFO_ARRAY[4]; + + /// Return selection information for the selection indicated by the + /// specified 'id' if the selection exists, and 0 otherwise. + static const bdlat_SelectionInfo* lookupSelectionInfo(int id); + + /// Return selection information for the selection indicated by the + /// specified 'name' of the specified 'nameLength' if the selection + /// exists, and 0 otherwise. + static const bdlat_SelectionInfo* lookupSelectionInfo( + const char* name, int nameLength); + /// Defines the traits of this type. These traits can be used to select, /// at compile-time, the most efficient algorithm to manipulate objects /// of this type. @@ -395,6 +443,134 @@ void hashAppend(HASH_ALGORITHM& algorithm, const Host& value) } } +NTSCFG_INLINE +int Host::makeSelection(int id) +{ + switch (id) { + case ntsa::HostType::e_UNDEFINED: + this->reset(); + break; + case ntsa::HostType::e_DOMAIN_NAME: + this->makeDomainName(); + break; + case ntsa::HostType::e_IP: + this->makeIp(); + break; + case ntsa::HostType::e_LOCAL_NAME: + this->makeLocalName(); + break; + default: + return -1; + } + + return 0; +} + +NTSCFG_INLINE +int Host::makeSelection(const char* name, int nameLength) +{ + const bdlat_SelectionInfo *selectionInfo = + ntsa::Host::lookupSelectionInfo(name, nameLength); + if (selectionInfo == 0) { + return -1; + } + + return this->makeSelection(selectionInfo->d_id); +} + +NTSCFG_INLINE +int Host::selectionId() const +{ + return static_cast(d_type); +} + +template +int Host::manipulateSelection(MANIPULATOR& manipulator) +{ + int rc; + + if (d_type == ntsa::HostType::e_UNDEFINED) { + ; + } + else if (d_type == ntsa::HostType::e_DOMAIN_NAME) { + bsl::string representation; + rc = manipulator(&representation, SELECTION_INFO_ARRAY[d_type]); + if (rc != 0) { + return rc; + } + + if (!d_domainName.object().parse(representation)) { + return 1; + } + } + else if (d_type == ntsa::HostType::e_IP) { + bsl::string representation; + rc = manipulator(&representation, SELECTION_INFO_ARRAY[d_type]); + if (rc != 0) { + return rc; + } + + if (!d_ip.object().parse(representation)) { + return 1; + } + } + else if (d_type == ntsa::HostType::e_LOCAL_NAME) { + rc = manipulator(&d_localName.object(), SELECTION_INFO_ARRAY[d_type]); + if (rc != 0) { + return rc; + } + } + else { + return -1; + } + + return 0; +} + +template +int Host::accessSelection(ACCESSOR& accessor) const +{ + int rc; + + const bdlat_SelectionInfo *selectionInfo = + ntsa::Host::lookupSelectionInfo(d_type); + if (selectionInfo == 0) { + return -1; + } + + if (d_type == ntsa::HostType::e_UNDEFINED) { + ; + } + else if (d_type == ntsa::HostType::e_DOMAIN_NAME) { + bsl::string representation = d_domainName.object().text(); + rc = accessor(representation, SELECTION_INFO_ARRAY[d_type]); + if (rc != 0) { + return rc; + } + } + else if (d_type == ntsa::HostType::e_IP) { + bsl::string representation = d_ip.object().text(); + rc = accessor(representation, SELECTION_INFO_ARRAY[d_type]); + if (rc != 0) { + return rc; + } + } + else if (d_type == ntsa::HostType::e_LOCAL_NAME) { + rc = accessor(d_localName.object(), SELECTION_INFO_ARRAY[d_type]); + if (rc != 0) { + return rc; + } + } + else { + return -1; + } + + return 0; +} + } // close package namespace + +BDLAT_DECL_CHOICE_TRAITS(ntsa::Host) + } // close enterprise namespace #endif diff --git a/groups/nts/ntsa/ntsa_host.t.cpp b/groups/nts/ntsa/ntsa_host.t.cpp index b518ec11..69dc8af2 100644 --- a/groups/nts/ntsa/ntsa_host.t.cpp +++ b/groups/nts/ntsa/ntsa_host.t.cpp @@ -15,6 +15,12 @@ #include #include +#include +#include +#include +#include +#include +#include #include #include #include @@ -125,9 +131,115 @@ NTSCFG_TEST_CASE(2) NTSCFG_TEST_ASSERT(ta.numBlocksInUse() == 0); } +NTSCFG_TEST_CASE(3) +{ + int rc; + + ntscfg::TestAllocator ta; + { + ntsa::Host e1("10.26.55.100"); + ntsa::Host e2; + + bdlsb::MemOutStreamBuf osb(&ta); + + balber::BerEncoder encoder(0, &ta); + rc = encoder.encode(&osb, e1); + if (rc != 0) { + NTSCFG_TEST_LOG_DEBUG << encoder.loggedMessages() + << NTSCFG_TEST_LOG_END; + + NTSCFG_TEST_EQ(rc, 0); + } + + rc = osb.pubsync(); + NTSCFG_TEST_EQ(rc, 0); + + NTSCFG_TEST_GT(osb.length(), 0); + NTSCFG_TEST_NE(osb.data(), 0); + + NTSCFG_TEST_LOG_DEBUG << "Encoded:\n" + << bdlb::PrintStringHexDumper( + osb.data(), + static_cast(osb.length())) + << NTSCFG_TEST_LOG_END; + + bdlsb::FixedMemInStreamBuf isb(osb.data(), osb.length()); + + balber::BerDecoder decoder(0, &ta); + rc = decoder.decode(&isb, &e2); + if (rc != 0) { + NTSCFG_TEST_LOG_DEBUG << encoder.loggedMessages() + << NTSCFG_TEST_LOG_END; + + NTSCFG_TEST_EQ(rc, 0); + } + + NTSCFG_TEST_EQ(e2, e1); + } + NTSCFG_TEST_EQ(ta.numBlocksInUse(), 0); +} + +NTSCFG_TEST_CASE(4) +{ + int rc; + + ntscfg::TestAllocator ta; + { + bsl::vector e1(&ta); + bsl::vector e2(&ta); + + e1.push_back(ntsa::Host("ntf.example.com")); + e1.push_back(ntsa::Host("10.26.55.100")); + e1.push_back(ntsa::Host("/tmp/ntf/socket")); + + bdlsb::MemOutStreamBuf osb; + + baljsn::Encoder encoder(&ta); + rc = encoder.encode(&osb, e1); + if (rc != 0) { + NTSCFG_TEST_LOG_DEBUG << encoder.loggedMessages() + << NTSCFG_TEST_LOG_END; + + NTSCFG_TEST_EQ(rc, 0); + } + + rc = osb.pubsync(); + NTSCFG_TEST_EQ(rc, 0); + + NTSCFG_TEST_GT(osb.length(), 0); + NTSCFG_TEST_NE(osb.data(), 0); + + NTSCFG_TEST_LOG_DEBUG << "Encoded: " + << bsl::string_view( + osb.data(), + static_cast(osb.length())) + << NTSCFG_TEST_LOG_END; + + bdlsb::FixedMemInStreamBuf isb(osb.data(), osb.length()); + + baljsn::Decoder decoder(&ta); + rc = decoder.decode(&isb, &e2); + if (rc != 0) { + NTSCFG_TEST_LOG_DEBUG << encoder.loggedMessages() + << NTSCFG_TEST_LOG_END; + + NTSCFG_TEST_EQ(rc, 0); + } + + NTSCFG_TEST_EQ(e2.size(), e1.size()); + + for (bsl::size_t i = 0; i < e1.size(); ++i) { + NTSCFG_TEST_EQ(e2[i], e1[i]); + } + } + NTSCFG_TEST_EQ(ta.numBlocksInUse(), 0); +} + NTSCFG_TEST_DRIVER { NTSCFG_TEST_REGISTER(1); NTSCFG_TEST_REGISTER(2); + NTSCFG_TEST_REGISTER(3); + NTSCFG_TEST_REGISTER(4); } NTSCFG_TEST_DRIVER_END; diff --git a/groups/nts/ntsa/ntsa_transport.cpp b/groups/nts/ntsa/ntsa_transport.cpp index bffe9f53..3fd148ba 100644 --- a/groups/nts/ntsa/ntsa_transport.cpp +++ b/groups/nts/ntsa/ntsa_transport.cpp @@ -275,6 +275,13 @@ int Transport::fromString(Transport::Value* result, return -1; } +int Transport::fromString(Value* result, const char* string, int stringLength) +{ + return Transport::fromString( + result, + bslstl::StringRef(string, static_cast(stringLength))); +} + const char* Transport::toString(Transport::Value value) { switch (value) { diff --git a/groups/nts/ntsa/ntsa_transport.h b/groups/nts/ntsa/ntsa_transport.h index fa660289..8633eb6a 100644 --- a/groups/nts/ntsa/ntsa_transport.h +++ b/groups/nts/ntsa/ntsa_transport.h @@ -19,6 +19,9 @@ #include BSLS_IDENT("$Id: $") +#include +#include +#include #include #include #include @@ -71,8 +74,6 @@ struct TransportProtocol { static bsl::ostream& print(bsl::ostream& stream, Value value); }; -// FREE OPERATORS - /// Format the specified 'rhs' to the specified output 'stream' and return a /// reference to the modifiable 'stream'. /// @@ -124,8 +125,6 @@ struct TransportDomain { static bsl::ostream& print(bsl::ostream& stream, Value value); }; -// FREE OPERATORS - /// Format the specified 'rhs' to the specified output 'stream' and return a /// reference to the modifiable 'stream'. /// @@ -174,8 +173,6 @@ struct TransportMode { static bsl::ostream& print(bsl::ostream& stream, Value value); }; -// FREE OPERATORS - /// Format the specified 'rhs' to the specified output 'stream' and return a /// reference to the modifiable 'stream'. /// @@ -236,6 +233,12 @@ struct Transport { /// enumerator). static int fromString(Value* result, const bslstl::StringRef& string); + /// Load into the specified `result` the enumerator matching the + /// specified `string` of the specified `stringLength`. Return 0 on + /// success, and a non-zero value with no effect on `result` otherwise + /// (i.e., `string` does not match any enumerator). + static int fromString(Value* result, const char* string, int stringLength); + /// Load into the specified 'result' the enumerator matching the /// specified 'number'. Return 0 on success, and a non-zero value with /// no effect on 'result' otherwise (i.e., 'number' does not match any @@ -257,8 +260,6 @@ struct Transport { static bsl::ostream& print(bsl::ostream& stream, Value value); }; -// FREE OPERATORS - /// Format the specified 'rhs' to the specified output 'stream' and return a /// reference to the modifiable 'stream'. /// @@ -266,5 +267,8 @@ struct Transport { bsl::ostream& operator<<(bsl::ostream& stream, Transport::Value rhs); } // end namespace ntsa + +BDLAT_DECL_ENUMERATION_TRAITS(ntsa::Transport) + } // end namespace BloombergLP #endif diff --git a/groups/nts/ntsa/ntsa_uri.cpp b/groups/nts/ntsa/ntsa_uri.cpp index 186d2d17..80c6a71c 100644 --- a/groups/nts/ntsa/ntsa_uri.cpp +++ b/groups/nts/ntsa/ntsa_uri.cpp @@ -564,6 +564,53 @@ bsl::ostream& UriAuthority::print(bsl::ostream& stream, return stream; } +const bdlat_AttributeInfo* UriAuthority::lookupAttributeInfo(int id) +{ + const int numAttributes = + sizeof(ATTRIBUTE_INFO_ARRAY) / sizeof(ATTRIBUTE_INFO_ARRAY[0]); + + if (id < 0 || id >= numAttributes) { + return 0; + } + + return &ATTRIBUTE_INFO_ARRAY[id]; +} + +const bdlat_AttributeInfo* UriAuthority::lookupAttributeInfo( + const char* name, + int nameLength) +{ + const bsl::size_t numAttributes = + sizeof(ATTRIBUTE_INFO_ARRAY) / sizeof(ATTRIBUTE_INFO_ARRAY[0]); + + for (bsl::size_t i = 0; i < numAttributes; ++i) { + const bdlat_AttributeInfo& attributeInfo = ATTRIBUTE_INFO_ARRAY[i]; + if (attributeInfo.d_nameLength == nameLength) { + const int compare = + bsl::memcmp(attributeInfo.d_name_p, name, nameLength); + if (compare == 0) { + return &attributeInfo; + } + } + } + + return 0; +} + +const char UriAuthority::CLASS_NAME[19] = "ntsa::UriAuthority"; + +// clang-format off +const bdlat_AttributeInfo UriAuthority::ATTRIBUTE_INFO_ARRAY[4] = +{ + { e_ATTRIBUTE_ID_USER, "user", 4, "", 0 }, + { e_ATTRIBUTE_ID_HOST, "host", 4, "", 0 }, + { e_ATTRIBUTE_ID_PORT, "port", 4, "", 0 }, + { e_ATTRIBUTE_ID_TRANSPORT, "transport", 9, "", 0 } +}; +// clang-format on + + + bsl::ostream& operator<<(bsl::ostream& stream, const UriAuthority& object) { return object.print(stream, 0, -1); @@ -639,7 +686,6 @@ ntsa::Error UriParameter::setValue(const bslstl::StringRef& value) return ntsa::Error(); } -// ACCCESSORS const bsl::string& UriParameter::name() const { return d_name; @@ -685,6 +731,49 @@ bsl::ostream& UriParameter::print(bsl::ostream& stream, return stream; } +const bdlat_AttributeInfo* UriParameter::lookupAttributeInfo(int id) +{ + const int numAttributes = + sizeof(ATTRIBUTE_INFO_ARRAY) / sizeof(ATTRIBUTE_INFO_ARRAY[0]); + + if (id < 0 || id >= numAttributes) { + return 0; + } + + return &ATTRIBUTE_INFO_ARRAY[id]; +} + +const bdlat_AttributeInfo* UriParameter::lookupAttributeInfo( + const char* name, + int nameLength) +{ + const bsl::size_t numAttributes = + sizeof(ATTRIBUTE_INFO_ARRAY) / sizeof(ATTRIBUTE_INFO_ARRAY[0]); + + for (bsl::size_t i = 0; i < numAttributes; ++i) { + const bdlat_AttributeInfo& attributeInfo = ATTRIBUTE_INFO_ARRAY[i]; + if (attributeInfo.d_nameLength == nameLength) { + const int compare = + bsl::memcmp(attributeInfo.d_name_p, name, nameLength); + if (compare == 0) { + return &attributeInfo; + } + } + } + + return 0; +} + +const char UriParameter::CLASS_NAME[19] = "ntsa::UriParameter"; + +// clang-format off +const bdlat_AttributeInfo UriParameter::ATTRIBUTE_INFO_ARRAY[2] = +{ + { e_ATTRIBUTE_ID_NAME, "name", 4, "", 0 }, + { e_ATTRIBUTE_ID_VALUE, "value", 5, "", 0 } +}; +// clang-format on + bsl::ostream& operator<<(bsl::ostream& stream, const UriParameter& object) { return object.print(stream, 0, -1); @@ -843,6 +932,48 @@ bsl::ostream& UriQuery::print(bsl::ostream& stream, return stream; } +const bdlat_AttributeInfo* UriQuery::lookupAttributeInfo(int id) +{ + const int numAttributes = + sizeof(ATTRIBUTE_INFO_ARRAY) / sizeof(ATTRIBUTE_INFO_ARRAY[0]); + + if (id < 0 || id >= numAttributes) { + return 0; + } + + return &ATTRIBUTE_INFO_ARRAY[id]; +} + +const bdlat_AttributeInfo* UriQuery::lookupAttributeInfo( + const char* name, + int nameLength) +{ + const bsl::size_t numAttributes = + sizeof(ATTRIBUTE_INFO_ARRAY) / sizeof(ATTRIBUTE_INFO_ARRAY[0]); + + for (bsl::size_t i = 0; i < numAttributes; ++i) { + const bdlat_AttributeInfo& attributeInfo = ATTRIBUTE_INFO_ARRAY[i]; + if (attributeInfo.d_nameLength == nameLength) { + const int compare = + bsl::memcmp(attributeInfo.d_name_p, name, nameLength); + if (compare == 0) { + return &attributeInfo; + } + } + } + + return 0; +} + +const char UriQuery::CLASS_NAME[15] = "ntsa::UriQuery"; + +// clang-format off +const bdlat_AttributeInfo UriQuery::ATTRIBUTE_INFO_ARRAY[1] = +{ + { e_ATTRIBUTE_ID_PARAMETER, "parameter", 9, "", 0 } +}; +// clang-format on + bsl::ostream& operator<<(bsl::ostream& stream, const UriQuery& object) { return object.print(stream, 0, -1); @@ -1666,6 +1797,53 @@ bsl::ostream& Uri::print(bsl::ostream& stream, return stream; } +const bdlat_AttributeInfo* Uri::lookupAttributeInfo(int id) +{ + const int numAttributes = + sizeof(ATTRIBUTE_INFO_ARRAY) / sizeof(ATTRIBUTE_INFO_ARRAY[0]); + + if (id < 0 || id >= numAttributes) { + return 0; + } + + return &ATTRIBUTE_INFO_ARRAY[id]; +} + +const bdlat_AttributeInfo* Uri::lookupAttributeInfo( + const char* name, + int nameLength) +{ + const bsl::size_t numAttributes = + sizeof(ATTRIBUTE_INFO_ARRAY) / sizeof(ATTRIBUTE_INFO_ARRAY[0]); + + for (bsl::size_t i = 0; i < numAttributes; ++i) { + const bdlat_AttributeInfo& attributeInfo = ATTRIBUTE_INFO_ARRAY[i]; + if (attributeInfo.d_nameLength == nameLength) { + const int compare = + bsl::memcmp(attributeInfo.d_name_p, name, nameLength); + if (compare == 0) { + return &attributeInfo; + } + } + } + + return 0; +} + +const char Uri::CLASS_NAME[10] = "ntsa::Uri"; + +// clang-format off +const bdlat_AttributeInfo Uri::ATTRIBUTE_INFO_ARRAY[5] = +{ + { e_ATTRIBUTE_ID_SCHEME, "scheme", 6, "", 0 }, + { e_ATTRIBUTE_ID_AUTHORITY, "authority", 9, "", 0 }, + { e_ATTRIBUTE_ID_PATH, "path", 4, "", 0 }, + { e_ATTRIBUTE_ID_QUERY, "query", 5, "", 0 }, + { e_ATTRIBUTE_ID_FRAGMENT, "fragment", 8, "", 0 }, + +}; +// clang-format on + bsl::ostream& operator<<(bsl::ostream& stream, const Uri& object) { return object.print(stream, 0, -1); diff --git a/groups/nts/ntsa/ntsa_uri.h b/groups/nts/ntsa/ntsa_uri.h index cbf91c1f..df23ae37 100644 --- a/groups/nts/ntsa/ntsa_uri.h +++ b/groups/nts/ntsa/ntsa_uri.h @@ -28,6 +28,9 @@ BSLS_IDENT("$Id: $") #include #include #include +#include +#include +#include #include #include #include @@ -50,6 +53,13 @@ namespace ntsa { /// @ingroup module_ntsa_identity class UriAuthority { + enum { + e_ATTRIBUTE_ID_USER = 0, + e_ATTRIBUTE_ID_HOST = 1, + e_ATTRIBUTE_ID_PORT = 2, + e_ATTRIBUTE_ID_TRANSPORT = 3 + }; + bdlb::NullableValue d_user; bdlb::NullableValue d_host; bdlb::NullableValue d_port; @@ -150,6 +160,77 @@ class UriAuthority int level = 0, int spacesPerLevel = 4) const; + /// Invoke the specified 'manipulator' sequentially on the address of each + /// (modifiable) attribute of this object, supplying 'manipulator' with + /// the corresponding attribute information structure until such + /// invocation returns a non-zero value. Return the value from the last + /// invocation of 'manipulator' (i.e., the invocation that terminated the + /// sequence). + template + int manipulateAttributes(MANIPULATOR& manipulator); + + /// Invoke the specified 'manipulator' on the address of the (modifiable) + /// attribute indicated by the specified 'id', supplying 'manipulator' + /// with the corresponding attribute information structure. Return the + /// value returned from the invocation of 'manipulator' if 'id' identifies + /// an attribute of this class, and -1 otherwise. + template + int manipulateAttribute(MANIPULATOR& manipulator, int id); + + /// Invoke the specified 'manipulator' on the address of the (modifiable) + /// attribute indicated by the specified 'name' of the specified + /// 'nameLength', supplying 'manipulator' with the corresponding attribute + /// information structure. Return the value returned from the invocation + /// of 'manipulator' if 'name' identifies an attribute of this class, and + /// -1 otherwise. + template + int manipulateAttribute(MANIPULATOR& manipulator, + const char* name, + int nameLength); + + /// Invoke the specified 'accessor' sequentially on each (non-modifiable) + /// attribute of this object, supplying 'accessor' with the corresponding + /// attribute information structure until such invocation returns a + /// non-zero value. Return the value from the last invocation of + /// 'accessor' (i.e., the invocation that terminated the sequence). + template + int accessAttributes(ACCESSOR& accessor) const; + + /// Invoke the specified 'accessor' on the (non-modifiable) attribute of + /// this object indicated by the specified 'id', supplying 'accessor' with + /// the corresponding attribute information structure. Return the value + /// returned from the invocation of 'accessor' if 'id' identifies an + /// attribute of this class, and -1 otherwise. + template + int accessAttribute(ACCESSOR& accessor, int id) const; + + /// Invoke the specified 'accessor' on the (non-modifiable) attribute of + /// this object indicated by the specified 'name' of the specified + /// 'nameLength', supplying 'accessor' with the corresponding attribute + /// information structure. Return the value returned from the invocation + /// of 'accessor' if 'name' identifies an attribute of this class, and -1 + /// otherwise. + template + int accessAttribute(ACCESSOR& accessor, + const char* name, + int nameLength) const; + + /// Return attribute information for the attribute indicated by the + /// specified 'id' if the attribute exists, and 0 otherwise. + static const bdlat_AttributeInfo* lookupAttributeInfo(int id); + + /// Return attribute information for the attribute indicated by the + /// specified 'name' of the specified 'nameLength' if the attribute + /// exists, and 0 otherwise. + static const bdlat_AttributeInfo* lookupAttributeInfo( + const char* name, int nameLength); + + /// Return the compiler-independant name for this class. + static const char CLASS_NAME[19]; + + /// The attribute info array, indexed by attribute index. + static const bdlat_AttributeInfo ATTRIBUTE_INFO_ARRAY[4]; + /// Defines the traits of this type. These traits can be used to select, /// at compile-time, the most efficient algorithm to manipulate objects /// of this type. @@ -200,6 +281,11 @@ void hashAppend(HASH_ALGORITHM& algorithm, const UriAuthority& value); /// @ingroup module_ntsa_identity class UriParameter { + enum { + e_ATTRIBUTE_ID_NAME = 0, + e_ATTRIBUTE_ID_VALUE = 1 + }; + bsl::string d_name; bdlb::NullableValue d_value; @@ -266,6 +352,77 @@ class UriParameter int level = 0, int spacesPerLevel = 4) const; + /// Invoke the specified 'manipulator' sequentially on the address of each + /// (modifiable) attribute of this object, supplying 'manipulator' with + /// the corresponding attribute information structure until such + /// invocation returns a non-zero value. Return the value from the last + /// invocation of 'manipulator' (i.e., the invocation that terminated the + /// sequence). + template + int manipulateAttributes(MANIPULATOR& manipulator); + + /// Invoke the specified 'manipulator' on the address of the (modifiable) + /// attribute indicated by the specified 'id', supplying 'manipulator' + /// with the corresponding attribute information structure. Return the + /// value returned from the invocation of 'manipulator' if 'id' identifies + /// an attribute of this class, and -1 otherwise. + template + int manipulateAttribute(MANIPULATOR& manipulator, int id); + + /// Invoke the specified 'manipulator' on the address of the (modifiable) + /// attribute indicated by the specified 'name' of the specified + /// 'nameLength', supplying 'manipulator' with the corresponding attribute + /// information structure. Return the value returned from the invocation + /// of 'manipulator' if 'name' identifies an attribute of this class, and + /// -1 otherwise. + template + int manipulateAttribute(MANIPULATOR& manipulator, + const char* name, + int nameLength); + + /// Invoke the specified 'accessor' sequentially on each (non-modifiable) + /// attribute of this object, supplying 'accessor' with the corresponding + /// attribute information structure until such invocation returns a + /// non-zero value. Return the value from the last invocation of + /// 'accessor' (i.e., the invocation that terminated the sequence). + template + int accessAttributes(ACCESSOR& accessor) const; + + /// Invoke the specified 'accessor' on the (non-modifiable) attribute of + /// this object indicated by the specified 'id', supplying 'accessor' with + /// the corresponding attribute information structure. Return the value + /// returned from the invocation of 'accessor' if 'id' identifies an + /// attribute of this class, and -1 otherwise. + template + int accessAttribute(ACCESSOR& accessor, int id) const; + + /// Invoke the specified 'accessor' on the (non-modifiable) attribute of + /// this object indicated by the specified 'name' of the specified + /// 'nameLength', supplying 'accessor' with the corresponding attribute + /// information structure. Return the value returned from the invocation + /// of 'accessor' if 'name' identifies an attribute of this class, and -1 + /// otherwise. + template + int accessAttribute(ACCESSOR& accessor, + const char* name, + int nameLength) const; + + /// Return attribute information for the attribute indicated by the + /// specified 'id' if the attribute exists, and 0 otherwise. + static const bdlat_AttributeInfo* lookupAttributeInfo(int id); + + /// Return attribute information for the attribute indicated by the + /// specified 'name' of the specified 'nameLength' if the attribute + /// exists, and 0 otherwise. + static const bdlat_AttributeInfo* lookupAttributeInfo( + const char* name, int nameLength); + + /// Return the compiler-independant name for this class. + static const char CLASS_NAME[19]; + + /// The attribute info array, indexed by attribute index. + static const bdlat_AttributeInfo ATTRIBUTE_INFO_ARRAY[2]; + /// Defines the traits of this type. These traits can be used to select, /// at compile-time, the most efficient algorithm to manipulate objects /// of this type. @@ -315,6 +472,10 @@ void hashAppend(HASH_ALGORITHM& algorithm, const UriParameter& value); /// @ingroup module_ntsa_identity class UriQuery { + enum { + e_ATTRIBUTE_ID_PARAMETER = 0 + }; + bsl::vector d_parameterList; public: @@ -382,6 +543,77 @@ class UriQuery int level = 0, int spacesPerLevel = 4) const; + /// Invoke the specified 'manipulator' sequentially on the address of each + /// (modifiable) attribute of this object, supplying 'manipulator' with + /// the corresponding attribute information structure until such + /// invocation returns a non-zero value. Return the value from the last + /// invocation of 'manipulator' (i.e., the invocation that terminated the + /// sequence). + template + int manipulateAttributes(MANIPULATOR& manipulator); + + /// Invoke the specified 'manipulator' on the address of the (modifiable) + /// attribute indicated by the specified 'id', supplying 'manipulator' + /// with the corresponding attribute information structure. Return the + /// value returned from the invocation of 'manipulator' if 'id' identifies + /// an attribute of this class, and -1 otherwise. + template + int manipulateAttribute(MANIPULATOR& manipulator, int id); + + /// Invoke the specified 'manipulator' on the address of the (modifiable) + /// attribute indicated by the specified 'name' of the specified + /// 'nameLength', supplying 'manipulator' with the corresponding attribute + /// information structure. Return the value returned from the invocation + /// of 'manipulator' if 'name' identifies an attribute of this class, and + /// -1 otherwise. + template + int manipulateAttribute(MANIPULATOR& manipulator, + const char* name, + int nameLength); + + /// Invoke the specified 'accessor' sequentially on each (non-modifiable) + /// attribute of this object, supplying 'accessor' with the corresponding + /// attribute information structure until such invocation returns a + /// non-zero value. Return the value from the last invocation of + /// 'accessor' (i.e., the invocation that terminated the sequence). + template + int accessAttributes(ACCESSOR& accessor) const; + + /// Invoke the specified 'accessor' on the (non-modifiable) attribute of + /// this object indicated by the specified 'id', supplying 'accessor' with + /// the corresponding attribute information structure. Return the value + /// returned from the invocation of 'accessor' if 'id' identifies an + /// attribute of this class, and -1 otherwise. + template + int accessAttribute(ACCESSOR& accessor, int id) const; + + /// Invoke the specified 'accessor' on the (non-modifiable) attribute of + /// this object indicated by the specified 'name' of the specified + /// 'nameLength', supplying 'accessor' with the corresponding attribute + /// information structure. Return the value returned from the invocation + /// of 'accessor' if 'name' identifies an attribute of this class, and -1 + /// otherwise. + template + int accessAttribute(ACCESSOR& accessor, + const char* name, + int nameLength) const; + + /// Return attribute information for the attribute indicated by the + /// specified 'id' if the attribute exists, and 0 otherwise. + static const bdlat_AttributeInfo* lookupAttributeInfo(int id); + + /// Return attribute information for the attribute indicated by the + /// specified 'name' of the specified 'nameLength' if the attribute + /// exists, and 0 otherwise. + static const bdlat_AttributeInfo* lookupAttributeInfo( + const char* name, int nameLength); + + /// Return the compiler-independant name for this class. + static const char CLASS_NAME[15]; + + /// The attribute info array, indexed by attribute index. + static const bdlat_AttributeInfo ATTRIBUTE_INFO_ARRAY[1]; + /// Defines the traits of this type. These traits can be used to select, /// at compile-time, the most efficient algorithm to manipulate objects /// of this type. @@ -431,6 +663,14 @@ void hashAppend(HASH_ALGORITHM& algorithm, const UriQuery& value); /// @ingroup module_ntsa_identity class Uri { + enum { + e_ATTRIBUTE_ID_SCHEME = 0, + e_ATTRIBUTE_ID_AUTHORITY = 1, + e_ATTRIBUTE_ID_PATH = 2, + e_ATTRIBUTE_ID_QUERY = 3, + e_ATTRIBUTE_ID_FRAGMENT = 4 + }; + bdlb::NullableValue d_scheme; bdlb::NullableValue d_authority; bdlb::NullableValue d_path; @@ -582,6 +822,77 @@ class Uri int level = 0, int spacesPerLevel = 4) const; + /// Invoke the specified 'manipulator' sequentially on the address of each + /// (modifiable) attribute of this object, supplying 'manipulator' with + /// the corresponding attribute information structure until such + /// invocation returns a non-zero value. Return the value from the last + /// invocation of 'manipulator' (i.e., the invocation that terminated the + /// sequence). + template + int manipulateAttributes(MANIPULATOR& manipulator); + + /// Invoke the specified 'manipulator' on the address of the (modifiable) + /// attribute indicated by the specified 'id', supplying 'manipulator' + /// with the corresponding attribute information structure. Return the + /// value returned from the invocation of 'manipulator' if 'id' identifies + /// an attribute of this class, and -1 otherwise. + template + int manipulateAttribute(MANIPULATOR& manipulator, int id); + + /// Invoke the specified 'manipulator' on the address of the (modifiable) + /// attribute indicated by the specified 'name' of the specified + /// 'nameLength', supplying 'manipulator' with the corresponding attribute + /// information structure. Return the value returned from the invocation + /// of 'manipulator' if 'name' identifies an attribute of this class, and + /// -1 otherwise. + template + int manipulateAttribute(MANIPULATOR& manipulator, + const char* name, + int nameLength); + + /// Invoke the specified 'accessor' sequentially on each (non-modifiable) + /// attribute of this object, supplying 'accessor' with the corresponding + /// attribute information structure until such invocation returns a + /// non-zero value. Return the value from the last invocation of + /// 'accessor' (i.e., the invocation that terminated the sequence). + template + int accessAttributes(ACCESSOR& accessor) const; + + /// Invoke the specified 'accessor' on the (non-modifiable) attribute of + /// this object indicated by the specified 'id', supplying 'accessor' with + /// the corresponding attribute information structure. Return the value + /// returned from the invocation of 'accessor' if 'id' identifies an + /// attribute of this class, and -1 otherwise. + template + int accessAttribute(ACCESSOR& accessor, int id) const; + + /// Invoke the specified 'accessor' on the (non-modifiable) attribute of + /// this object indicated by the specified 'name' of the specified + /// 'nameLength', supplying 'accessor' with the corresponding attribute + /// information structure. Return the value returned from the invocation + /// of 'accessor' if 'name' identifies an attribute of this class, and -1 + /// otherwise. + template + int accessAttribute(ACCESSOR& accessor, + const char* name, + int nameLength) const; + + /// Return attribute information for the attribute indicated by the + /// specified 'id' if the attribute exists, and 0 otherwise. + static const bdlat_AttributeInfo* lookupAttributeInfo(int id); + + /// Return attribute information for the attribute indicated by the + /// specified 'name' of the specified 'nameLength' if the attribute + /// exists, and 0 otherwise. + static const bdlat_AttributeInfo* lookupAttributeInfo( + const char* name, int nameLength); + + /// Return the compiler-independant name for this class. + static const char CLASS_NAME[10]; + + /// The attribute info array, indexed by attribute index. + static const bdlat_AttributeInfo ATTRIBUTE_INFO_ARRAY[5]; + /// Defines the traits of this type. These traits can be used to select, /// at compile-time, the most efficient algorithm to manipulate objects /// of this type. @@ -660,6 +971,548 @@ void hashAppend(HASH_ALGORITHM& algorithm, const Uri& value) hashAppend(algorithm, value.fragment()); } +template +int UriParameter::manipulateAttributes(MANIPULATOR& manipulator) +{ + int rc; + + rc = this->manipulateAttribute(manipulator, e_ATTRIBUTE_ID_NAME); + if (rc != 0) { + return rc; + } + + rc = this->manipulateAttribute(manipulator, e_ATTRIBUTE_ID_VALUE); + if (rc != 0) { + return rc; + } + + return 0; +} + +template +int UriParameter::manipulateAttribute(MANIPULATOR& manipulator, int id) +{ + int rc; + + if (id == e_ATTRIBUTE_ID_NAME) { + rc = manipulator(&d_name, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_VALUE) { + rc = manipulator(&d_value, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else { + return -1; + } + + return 0; +} + +template +int UriParameter::manipulateAttribute(MANIPULATOR& manipulator, + const char* name, + int nameLength) +{ + const bdlat_AttributeInfo* info = + ntsa::UriParameter::lookupAttributeInfo(name, nameLength); + if (info == 0) { + return -1; + } + + return this->manipulateAttribute(manipulator, info->d_id); +} + +template +int UriParameter::accessAttributes(ACCESSOR& accessor) const +{ + int rc; + + rc = this->accessAttribute(accessor, e_ATTRIBUTE_ID_NAME); + if (rc != 0) { + return rc; + } + + rc = this->accessAttribute(accessor, e_ATTRIBUTE_ID_VALUE); + if (rc != 0) { + return rc; + } + + return 0; +} + +template +int UriParameter::accessAttribute(ACCESSOR& accessor, int id) const +{ + int rc; + + if (id == e_ATTRIBUTE_ID_NAME) { + rc = accessor(d_name, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_VALUE) { + rc = accessor(d_value, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else { + return -1; + } + + return 0; +} + +template +int UriParameter::accessAttribute(ACCESSOR& accessor, + const char* name, + int nameLength) const +{ + const bdlat_AttributeInfo* info = + ntsa::UriParameter::lookupAttributeInfo(name, nameLength); + if (info == 0) { + return -1; + } + + return this->accessAttribute(accessor, info->d_id); +} + +template +int UriQuery::manipulateAttributes(MANIPULATOR& manipulator) +{ + int rc; + + rc = this->manipulateAttribute(manipulator, e_ATTRIBUTE_ID_PARAMETER); + if (rc != 0) { + return rc; + } + + return 0; +} + +template +int UriQuery::manipulateAttribute(MANIPULATOR& manipulator, int id) +{ + int rc; + + if (id == e_ATTRIBUTE_ID_PARAMETER) { + rc = manipulator(&d_parameterList, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else { + return -1; + } + + return 0; +} + +template +int UriQuery::manipulateAttribute(MANIPULATOR& manipulator, + const char* name, + int nameLength) +{ + const bdlat_AttributeInfo* info = + ntsa::UriQuery::lookupAttributeInfo(name, nameLength); + if (info == 0) { + return -1; + } + + return this->manipulateAttribute(manipulator, info->d_id); +} + +template +int UriQuery::accessAttributes(ACCESSOR& accessor) const +{ + int rc; + + rc = this->accessAttribute(accessor, e_ATTRIBUTE_ID_PARAMETER); + if (rc != 0) { + return rc; + } + + return 0; +} + +template +int UriQuery::accessAttribute(ACCESSOR& accessor, int id) const +{ + int rc; + + if (id == e_ATTRIBUTE_ID_PARAMETER) { + rc = accessor(d_parameterList, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else { + return -1; + } + + return 0; +} + +template +int UriQuery::accessAttribute(ACCESSOR& accessor, + const char* name, + int nameLength) const +{ + const bdlat_AttributeInfo* info = + ntsa::UriQuery::lookupAttributeInfo(name, nameLength); + if (info == 0) { + return -1; + } + + return this->accessAttribute(accessor, info->d_id); +} + +template +int UriAuthority::manipulateAttributes(MANIPULATOR& manipulator) +{ + int rc; + + rc = this->manipulateAttribute(manipulator, e_ATTRIBUTE_ID_USER); + if (rc != 0) { + return rc; + } + + rc = this->manipulateAttribute(manipulator, e_ATTRIBUTE_ID_HOST); + if (rc != 0) { + return rc; + } + + rc = this->manipulateAttribute(manipulator, e_ATTRIBUTE_ID_PORT); + if (rc != 0) { + return rc; + } + + rc = this->manipulateAttribute(manipulator, e_ATTRIBUTE_ID_TRANSPORT); + if (rc != 0) { + return rc; + } + + return 0; +} + +template +int UriAuthority::manipulateAttribute(MANIPULATOR& manipulator, int id) +{ + int rc; + + if (id == e_ATTRIBUTE_ID_USER) { + rc = manipulator(&d_user, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_HOST) { + rc = manipulator(&d_host, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_PORT) { + rc = manipulator(&d_port, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_TRANSPORT) { + rc = manipulator(&d_transport, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else { + return -1; + } + + return 0; +} + +template +int UriAuthority::manipulateAttribute(MANIPULATOR& manipulator, + const char* name, + int nameLength) +{ + const bdlat_AttributeInfo* info = + ntsa::UriAuthority::lookupAttributeInfo(name, nameLength); + if (info == 0) { + return -1; + } + + return this->manipulateAttribute(manipulator, info->d_id); +} + +template +int UriAuthority::accessAttributes(ACCESSOR& accessor) const +{ + int rc; + + rc = this->accessAttribute(accessor, e_ATTRIBUTE_ID_USER); + if (rc != 0) { + return rc; + } + + rc = this->accessAttribute(accessor, e_ATTRIBUTE_ID_HOST); + if (rc != 0) { + return rc; + } + + rc = this->accessAttribute(accessor, e_ATTRIBUTE_ID_PORT); + if (rc != 0) { + return rc; + } + + rc = this->accessAttribute(accessor, e_ATTRIBUTE_ID_TRANSPORT); + if (rc != 0) { + return rc; + } + + return 0; +} + +template +int UriAuthority::accessAttribute(ACCESSOR& accessor, int id) const +{ + int rc; + + if (id == e_ATTRIBUTE_ID_USER) { + rc = accessor(d_user, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_HOST) { + rc = accessor(d_host, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_PORT) { + rc = accessor(d_port, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_TRANSPORT) { + rc = accessor(d_transport, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else { + return -1; + } + + return 0; +} + +template +int UriAuthority::accessAttribute(ACCESSOR& accessor, + const char* name, + int nameLength) const +{ + const bdlat_AttributeInfo* info = + ntsa::UriAuthority::lookupAttributeInfo(name, nameLength); + if (info == 0) { + return -1; + } + + return this->accessAttribute(accessor, info->d_id); +} + +template +int Uri::manipulateAttributes(MANIPULATOR& manipulator) +{ + int rc; + + rc = this->manipulateAttribute(manipulator, e_ATTRIBUTE_ID_SCHEME); + if (rc != 0) { + return rc; + } + + rc = this->manipulateAttribute(manipulator, e_ATTRIBUTE_ID_AUTHORITY); + if (rc != 0) { + return rc; + } + + rc = this->manipulateAttribute(manipulator, e_ATTRIBUTE_ID_PATH); + if (rc != 0) { + return rc; + } + + rc = this->manipulateAttribute(manipulator, e_ATTRIBUTE_ID_QUERY); + if (rc != 0) { + return rc; + } + + rc = this->manipulateAttribute(manipulator, e_ATTRIBUTE_ID_FRAGMENT); + if (rc != 0) { + return rc; + } + + return 0; +} + +template +int Uri::manipulateAttribute(MANIPULATOR& manipulator, int id) +{ + int rc; + + if (id == e_ATTRIBUTE_ID_SCHEME) { + rc = manipulator(&d_scheme, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_AUTHORITY) { + rc = manipulator(&d_authority, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_PATH) { + rc = manipulator(&d_path, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_QUERY) { + rc = manipulator(&d_query, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_FRAGMENT) { + rc = manipulator(&d_fragment, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else { + return -1; + } + + return 0; +} + +template +int Uri::manipulateAttribute(MANIPULATOR& manipulator, + const char* name, + int nameLength) +{ + const bdlat_AttributeInfo* info = + ntsa::Uri::lookupAttributeInfo(name, nameLength); + if (info == 0) { + return -1; + } + + return this->manipulateAttribute(manipulator, info->d_id); +} + +template +int Uri::accessAttributes(ACCESSOR& accessor) const +{ + int rc; + + rc = this->accessAttribute(accessor, e_ATTRIBUTE_ID_SCHEME); + if (rc != 0) { + return rc; + } + + rc = this->accessAttribute(accessor, e_ATTRIBUTE_ID_AUTHORITY); + if (rc != 0) { + return rc; + } + + rc = this->accessAttribute(accessor, e_ATTRIBUTE_ID_PATH); + if (rc != 0) { + return rc; + } + + rc = this->accessAttribute(accessor, e_ATTRIBUTE_ID_QUERY); + if (rc != 0) { + return rc; + } + + rc = this->accessAttribute(accessor, e_ATTRIBUTE_ID_FRAGMENT); + if (rc != 0) { + return rc; + } + + return 0; +} + +template +int Uri::accessAttribute(ACCESSOR& accessor, int id) const +{ + int rc; + + if (id == e_ATTRIBUTE_ID_SCHEME) { + rc = accessor(d_scheme, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_AUTHORITY) { + rc = accessor(d_authority, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_PATH) { + rc = accessor(d_path, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_QUERY) { + rc = accessor(d_query, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else if (id == e_ATTRIBUTE_ID_FRAGMENT) { + rc = accessor(d_fragment, ATTRIBUTE_INFO_ARRAY[id]); + if (rc != 0) { + return rc; + } + } + else { + return -1; + } + + return 0; +} + +template +int Uri::accessAttribute(ACCESSOR& accessor, + const char* name, + int nameLength) const +{ + const bdlat_AttributeInfo* info = + ntsa::Uri::lookupAttributeInfo(name, nameLength); + if (info == 0) { + return -1; + } + + return this->accessAttribute(accessor, info->d_id); +} + } // close package namespace + +BDLAT_DECL_SEQUENCE_TRAITS(ntsa::UriAuthority) +BDLAT_DECL_SEQUENCE_TRAITS(ntsa::UriParameter) +BDLAT_DECL_SEQUENCE_TRAITS(ntsa::UriQuery) +BDLAT_DECL_SEQUENCE_TRAITS(ntsa::Uri) + } // close enterprise namespace #endif diff --git a/groups/nts/ntsa/ntsa_uri.t.cpp b/groups/nts/ntsa/ntsa_uri.t.cpp index 258839d6..c19e03f1 100644 --- a/groups/nts/ntsa/ntsa_uri.t.cpp +++ b/groups/nts/ntsa/ntsa_uri.t.cpp @@ -16,7 +16,12 @@ #include #include - +#include +#include +#include +#include +#include +#include #include #include #include @@ -807,10 +812,147 @@ NTSCFG_TEST_CASE(3) NTSCFG_TEST_ASSERT(ta.numBlocksInUse() == 0); } +NTSCFG_TEST_CASE(4) +{ + int rc; + + ntscfg::TestAllocator ta; + { + ntsa::Uri e1; + ntsa::Uri e2; + + bool valid = + e1.parse("http://10.26.55.100:12345/path/to/resource?foo=bar#baz"); + NTSCFG_TEST_TRUE(valid); + + bdlsb::MemOutStreamBuf osb(&ta); + + balber::BerEncoder encoder(0, &ta); + rc = encoder.encode(&osb, e1); + if (rc != 0) { + NTSCFG_TEST_LOG_DEBUG << encoder.loggedMessages() + << NTSCFG_TEST_LOG_END; + + NTSCFG_TEST_EQ(rc, 0); + } + + rc = osb.pubsync(); + NTSCFG_TEST_EQ(rc, 0); + + NTSCFG_TEST_GT(osb.length(), 0); + NTSCFG_TEST_NE(osb.data(), 0); + + NTSCFG_TEST_LOG_DEBUG << "Encoded:\n" + << bdlb::PrintStringHexDumper( + osb.data(), + static_cast(osb.length())) + << NTSCFG_TEST_LOG_END; + + bdlsb::FixedMemInStreamBuf isb(osb.data(), osb.length()); + + balber::BerDecoder decoder(0, &ta); + rc = decoder.decode(&isb, &e2); + if (rc != 0) { + NTSCFG_TEST_LOG_DEBUG << encoder.loggedMessages() + << NTSCFG_TEST_LOG_END; + + NTSCFG_TEST_EQ(rc, 0); + } + + NTSCFG_TEST_EQ(e2, e1); + } + NTSCFG_TEST_EQ(ta.numBlocksInUse(), 0); +} + +NTSCFG_TEST_CASE(5) +{ + int rc; + + ntscfg::TestAllocator ta; + { + bsl::vector e1(&ta); + bsl::vector e2(&ta); + + { + ntsa::Uri element; + + bool valid = element.parse( + "http://ntf.example.com:12345/path/to/resource?foo=bar#baz"); + NTSCFG_TEST_TRUE(valid); + + e1.push_back(element); + } + + { + ntsa::Uri element; + + bool valid = element.parse( + "http://10.26.55.100:12345/path/to/resource?foo=bar#baz"); + NTSCFG_TEST_TRUE(valid); + + e1.push_back(element); + } + + { + ntsa::Uri element; + + ntsa::LocalName localName; + localName.setValue("/tmp/ntf/socket"); + + element.setEndpoint(ntsa::Endpoint(localName)); + + e1.push_back(element); + } + + bdlsb::MemOutStreamBuf osb; + + baljsn::Encoder encoder(&ta); + rc = encoder.encode(&osb, e1); + if (rc != 0) { + NTSCFG_TEST_LOG_DEBUG << encoder.loggedMessages() + << NTSCFG_TEST_LOG_END; + + NTSCFG_TEST_EQ(rc, 0); + } + + rc = osb.pubsync(); + NTSCFG_TEST_EQ(rc, 0); + + NTSCFG_TEST_GT(osb.length(), 0); + NTSCFG_TEST_NE(osb.data(), 0); + + NTSCFG_TEST_LOG_DEBUG << "Encoded: " + << bsl::string_view( + osb.data(), + static_cast(osb.length())) + << NTSCFG_TEST_LOG_END; + + bdlsb::FixedMemInStreamBuf isb(osb.data(), osb.length()); + + baljsn::Decoder decoder(&ta); + rc = decoder.decode(&isb, &e2); + if (rc != 0) { + NTSCFG_TEST_LOG_DEBUG << encoder.loggedMessages() + << NTSCFG_TEST_LOG_END; + + NTSCFG_TEST_EQ(rc, 0); + } + + NTSCFG_TEST_EQ(e2.size(), e1.size()); + + for (bsl::size_t i = 0; i < e1.size(); ++i) { + NTSCFG_TEST_EQ(e2[i], e1[i]); + } + } + NTSCFG_TEST_EQ(ta.numBlocksInUse(), 0); +} + NTSCFG_TEST_DRIVER { NTSCFG_TEST_REGISTER(1); NTSCFG_TEST_REGISTER(2); NTSCFG_TEST_REGISTER(3); + NTSCFG_TEST_REGISTER(4); + NTSCFG_TEST_REGISTER(5); } NTSCFG_TEST_DRIVER_END;