| 2588 | /************************************************************************/ |
| 2589 | |
| 2590 | bool VSIS3FSHandler::SetFileMetadata(const char *pszFilename, |
| 2591 | CSLConstList papszMetadata, |
| 2592 | const char *pszDomain, |
| 2593 | CSLConstList /* papszOptions */) |
| 2594 | { |
| 2595 | if (!STARTS_WITH_CI(pszFilename, GetFSPrefix().c_str())) |
| 2596 | return false; |
| 2597 | |
| 2598 | CPLString osFilename(pszFilename); |
| 2599 | NormalizeFilenameIfNeeded(osFilename); |
| 2600 | if (!STARTS_WITH_CI(osFilename.c_str(), GetFSPrefix().c_str())) |
| 2601 | { |
| 2602 | CPLError(CE_Failure, CPLE_AppDefined, "Invalid filename '%s'", |
| 2603 | pszFilename); |
| 2604 | return false; |
| 2605 | } |
| 2606 | |
| 2607 | if (pszDomain == nullptr || |
| 2608 | !(EQUAL(pszDomain, "HEADERS") || EQUAL(pszDomain, "TAGS"))) |
| 2609 | { |
| 2610 | CPLError(CE_Failure, CPLE_NotSupported, |
| 2611 | "Only HEADERS and TAGS domain are supported"); |
| 2612 | return false; |
| 2613 | } |
| 2614 | |
| 2615 | if (EQUAL(pszDomain, "HEADERS")) |
| 2616 | { |
| 2617 | return CopyObject(osFilename, osFilename, papszMetadata) == 0; |
| 2618 | } |
| 2619 | |
| 2620 | auto poS3HandleHelper = |
| 2621 | std::unique_ptr<VSIS3HandleHelper>(VSIS3HandleHelper::BuildFromURI( |
| 2622 | osFilename.c_str() + GetFSPrefix().size(), GetFSPrefix().c_str(), |
| 2623 | false)); |
| 2624 | if (!poS3HandleHelper) |
| 2625 | return false; |
| 2626 | |
| 2627 | NetworkStatisticsFileSystem oContextFS(GetFSPrefix().c_str()); |
| 2628 | NetworkStatisticsAction oContextAction("SetFileMetadata"); |
| 2629 | |
| 2630 | // Compose XML post content |
| 2631 | std::string osXML; |
| 2632 | if (papszMetadata != nullptr && papszMetadata[0] != nullptr) |
| 2633 | { |
| 2634 | CPLXMLNode *psXML = CPLCreateXMLNode(nullptr, CXT_Element, "?xml"); |
| 2635 | CPLAddXMLAttributeAndValue(psXML, "version", "1.0"); |
| 2636 | CPLAddXMLAttributeAndValue(psXML, "encoding", "UTF-8"); |
| 2637 | CPLXMLNode *psTagging = |
| 2638 | CPLCreateXMLNode(nullptr, CXT_Element, "Tagging"); |
| 2639 | psXML->psNext = psTagging; |
| 2640 | CPLAddXMLAttributeAndValue(psTagging, "xmlns", |
| 2641 | "http://s3.amazonaws.com/doc/2006-03-01/"); |
| 2642 | CPLXMLNode *psTagSet = |
| 2643 | CPLCreateXMLNode(psTagging, CXT_Element, "TagSet"); |
| 2644 | for (int i = 0; papszMetadata[i]; ++i) |
| 2645 | { |
| 2646 | char *pszKey = nullptr; |
| 2647 | const char *pszValue = CPLParseNameValue(papszMetadata[i], &pszKey); |
nothing calls this directly
no test coverage detected