You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

json_helper.h 9.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /**
  2. * Copyright 2019-2021 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_JSON_DATA_HELPER_H_
  17. #define MINDSPORE_CCSRC_MINDDATA_DATASET_JSON_DATA_HELPER_H_
  18. #include <fstream>
  19. #include <iostream>
  20. #include <map>
  21. #include <memory>
  22. #include <sstream>
  23. #include <string>
  24. #include <unordered_map>
  25. #include <vector>
  26. #include <nlohmann/json.hpp>
  27. #include "./securec.h"
  28. #include "minddata/dataset/util/log_adapter.h"
  29. #include "minddata/dataset/util/path.h"
  30. #include "minddata/dataset/util/status.h"
  31. namespace mindspore {
  32. namespace dataset {
  33. /// \brief Simple class to do data manipulation, contains helper function to update json files in dataset
  34. class JsonHelper {
  35. public:
  36. /// \brief constructor
  37. JsonHelper() {}
  38. /// \brief Destructor
  39. ~JsonHelper() = default;
  40. /// \brief Create an Album dataset while taking in a path to a image folder
  41. /// Creates the output directory if doesn't exist
  42. /// \param[in] in_dir Image folder directory that takes in images
  43. /// \param[in] out_dir Directory containing output json files
  44. Status CreateAlbum(const std::string &in_dir, const std::string &out_dir);
  45. /// \brief Update a json file field with a vector of integers
  46. /// \param in_file The input file name to read in
  47. /// \param key Key of field to write to
  48. /// \param value Value array to write to file
  49. /// \param out_file Optional input for output file path, will write to input file if not specified
  50. /// \return Status The status code returned
  51. Status UpdateArray(const std::string &in_file, const std::string &key, const std::vector<std::string> &value,
  52. const std::string &out_file = "");
  53. /// \brief Update a json file field with a vector of type T values
  54. /// \param in_file The input file name to read in
  55. /// \param key Key of field to write to
  56. /// \param value Value array to write to file
  57. /// \param out_file Optional parameter for output file path, will write to input file if not specified
  58. /// \return Status The status code returned
  59. template <typename T>
  60. Status UpdateArray(const std::string &in_file, const std::string &key, const std::vector<T> &value,
  61. const std::string &out_file = "") {
  62. try {
  63. Path in = Path(in_file);
  64. nlohmann::json js;
  65. if (in.Exists()) {
  66. RETURN_IF_NOT_OK(RealPath(in_file));
  67. try {
  68. std::ifstream in_stream(in_file);
  69. MS_LOG(INFO) << "Filename: " << in_file << ".";
  70. in_stream >> js;
  71. in_stream.close();
  72. } catch (const std::exception &err) {
  73. RETURN_STATUS_UNEXPECTED("Invalid file, failed to open json file: " + in_file +
  74. ", please delete it and try again!");
  75. }
  76. }
  77. js[key] = value;
  78. MS_LOG(INFO) << "Write outfile is: " << js << ".";
  79. if (out_file == "") {
  80. std::ofstream o(in_file, std::ofstream::trunc);
  81. o << js;
  82. o.close();
  83. } else {
  84. std::ofstream o(out_file, std::ofstream::trunc);
  85. o << js;
  86. o.close();
  87. }
  88. }
  89. // Catch any exception and convert to Status return code
  90. catch (const std::exception &err) {
  91. RETURN_STATUS_UNEXPECTED("Update json failed ");
  92. }
  93. return Status::OK();
  94. }
  95. /// \brief Update a json file field with a single value of of type T
  96. /// \param in_file The input file name to read in
  97. /// \param key Key of field to write to
  98. /// \param value Value to write to file
  99. /// \param out_file Optional parameter for output file path, will write to input file if not specified
  100. /// \return Status The status code returned
  101. template <typename T>
  102. Status UpdateValue(const std::string &in_file, const std::string &key, const T &value,
  103. const std::string &out_file = "") {
  104. try {
  105. Path in = Path(in_file);
  106. nlohmann::json js;
  107. if (in.Exists()) {
  108. RETURN_IF_NOT_OK(RealPath(in_file));
  109. try {
  110. std::ifstream in_stream(in_file);
  111. MS_LOG(INFO) << "Filename: " << in_file << ".";
  112. in_stream >> js;
  113. in_stream.close();
  114. } catch (const std::exception &err) {
  115. RETURN_STATUS_UNEXPECTED("Invalid file, failed to open json file: " + in_file +
  116. ", please delete it and try again!");
  117. }
  118. }
  119. js[key] = value;
  120. MS_LOG(INFO) << "Write outfile is: " << js << ".";
  121. if (out_file == "") {
  122. std::ofstream o(in_file, std::ofstream::trunc);
  123. o << js;
  124. o.close();
  125. } else {
  126. std::ofstream o(out_file, std::ofstream::trunc);
  127. o << js;
  128. o.close();
  129. }
  130. }
  131. // Catch any exception and convert to Status return code
  132. catch (const std::exception &err) {
  133. RETURN_STATUS_UNEXPECTED("Update json failed ");
  134. }
  135. return Status::OK();
  136. }
  137. /// \brief Template function to write tensor to file
  138. /// \param[in] in_file File to write to
  139. /// \param[in] data Array of type T values
  140. /// \return Status The status code returned
  141. template <typename T>
  142. Status WriteBinFile(const std::string &in_file, const std::vector<T> &data) {
  143. try {
  144. std::ofstream o(in_file, std::ios::binary | std::ios::out);
  145. if (!o.is_open()) {
  146. RETURN_STATUS_UNEXPECTED("Error opening Bin file to write");
  147. }
  148. size_t length = data.size();
  149. o.write(reinterpret_cast<const char *>(&data[0]), std::streamsize(length * sizeof(T)));
  150. o.close();
  151. }
  152. // Catch any exception and convert to Status return code
  153. catch (const std::exception &err) {
  154. RETURN_STATUS_UNEXPECTED("Write bin file failed ");
  155. }
  156. return Status::OK();
  157. }
  158. /// \brief Write pointer to bin, use pointer to avoid memcpy
  159. /// \param[in] in_file File name to write to
  160. /// \param[in] data Pointer to data
  161. /// \param[in] length Length of values to write from pointer
  162. /// \return Status The status code returned
  163. template <typename T>
  164. Status WriteBinFile(const std::string &in_file, T *data, size_t length) {
  165. try {
  166. std::string real_in_file;
  167. RETURN_IF_NOT_OK(Path::RealPath(in_file, real_in_file));
  168. std::ofstream o(real_in_file, std::ios::binary | std::ios::out);
  169. if (!o.is_open()) {
  170. RETURN_STATUS_UNEXPECTED("Error opening Bin file to write");
  171. }
  172. o.write(reinterpret_cast<const char *>(data), std::streamsize(length * sizeof(T)));
  173. o.close();
  174. }
  175. // Catch any exception and convert to Status return code
  176. catch (const std::exception &err) {
  177. RETURN_STATUS_UNEXPECTED("Write bin file failed ");
  178. }
  179. return Status::OK();
  180. }
  181. /// \brief Helper function to copy content of a tensor to buffer
  182. /// \note This function iterates over the tensor in bytes, since
  183. /// \param[in] tensor_addr The memory held by a tensor, e.g. tensor->GetBuffer()
  184. /// \param[in] tensor_size The amount of data in bytes in tensor_addr, e.g. tensor->SizeInBytes()
  185. /// \param[out] addr The address to copy tensor data to
  186. /// \param[in] buffer_size The buffer size of addr
  187. /// \return The size of the tensor (bytes copied
  188. size_t DumpData(const unsigned char *tensor_addr, const size_t &tensor_size, void *addr, const size_t &buffer_size);
  189. /// \brief Helper function to delete key in json file
  190. /// \note This function will return okay even if key not found
  191. /// \param[in] in_file Json file to remove key from
  192. /// \param[in] key The key to remove
  193. /// \return Status The status code returned
  194. Status RemoveKey(const std::string &in_file, const std::string &key, const std::string &out_file = "");
  195. /// \brief A print method typically used for debugging
  196. /// \param out - The output stream to write output to
  197. void Print(std::ostream &out) const;
  198. /// \brief Helper function to check real path
  199. /// \note This function will return okay even if key not found
  200. /// \param[in] path Path to Json file
  201. /// \return Status The status code returned
  202. Status RealPath(const std::string &path);
  203. /// \brief << Stream output operator overload
  204. /// \note This allows you to write the debug print info using stream operators
  205. /// \param out Reference to the output stream being overloaded
  206. /// \param dh Reference to the DataSchema to display
  207. /// \return The output stream must be returned
  208. friend std::ostream &operator<<(std::ostream &out, const JsonHelper &dh) {
  209. dh.Print(out);
  210. return out;
  211. }
  212. };
  213. } // namespace dataset
  214. } // namespace mindspore
  215. #endif // MINDSPORE_CCSRC_MINDDATA_DATASET_UTIL_JSON_HELPER_H_