#include <memory>
#include <sstream>
#include <utility>
#include "base/include/log/logging.h"
#include "base/include/sorted_for_each.h"
#include "base/include/value/array.h"
#include "base/include/value/base_value.h"
#include "base/include/value/lynx_value_extended.h"
#include "base/include/value/table.h"
namespace lynx {
namespace lepus {
void Value::Print() const {
std::ostringstream s;
PrintValue(s);
LOGE(s.str() << std::endl);
}
void Value::PrintValue(std::ostream& output, bool ignore_other, bool pretty,
bool sort_map_key) const {
if (IsJSValue()) {
lynx_value_print_ext(env_, value_, &output, nullptr);
return;
}
int64_t i64;
uint64_t u64;
switch (value_.type) {
case lynx_value_null:
if (!ignore_other) {
output << "null";
}
break;
case lynx_value_undefined:
if (!ignore_other) {
output << "undefined";
}
break;
case lynx_value_double:
output << base::StringConvertHelper::DoubleToString(Number());
break;
case lynx_value_int32:
i64 = Int32();
goto write_i64;
case lynx_value_int64:
i64 = Int64();
write_i64:
output << i64;
break;
case lynx_value_uint32:
u64 = UInt32();
goto write_u64;
case lynx_value_uint64:
u64 = UInt64();
write_u64:
output << u64;
break;
case lynx_value_bool:
output << (Bool() ? "true" : "false");
break;
case lynx_value_string:
if (pretty) {
output << "\"" << CString() << "\"";
} else {
output << CString();
}
break;
case lynx_value_map: {
auto table = Table();
output << "{";
bool first = true;
auto print_each = [&](const auto& it) {
if (!first) {
output << ",";
}
if (pretty) {
output << "\"" << it.first.str() << "\"";
} else {
output << it.first.str();
}
output << ":";
it.second.PrintValue(output, ignore_other, pretty, sort_map_key);
first = false;
};
if (sort_map_key) {
base::sorted_for_each(
table->begin(), table->end(),
[&](const auto& it) { print_each(it); },
[](const auto& left, const auto& right) {
return left.first.str() < right.first.str();
});
} else {
for (const auto& it : *table) {
print_each(it);
}
}
output << "}";
break;
}
case lynx_value_array: {
auto array = Array();
output << "[";
for (size_t i = 0; i < array->size(); i++) {
array->get(i).PrintValue(output, ignore_other, pretty, sort_map_key);
if (i != (array->size() - 1)) {
output << ",";
}
}
output << "]";
break;
}
case lynx_value_function:
case lynx_value_external:
if (!ignore_other) {
output << "closure/cfunction/cpointer/refcounted" << std::endl;
}
break;
case lynx_value_object: {
RefType ref_type = static_cast<RefType>(value_.tag);
switch (ref_type) {
case RefType::kJSIObject:
if (!ignore_other) {
RefCounted()->Print(output);
}
break;
#if !ENABLE_JUST_LEPUSNG
case RefType::kClosure:
if (!ignore_other) {
output << "closure/cfunction/cpointer/refcounted" << std::endl;
}
break;
case RefType::kCDate:
if (!ignore_other) {
RefCounted()->Print(output);
}
break;
case RefType::kRegExp: {
RefCounted()->Print(output);
} break;
#endif
default:
if (!ignore_other) {
output << "closure/cfunction/cpointer/refcounted" << std::endl;
}
break;
}
} break;
case lynx_value_nan:
if (!ignore_other) {
output << "NaN";
}
break;
case lynx_value_arraybuffer:
if (!ignore_other) {
output << "ByteArray";
}
break;
default:
if (!ignore_other) {
output << "unknow type";
}
break;
}
}
}
}