Response BlobContainerClient::FindBlobsByTags()

in sdk/storage/azure-storage-blobs/src/rest_client.cpp [1848:1996]


    Response<Models::_detail::FindBlobsByTagsResult> BlobContainerClient::FindBlobsByTags(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const FindBlobContainerBlobsByTagsOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("restype", "container");
      request.GetUrl().AppendQueryParameter("comp", "blobs");
      request.SetHeader("x-ms-version", "2024-08-04");
      if (options.Where.HasValue() && !options.Where.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "where", _internal::UrlEncodeQueryParameter(options.Where.Value()));
      }
      if (options.Marker.HasValue() && !options.Marker.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "marker", _internal::UrlEncodeQueryParameter(options.Marker.Value()));
      }
      if (options.MaxResults.HasValue())
      {
        request.GetUrl().AppendQueryParameter(
            "maxresults", std::to_string(options.MaxResults.Value()));
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::FindBlobsByTagsResult response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kEnumerationResults,
          kBlobs,
          kBlob,
          kName,
          kContainerName,
          kTags,
          kTagSet,
          kTag,
          kKey,
          kValue,
          kNextMarker,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"EnumerationResults", XmlTagEnum::kEnumerationResults},
            {"Blobs", XmlTagEnum::kBlobs},
            {"Blob", XmlTagEnum::kBlob},
            {"Name", XmlTagEnum::kName},
            {"ContainerName", XmlTagEnum::kContainerName},
            {"Tags", XmlTagEnum::kTags},
            {"TagSet", XmlTagEnum::kTagSet},
            {"Tag", XmlTagEnum::kTag},
            {"Key", XmlTagEnum::kKey},
            {"Value", XmlTagEnum::kValue},
            {"NextMarker", XmlTagEnum::kNextMarker},
        };
        std::vector<XmlTagEnum> xmlPath;
        Models::TaggedBlobItem vectorElement1;
        std::string mapKey2;
        std::string mapValue3;
        while (true)
        {
          auto node = reader.Read();
          if (node.Type == _internal::XmlNodeType::End)
          {
            break;
          }
          else if (node.Type == _internal::XmlNodeType::StartTag)
          {
            auto ite = XmlTagEnumMap.find(node.Name);
            xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown : ite->second);
          }
          else if (node.Type == _internal::XmlNodeType::Text)
          {
            if (xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kBlobs && xmlPath[2] == XmlTagEnum::kBlob
                && xmlPath[3] == XmlTagEnum::kName)
            {
              vectorElement1.BlobName = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kBlobs && xmlPath[2] == XmlTagEnum::kBlob
                && xmlPath[3] == XmlTagEnum::kContainerName)
            {
              vectorElement1.BlobContainerName = node.Value;
            }
            else if (
                xmlPath.size() == 7 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kBlobs && xmlPath[2] == XmlTagEnum::kBlob
                && xmlPath[3] == XmlTagEnum::kTags && xmlPath[4] == XmlTagEnum::kTagSet
                && xmlPath[5] == XmlTagEnum::kTag && xmlPath[6] == XmlTagEnum::kKey)
            {
              mapKey2 = node.Value;
            }
            else if (
                xmlPath.size() == 7 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kBlobs && xmlPath[2] == XmlTagEnum::kBlob
                && xmlPath[3] == XmlTagEnum::kTags && xmlPath[4] == XmlTagEnum::kTagSet
                && xmlPath[5] == XmlTagEnum::kTag && xmlPath[6] == XmlTagEnum::kValue)
            {
              mapValue3 = node.Value;
            }
            else if (
                xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kNextMarker)
            {
              response.ContinuationToken = node.Value;
            }
          }
          else if (node.Type == _internal::XmlNodeType::Attribute)
          {
            if (xmlPath.size() == 1 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && node.Name == "ServiceEndpoint")
            {
              response.ServiceEndpoint = node.Value;
            }
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {
            if (xmlPath.size() == 7 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kBlobs && xmlPath[2] == XmlTagEnum::kBlob
                && xmlPath[3] == XmlTagEnum::kTags && xmlPath[4] == XmlTagEnum::kTagSet
                && xmlPath[5] == XmlTagEnum::kTag && xmlPath[6] == XmlTagEnum::kValue)
            {
              vectorElement1.Tags[std::move(mapKey2)] = std::move(mapValue3);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kBlobs && xmlPath[2] == XmlTagEnum::kBlob)
            {
              response.Items.push_back(std::move(vectorElement1));
              vectorElement1 = Models::TaggedBlobItem();
            }
            xmlPath.pop_back();
          }
        }
      }
      return Response<Models::_detail::FindBlobsByTagsResult>(
          std::move(response), std::move(pRawResponse));
    }