// Copyright 2014 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include #include #include namespace brillo { // *************************************************************************** // ******************************* MIME types ******************************** // *************************************************************************** const char mime::types::kApplication[] = "application"; const char mime::types::kAudio[] = "audio"; const char mime::types::kImage[] = "image"; const char mime::types::kMessage[] = "message"; const char mime::types::kMultipart[] = "multipart"; const char mime::types::kText[] = "text"; const char mime::types::kVideo[] = "video"; const char mime::parameters::kCharset[] = "charset"; const char mime::image::kJpeg[] = "image/jpeg"; const char mime::image::kPng[] = "image/png"; const char mime::image::kBmp[] = "image/bmp"; const char mime::image::kTiff[] = "image/tiff"; const char mime::image::kGif[] = "image/gif"; const char mime::text::kPlain[] = "text/plain"; const char mime::text::kHtml[] = "text/html"; const char mime::text::kXml[] = "text/xml"; const char mime::application::kOctet_stream[] = "application/octet-stream"; const char mime::application::kJson[] = "application/json"; const char mime::application::kWwwFormUrlEncoded[] = "application/x-www-form-urlencoded"; const char mime::application::kProtobuf[] = "application/x-protobuf"; const char mime::multipart::kFormData[] = "multipart/form-data"; const char mime::multipart::kMixed[] = "multipart/mixed"; // *************************************************************************** // **************************** Utility Functions **************************** // *************************************************************************** static std::string EncodeParam(const std::string& param) { // If the string contains one of "tspecials" characters as // specified in RFC 1521, enclose it in quotes. if (param.find_first_of("()<>@,;:\\\"/[]?=") != std::string::npos) { return '"' + param + '"'; } return param; } static std::string DecodeParam(const std::string& param) { if (param.size() > 1 && param.front() == '"' && param.back() == '"') { return param.substr(1, param.size() - 2); } return param; } // *************************************************************************** // ******************** Main MIME manipulation functions ********************* // *************************************************************************** bool mime::Split(const std::string& mime_string, std::string* type, std::string* subtype, mime::Parameters* parameters) { std::vector parts = brillo::string_utils::Split(mime_string, ";"); if (parts.empty()) return false; if (!mime::Split(parts.front(), type, subtype)) return false; if (parameters) { parameters->clear(); parameters->reserve(parts.size() - 1); for (size_t i = 1; i < parts.size(); i++) { auto pair = brillo::string_utils::SplitAtFirst(parts[i], "="); pair.second = DecodeParam(pair.second); parameters->push_back(pair); } } return true; } bool mime::Split(const std::string& mime_string, std::string* type, std::string* subtype) { std::string mime = mime::RemoveParameters(mime_string); auto types = brillo::string_utils::SplitAtFirst(mime, "/"); if (type) *type = types.first; if (subtype) *subtype = types.second; return !types.first.empty() && !types.second.empty(); } std::string mime::Combine(const std::string& type, const std::string& subtype, const mime::Parameters& parameters) { std::vector parts; parts.push_back(brillo::string_utils::Join("/", type, subtype)); for (const auto& pair : parameters) { parts.push_back( brillo::string_utils::Join("=", pair.first, EncodeParam(pair.second))); } return brillo::string_utils::Join("; ", parts); } std::string mime::GetType(const std::string& mime_string) { std::string mime = mime::RemoveParameters(mime_string); return brillo::string_utils::SplitAtFirst(mime, "/").first; } std::string mime::GetSubtype(const std::string& mime_string) { std::string mime = mime::RemoveParameters(mime_string); return brillo::string_utils::SplitAtFirst(mime, "/").second; } mime::Parameters mime::GetParameters(const std::string& mime_string) { std::string type; std::string subtype; mime::Parameters parameters; if (mime::Split(mime_string, &type, &subtype, ¶meters)) return parameters; return mime::Parameters(); } std::string mime::RemoveParameters(const std::string& mime_string) { return brillo::string_utils::SplitAtFirst(mime_string, ";").first; } std::string mime::AppendParameter(const std::string& mime_string, const std::string& paramName, const std::string& paramValue) { std::string mime(mime_string); mime += "; "; mime += brillo::string_utils::Join("=", paramName, EncodeParam(paramValue)); return mime; } std::string mime::GetParameterValue(const std::string& mime_string, const std::string& paramName) { mime::Parameters params = mime::GetParameters(mime_string); for (const auto& pair : params) { if (base::EqualsCaseInsensitiveASCII(pair.first.c_str(), paramName.c_str())) return pair.second; } return std::string(); } } // namespace brillo