X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Frgw%2Frgw_formats.cc;fp=src%2Fceph%2Fsrc%2Frgw%2Frgw_formats.cc;h=8a84083c75704baff6db6c1c7b48ee1a3e72aa7a;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/rgw/rgw_formats.cc b/src/ceph/src/rgw/rgw_formats.cc new file mode 100644 index 0000000..8a84083 --- /dev/null +++ b/src/ceph/src/rgw/rgw_formats.cc @@ -0,0 +1,370 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include + +#include "common/escape.h" +#include "common/Formatter.h" +#include "rgw/rgw_common.h" +#include "rgw/rgw_formats.h" +#include "rgw/rgw_rest.h" + +#define LARGE_SIZE 8192 + +#define dout_subsys ceph_subsys_rgw + +RGWFormatter_Plain::RGWFormatter_Plain(const bool ukv) + : use_kv(ukv) +{ +} + +RGWFormatter_Plain::~RGWFormatter_Plain() +{ + free(buf); +} + +void RGWFormatter_Plain::flush(ostream& os) +{ + if (!buf) + return; + + if (len) { + os << buf; + os.flush(); + } + + reset_buf(); +} + +void RGWFormatter_Plain::reset_buf() +{ + free(buf); + buf = NULL; + len = 0; + max_len = 0; +} + +void RGWFormatter_Plain::reset() +{ + reset_buf(); + stack.clear(); + min_stack_level = 0; +} + +void RGWFormatter_Plain::open_array_section(const char *name) +{ + struct plain_stack_entry new_entry; + new_entry.is_array = true; + new_entry.size = 0; + + if (use_kv && min_stack_level > 0 && !stack.empty()) { + struct plain_stack_entry& entry = stack.back(); + + if (!entry.is_array) + dump_format(name, ""); + } + + stack.push_back(new_entry); +} + +void RGWFormatter_Plain::open_array_section_in_ns(const char *name, const char *ns) +{ + ostringstream oss; + oss << name << " " << ns; + open_array_section(oss.str().c_str()); +} + +void RGWFormatter_Plain::open_object_section(const char *name) +{ + struct plain_stack_entry new_entry; + new_entry.is_array = false; + new_entry.size = 0; + + if (use_kv && min_stack_level > 0) + dump_format(name, ""); + + stack.push_back(new_entry); +} + +void RGWFormatter_Plain::open_object_section_in_ns(const char *name, + const char *ns) +{ + ostringstream oss; + oss << name << " " << ns; + open_object_section(oss.str().c_str()); +} + +void RGWFormatter_Plain::close_section() +{ + stack.pop_back(); +} + +void RGWFormatter_Plain::dump_unsigned(const char *name, uint64_t u) +{ + dump_value_int(name, "%" PRIu64, u); +} + +void RGWFormatter_Plain::dump_int(const char *name, int64_t u) +{ + dump_value_int(name, "%" PRId64, u); +} + +void RGWFormatter_Plain::dump_float(const char *name, double d) +{ + dump_value_int(name, "%f", d); +} + +void RGWFormatter_Plain::dump_string(const char *name, const std::string& s) +{ + dump_format(name, "%s", s.c_str()); +} + +std::ostream& RGWFormatter_Plain::dump_stream(const char *name) +{ + // TODO: implement this! + ceph_abort(); +} + +void RGWFormatter_Plain::dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) +{ + char buf[LARGE_SIZE]; + + struct plain_stack_entry& entry = stack.back(); + + if (!min_stack_level) + min_stack_level = stack.size(); + + bool should_print = ((stack.size() == min_stack_level && !entry.size) || use_kv); + + entry.size++; + + if (!should_print) + return; + + vsnprintf(buf, LARGE_SIZE, fmt, ap); + + const char *eol; + if (wrote_something) { + if (use_kv && entry.is_array && entry.size > 1) + eol = ", "; + else + eol = "\n"; + } else + eol = ""; + wrote_something = true; + + if (use_kv && !entry.is_array) + write_data("%s%s: %s", eol, name, buf); + else + write_data("%s%s", eol, buf); +} + +int RGWFormatter_Plain::get_len() const +{ + // don't include null termination in length + return (len ? len - 1 : 0); +} + +void RGWFormatter_Plain::write_raw_data(const char *data) +{ + write_data("%s", data); +} + +void RGWFormatter_Plain::write_data(const char *fmt, ...) +{ +#define LARGE_ENOUGH_LEN 128 + int n, size = LARGE_ENOUGH_LEN; + char s[size + 8]; + char *p, *np; + bool p_on_stack; + va_list ap; + int pos; + + p = s; + p_on_stack = true; + + while (1) { + va_start(ap, fmt); + n = vsnprintf(p, size, fmt, ap); + va_end(ap); + + if (n > -1 && n < size) + goto done; + /* Else try again with more space. */ + if (n > -1) /* glibc 2.1 */ + size = n+1; /* precisely what is needed */ + else /* glibc 2.0 */ + size *= 2; /* twice the old size */ + if (p_on_stack) + np = (char *)malloc(size + 8); + else + np = (char *)realloc(p, size + 8); + if (!np) + goto done_free; + p = np; + p_on_stack = false; + } +done: +#define LARGE_ENOUGH_BUF 4096 + if (!buf) { + max_len = max(LARGE_ENOUGH_BUF, size); + buf = (char *)malloc(max_len); + if (!buf) { + cerr << "ERROR: RGWFormatter_Plain::write_data: failed allocating " << max_len << " bytes" << std::endl; + goto done_free; + } + } + + if (len + size > max_len) { + max_len = len + size + LARGE_ENOUGH_BUF; + void *_realloc = NULL; + if ((_realloc = realloc(buf, max_len)) == NULL) { + cerr << "ERROR: RGWFormatter_Plain::write_data: failed allocating " << max_len << " bytes" << std::endl; + goto done_free; + } else { + buf = (char *)_realloc; + } + } + + pos = len; + if (len) + pos--; // squash null termination + strcpy(buf + pos, p); + len = pos + strlen(p) + 1; +done_free: + if (!p_on_stack) + free(p); +} + +void RGWFormatter_Plain::dump_value_int(const char *name, const char *fmt, ...) +{ + char buf[LARGE_SIZE]; + va_list ap; + + if (!min_stack_level) + min_stack_level = stack.size(); + + struct plain_stack_entry& entry = stack.back(); + bool should_print = ((stack.size() == min_stack_level && !entry.size) || use_kv); + + entry.size++; + + if (!should_print) + return; + + va_start(ap, fmt); + vsnprintf(buf, LARGE_SIZE, fmt, ap); + va_end(ap); + + const char *eol; + if (wrote_something) { + eol = "\n"; + } else + eol = ""; + wrote_something = true; + + if (use_kv && !entry.is_array) + write_data("%s%s: %s", eol, name, buf); + else + write_data("%s%s", eol, buf); + +} + + +/* An utility class that serves as a mean to access the protected static + * methods of XMLFormatter. */ +class HTMLHelper : public XMLFormatter { +public: + static std::string escape(const std::string& unescaped_str) { + return escape_xml_str(unescaped_str.c_str()); + } +}; + +void RGWSwiftWebsiteListingFormatter::generate_header( + const std::string& dir_path, + const std::string& css_path) +{ + ss << R"()"; + + ss << "Listing of " << HTMLHelper::escape(dir_path) + << ""; + + if (! css_path.empty()) { + ss << boost::format(R"()") + % url_encode(css_path); + } else { + ss << R"()"; + } + + ss << ""; + + ss << R"(

