in edge-hub/core/src/Microsoft.Azure.Devices.Edge.Hub.Mqtt/TwinAddressHelper.cs [65:146]
public static bool TryParseOperation(string address, Dictionary<StringSegment, StringSegment> properties, out Operation operation, out StringSegment resource)
{
Preconditions.CheckArgument(CheckTwinAddress(address));
int offset = ServicePrefix.Length;
if ((address.Length > TwinPrefix.Length)
&& (string.CompareOrdinal(address, offset, TwinChannelSegment, 0, TwinChannelSegment.Length) == 0))
{
offset += TwinChannelSegment.Length;
const string PatchReportedSegments = PatchMethod + SegmentSeparator + TwinNames.Properties + SegmentSeparator + TwinNames.Reported + SegmentSeparator;
const string GetSegment = GetMethod + SegmentSeparator;
if (string.CompareOrdinal(address, offset, PatchReportedSegments, 0, PatchReportedSegments.Length) == 0)
{
operation = Operation.TwinPatchReportedState;
offset += PatchReportedSegments.Length;
}
else if (string.CompareOrdinal(address, offset, GetSegment, 0, GetSegment.Length) == 0)
{
operation = Operation.TwinGetState;
offset += GetSegment.Length;
}
else
{
operation = Operation.InvalidTwinRequest;
resource = default(StringSegment);
return false;
}
}
else if ((address.Length > DirectMethodPrefix.Length)
&& (string.CompareOrdinal(address, offset, DirectMethodResponseSegments, 0, DirectMethodResponseSegments.Length) == 0))
{
operation = Operation.DirectMethodResponse;
offset += DirectMethodResponseSegments.Length;
}
else
{
operation = Operation.Unknown;
resource = default(StringSegment);
return false;
}
if (offset == address.Length)
{
resource = EmptyStringSegment;
return true;
}
if (address[offset] == PropertiesSegmentPrefixChar) // check if property bag follows parsed part immediately
{
resource = EmptyStringSegment;
offset++;
}
else
{
// find the final segment to derive
int lastSegmentSeparatorIndex = address.LastIndexOf(SegmentSeparatorChar, address.Length - 1, address.Length - offset); // todo: check for off by 1
if ((lastSegmentSeparatorIndex == -1) // no more segments
|| (lastSegmentSeparatorIndex == address.Length - 1) // no more non-empty segments
|| (address[lastSegmentSeparatorIndex + 1] != PropertiesSegmentPrefixChar)) // last segment is not a property bag
{
// declare the rest of the address as resource
resource = StringSegmentAtOffset(address, offset);
return true;
}
else
{
resource = StringSegmentRange(address, offset, lastSegmentSeparatorIndex - 1);
offset = lastSegmentSeparatorIndex + 2;
}
}
// property bag follows last separator
if (!TryParseProperties(address, offset, properties))
{
return false;
}
return true;
}