1 #include "image_io/utils/file_utils.h"
2 
3 #include <sys/stat.h>
4 #import <fstream>
5 #import <iostream>
6 #import <memory>
7 
8 #include "image_io/base/data_range.h"
9 
10 namespace photos_editing_formats {
11 namespace image_io {
12 
13 using std::fstream;
14 using std::istream;
15 using std::ostream;
16 using std::unique_ptr;
17 
GetFileSize(const std::string & file_name,size_t * size)18 bool GetFileSize(const std::string& file_name, size_t* size) {
19   struct stat stat_buf;
20   if (stat(file_name.c_str(), &stat_buf)) {
21     return false;
22   } else {
23     if (size) {
24       *size = stat_buf.st_size;
25     }
26     return true;
27   }
28 }
29 
OpenOutputFile(const std::string & file_name,MessageHandler * message_handler)30 unique_ptr<ostream> OpenOutputFile(const std::string& file_name,
31                                    MessageHandler* message_handler) {
32   auto* file_stream = new fstream(file_name, std::ios::out | std::ios::binary);
33   if (file_stream && !file_stream->is_open()) {
34     delete file_stream;
35     file_stream = nullptr;
36     if (message_handler) {
37       message_handler->ReportMessage(Message::kStdLibError, file_name);
38     }
39   }
40   return unique_ptr<ostream>(file_stream);
41 }
42 
OpenInputFile(const std::string & file_name,MessageHandler * message_handler)43 unique_ptr<istream> OpenInputFile(const std::string& file_name,
44                                   MessageHandler* message_handler) {
45   auto* file_stream = new fstream(file_name, std::ios::in | std::ios::binary);
46   if (file_stream && !file_stream->is_open()) {
47     delete file_stream;
48     file_stream = nullptr;
49     if (message_handler) {
50       message_handler->ReportMessage(Message::kStdLibError, file_name);
51     }
52   }
53   return unique_ptr<istream>(file_stream);
54 }
55 
ReadEntireFile(const std::string & file_name,MessageHandler * message_handler)56 std::shared_ptr<DataSegment> ReadEntireFile(const std::string& file_name,
57                                             MessageHandler* message_handler) {
58   size_t buffer_size = 0;
59   std::shared_ptr<DataSegment> shared_data_segment;
60   if (GetFileSize(file_name, &buffer_size)) {
61     unique_ptr<istream> shared_istream =
62         OpenInputFile(file_name, message_handler);
63     if (shared_istream) {
64       Byte* buffer = new Byte[buffer_size];
65       if (buffer) {
66         shared_data_segment =
67             DataSegment::Create(DataRange(0, buffer_size), buffer);
68         shared_istream->read(reinterpret_cast<char*>(buffer), buffer_size);
69         size_t bytes_read = shared_istream->tellg();
70         if (bytes_read != buffer_size) {
71           shared_data_segment.reset();
72         }
73       }
74     }
75   }
76   if (!shared_data_segment && message_handler) {
77     message_handler->ReportMessage(Message::kStdLibError, file_name);
78   }
79   return shared_data_segment;
80 }
81 
82 }  // namespace image_io
83 }  // namespace photos_editing_formats
84