Listing of )" << HTMLHelper::escape(dir_path) << "

" + << R"()" + << R"()" + << R"()" + << R"()" + << R"()" + << R"()"; + + if (! prefix.empty()) { + ss << R"()" + << R"()" + << R"()" + << R"()" + << R"()"; + } +} + +void RGWSwiftWebsiteListingFormatter::generate_footer() +{ + ss << R"(
NameSizeDate
../  
)"; +} + +std::string RGWSwiftWebsiteListingFormatter::format_name( + const std::string& item_name) const +{ + return item_name.substr(prefix.length()); +} + +void RGWSwiftWebsiteListingFormatter::dump_object(const rgw_bucket_dir_entry& objent) +{ + const auto name = format_name(objent.key.name); + ss << boost::format(R"()") + % "default" + << boost::format(R"(%s)") + % url_encode(name) + % HTMLHelper::escape(name) + << boost::format(R"(%lld)") % objent.meta.size + << boost::format(R"(%s)") + % dump_time_to_str(objent.meta.mtime) + << R"()"; +} + +void RGWSwiftWebsiteListingFormatter::dump_subdir(const std::string& name) +{ + const auto fname = format_name(name); + ss << R"()" + << boost::format(R"(%s)") + % url_encode(fname) + % HTMLHelper::escape(fname) + << R"( )" + << R"( )" + << R"()"; +}