yql_structured_token.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include "yql_structured_token.h"
  2. #include <yql/essentials/utils/utf8.h>
  3. #include <library/cpp/json/json_reader.h>
  4. #include <library/cpp/json/json_writer.h>
  5. #include <library/cpp/string_utils/base64/base64.h>
  6. namespace NYql {
  7. TStructuredToken::TStructuredToken(TMap<TString, TString>&& data)
  8. : Data(std::move(data)) {
  9. }
  10. TString TStructuredToken::GetField(const TString& name) const {
  11. return Data.at(name);
  12. }
  13. TString TStructuredToken::GetFieldOrDefault(const TString& name, const TString& defaultValue) const {
  14. return FindField(name).GetOrElse(defaultValue);
  15. }
  16. TMaybe<TString> TStructuredToken::FindField(const TString& name) const {
  17. auto* r = Data.FindPtr(name);
  18. return r ? MakeMaybe(*r) : Nothing();
  19. }
  20. bool TStructuredToken::HasField(const TString& name) const {
  21. return Data.contains(name);
  22. }
  23. TStructuredToken& TStructuredToken::SetField(const TString& name, const TString& value) {
  24. Data[name] = value;
  25. return *this;
  26. }
  27. TStructuredToken& TStructuredToken::ClearField(const TString& name) {
  28. Data.erase(name);
  29. return *this;
  30. }
  31. TString TStructuredToken::ToJson() const {
  32. TStringStream output;
  33. // set "format output" to false, no need for extra indents
  34. // "sort keys" value is not used actually
  35. // turn on UTF8 validation (need for keys checks)
  36. NJson::TJsonWriter writer(&output, false, true, true);
  37. writer.OpenMap();
  38. for (auto&[k, v] : Data) {
  39. if (!IsUtf8(v)) {
  40. writer.Write(k + "(base64)", Base64Encode(TStringBuf(v)));
  41. } else {
  42. writer.Write(k, v);
  43. }
  44. }
  45. writer.CloseMap();
  46. writer.Flush();
  47. return output.Str();
  48. }
  49. TStructuredToken ParseStructuredToken(const TString& content) {
  50. Y_ABORT_UNLESS(IsStructuredTokenJson(content));
  51. NJson::TJsonValue v;
  52. // will throw on error
  53. NJson::ReadJsonTree(content, &v, true);
  54. TMap<TString, TString> data;
  55. const auto& m = v.GetMapSafe();
  56. for (auto&[k, v] : m) {
  57. TStringBuf key(k);
  58. if (key.ChopSuffix("(base64)")) {
  59. const auto& s = v.GetStringSafe();
  60. data[TString(key)] = Base64Decode(TStringBuf(s));
  61. } else {
  62. data[k] = v.GetStringSafe();
  63. }
  64. }
  65. return TStructuredToken(std::move(data));
  66. }
  67. bool IsStructuredTokenJson(const TString& content) {
  68. return content.StartsWith("{") && content.EndsWith("}");
  69. }
  70. } // namespace NYql