util.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #ifndef LIB_COMMON_UTIL_H_
  19. #define LIB_COMMON_UTIL_H_
  20. #include "hdfspp/status.h"
  21. #include <sstream>
  22. #include <mutex>
  23. #include <string>
  24. #include <asio/error_code.hpp>
  25. #include <openssl/rand.h>
  26. #include <google/protobuf/message_lite.h>
  27. #include <google/protobuf/io/coded_stream.h>
  28. #include <asio.hpp>
  29. namespace hdfs {
  30. // typedefs based on code that's repeated everywhere
  31. typedef std::lock_guard<std::mutex> mutex_guard;
  32. static inline Status ToStatus(const ::asio::error_code &ec) {
  33. if (ec) {
  34. return Status(ec.value(), ec.message().c_str());
  35. } else {
  36. return Status::OK();
  37. }
  38. }
  39. // Determine size of buffer that needs to be allocated in order to serialize msg
  40. // in delimited format
  41. static inline int DelimitedPBMessageSize(const ::google::protobuf::MessageLite *msg) {
  42. size_t size = msg->ByteSize();
  43. return ::google::protobuf::io::CodedOutputStream::VarintSize32(size) + size;
  44. }
  45. // Construct msg from the input held in the CodedInputStream
  46. // return false on failure, otherwise return true
  47. bool ReadDelimitedPBMessage(::google::protobuf::io::CodedInputStream *in,
  48. ::google::protobuf::MessageLite *msg);
  49. // Serialize msg into a delimited form (java protobuf compatible)
  50. // err, if not null, will be set to false on failure
  51. std::string SerializeDelimitedProtobufMessage(const ::google::protobuf::MessageLite *msg,
  52. bool *err);
  53. std::string Base64Encode(const std::string &src);
  54. // Return a new high-entropy client name
  55. std::string GetRandomClientName();
  56. // Returns true if _someone_ is holding the lock (not necessarily this thread,
  57. // but a std::mutex doesn't track which thread is holding the lock)
  58. template<class T>
  59. bool lock_held(T & mutex) {
  60. bool result = !mutex.try_lock();
  61. if (!result)
  62. mutex.unlock();
  63. return result;
  64. }
  65. // Shutdown and close a socket safely; will check if the socket is open and
  66. // catch anything thrown by asio.
  67. // Returns a string containing error message on failure, otherwise an empty string.
  68. std::string SafeDisconnect(asio::ip::tcp::socket *sock);
  69. // The following helper function is used for classes that look like the following:
  70. //
  71. // template <typename socket_like_object>
  72. // class ObjectThatHoldsSocket {
  73. // socket_like_object sock_;
  74. // void DoSomethingWithAsioTcpSocket();
  75. // }
  76. //
  77. // The trick here is that ObjectThatHoldsSocket may be templated on a mock socket
  78. // in mock tests. If you have a method that explicitly needs to call some asio
  79. // method unrelated to the mock test you need a way of making sure socket_like_object
  80. // is, in fact, an asio::ip::tcp::socket. Otherwise the mocks need to implement
  81. // lots of no-op boilerplate. This will return the value of the input param if
  82. // it's a asio socket, and nullptr if it's anything else.
  83. template <typename sock_t>
  84. inline asio::ip::tcp::socket *get_asio_socket_ptr(sock_t *s) {
  85. (void)s;
  86. return nullptr;
  87. }
  88. template<>
  89. inline asio::ip::tcp::socket *get_asio_socket_ptr<asio::ip::tcp::socket>
  90. (asio::ip::tcp::socket *s) {
  91. return s;
  92. }
  93. }
  94. #endif