static void parseHostStrings( JSON::Entity const &entity, HostStrings &result ) { if ( entity.isString() ) { HostSpec hostSpec; hostSpec.push_back( "*" ); result.insert( HostStrings::value_type( entity.stringToStdString(), hostSpec ) ); } else if ( entity.isObject() ) { JSON::ObjectDecoder objectDecoder( entity ); JSON::Entity keyString, valueEntity; while ( objectDecoder.getNext( keyString, valueEntity ) ) { try { HostSpec hostSpec = parseHostSpec( valueEntity ); result.insert( HostStrings::value_type( keyString.stringToStdString(), hostSpec ) ); } catch ( Exception e ) { objectDecoder.rethrow( e ); } } } else throw Exception( "must be a string or an object" ); }
/* * Finally, bring it all together to handle parsing full connection URLs: * * pcp://oss.sgi.com:45892?user=otto&pass=blotto&compress=true * pcps://[email protected]:45893?user=jimbo&pass=jones&compress=true * local://path/to/socket:?user=jimbo&pass=jones * unix://path/to/socket */ int __pmParseHostAttrsSpec( const char *spec, /* the original, complete string to parse */ pmHostSpec **host, /* hosts result allocated and returned here */ int *count, __pmHashCtl *attributes, char **errmsg) /* error message */ { char *value = NULL, *s = (char *)spec; int sts, attr; *count = 0; /* ensure this initialised for fail: code */ /* parse optional protocol section */ if ((sts = parseProtocolSpec(spec, &s, &attr, &value, errmsg)) < 0) return sts; if (attr == PCP_ATTR_LOCAL || attr == PCP_ATTR_UNIXSOCK) { /* We are looking for a socket path. */ if ((sts = parseSocketPath(spec, &s, host)) < 0) goto fail; *count = 1; host[0]->nports = (attr == PCP_ATTR_LOCAL) ? PM_HOST_SPEC_NPORTS_LOCAL : PM_HOST_SPEC_NPORTS_UNIX; } else { /* We are looking for a host spec. */ if ((sts = parseHostSpec(spec, &s, host, count, errmsg)) < 0) goto fail; } /* skip over an attributes delimiter */ if (*s == '?') { s++; /* optionally skip over the question mark */ } else if (*s != '\0' && *s != '/') { hostError(spec, s, "unexpected terminal character", errmsg); sts = PM_ERR_GENERIC; goto fail; } /* parse optional attributes section */ if ((sts = parseAttributeSpec(spec, &s, attr, value, attributes, errmsg)) < 0) goto fail; return 0; fail: if (value) free(value); if (*count) __pmFreeHostSpec(*host, *count); *count = 0; *host = NULL; return sts; }
int __pmParseHostSpec( const char *spec, /* parse this string */ pmHostSpec **rslt, /* result allocated and returned here */ int *count, /* number of host specs returned here */ char **errmsg) /* error message */ { char *s = (char *)spec; int sts; if ((sts = parseHostSpec(spec, &s, rslt, count, errmsg)) < 0) return sts; if (*s == '\0') return 0; hostError(spec, s, "unexpected terminal character", errmsg); __pmFreeHostSpec(*rslt, *count); *rslt = NULL; *count = 0; return PM_ERR_GENERIC; }