1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef PPAPI_CPP_FILE_IO_H_ 6 #define PPAPI_CPP_FILE_IO_H_ 7 8 #include "ppapi/c/pp_time.h" 9 #include "ppapi/cpp/completion_callback.h" 10 #include "ppapi/cpp/resource.h" 11 12 /// @file 13 /// This file defines the API to create a file i/o object. 14 15 struct PP_FileInfo; 16 17 namespace pp { 18 19 class FileRef; 20 class InstanceHandle; 21 22 /// The <code>FileIO</code> class represents a regular file. 23 class FileIO : public Resource { 24 public: 25 /// Default constructor for creating an is_null() <code>FileIO</code> 26 /// object. 27 FileIO(); 28 29 /// A constructor used to create a <code>FileIO</code> and associate it with 30 /// the provided <code>Instance</code>. 31 /// 32 /// @param[in] instance The instance with which this resource will be 33 /// associated. 34 explicit FileIO(const InstanceHandle& instance); 35 36 /// The copy constructor for <code>FileIO</code>. 37 /// 38 /// @param[in] other A reference to a <code>FileIO</code>. 39 FileIO(const FileIO& other); 40 41 /// Open() opens the specified regular file for I/O according to the given 42 /// open flags, which is a bit-mask of the PP_FileOpenFlags values. Upon 43 /// success, the corresponding file is classified as "in use" by this FileIO 44 /// object until such time as the FileIO object is closed or destroyed. 45 /// 46 /// @param[in] file_ref A <code>PP_Resource</code> corresponding to a file 47 /// reference. 48 /// 49 /// @param[in] open_flags A bit-mask of the <code>PP_FileOpenFlags</code> 50 /// values. Valid values are: 51 /// - PP_FILEOPENFLAG_READ 52 /// - PP_FILEOPENFLAG_WRITE 53 /// - PP_FILEOPENFLAG_CREATE 54 /// - PP_FILEOPENFLAG_TRUNCATE 55 /// - PP_FILEOPENFLAG_EXCLUSIVE 56 /// See <code>PP_FileOpenFlags</code> in <code>ppb_file_io.h</code> for more 57 /// details on these flags. 58 /// 59 /// @param[in] cc A <code>CompletionCallback</code> to be called upon 60 /// completion of Open(). 61 /// 62 /// @return An int32_t containing an error code from 63 /// <code>pp_errors.h</code>. 64 int32_t Open(const FileRef& file_ref, 65 int32_t open_flags, 66 const CompletionCallback& cc); 67 68 /// Query() queries info about the file opened by this FileIO object. This 69 /// function will fail if the FileIO object has not been opened. 70 /// 71 /// @param[in] result_buf The <code>PP_FileInfo</code> structure representing 72 /// all information about the file. 73 /// @param[in] cc A <code>CompletionCallback</code> to be called upon 74 /// completion of Query(). <code>result_buf</code> must remain valid until 75 /// after the callback runs. If you pass a blocking callback, 76 /// <code>result_buf</code> must remain valid until after Query() returns. 77 /// 78 /// @return An int32_t containing an error code from 79 /// <code>pp_errors.h</code>. 80 int32_t Query(PP_FileInfo* result_buf, 81 const CompletionCallback& cc); 82 83 /// Touch() Updates time stamps for the file opened by this FileIO object. 84 /// This function will fail if the FileIO object has not been opened. 85 /// 86 /// @param[in] last_access_time The last time the FileIO was accessed. 87 /// @param[in] last_modified_time The last time the FileIO was modified. 88 /// @param[in] cc A <code>CompletionCallback</code> to be called upon 89 /// completion of Touch(). 90 /// 91 /// @return An int32_t containing an error code from 92 /// <code>pp_errors.h</code>. 93 int32_t Touch(PP_Time last_access_time, 94 PP_Time last_modified_time, 95 const CompletionCallback& cc); 96 97 /// Reads from an offset in the file. 98 /// 99 /// The size of the buffer must be large enough to hold the specified number 100 /// of bytes to read. This function might perform a partial read, meaning 101 /// that all the requested bytes might not be returned, even if the end of the 102 /// file has not been reached. 103 /// 104 /// This function reads into a buffer that the caller supplies. This buffer 105 /// must remain valid as long as the FileIO resource is alive. If you use 106 /// a completion callback factory and it goes out of scope, it will not issue 107 /// the callback on your class, BUT the callback factory can NOT cancel 108 /// the request from the browser's perspective. This means that the browser 109 /// will still try to write to your buffer even if the callback factory is 110 /// destroyed! 111 /// 112 /// So you must ensure that your buffer outlives the FileIO resource. If you 113 /// have one class and use the FileIO resource exclusively from that class 114 /// and never make any copies, this will be fine: the resource will be 115 /// destroyed when your class is. But keep in mind that copying a pp::FileIO 116 /// object just creates a second reference to the original resource. For 117 /// example, if you have a function like this: 118 /// pp::FileIO MyClass::GetFileIO(); 119 /// where a copy of your FileIO resource could outlive your class, the 120 /// callback will still be pending when your class goes out of scope, creating 121 /// the possibility of writing into invalid memory. So it's recommended to 122 /// keep your FileIO resource and any output buffers tightly controlled in 123 /// the same scope. 124 /// 125 /// <strong>Caveat:</strong> This Read() is potentially unsafe if you're using 126 /// a CompletionCallbackFactory to scope callbacks to the lifetime of your 127 /// class. When your class goes out of scope, the callback factory will not 128 /// actually cancel the callback, but will rather just skip issuing the 129 /// callback on your class. This means that if the FileIO object outlives 130 /// your class (if you made a copy saved somewhere else, for example), then 131 /// the browser will still try to write into your buffer when the 132 /// asynchronous read completes, potentially causing a crash. 133 /// 134 /// See the other version of Read() which avoids this problem by writing into 135 /// CompletionCallbackWithOutput, where the output buffer is automatically 136 /// managed by the callback. 137 /// 138 /// @param[in] offset The offset into the file. 139 /// @param[in] buffer The buffer to hold the specified number of bytes read. 140 /// @param[in] bytes_to_read The number of bytes to read from 141 /// <code>offset</code>. 142 /// @param[in] cc A <code>CompletionCallback</code> to be called upon 143 /// completion of Read(). <code>buffer</code> must remain valid until after 144 /// the callback runs. If you pass a blocking callback, <code>buffer</code> 145 /// must remain valid until after Read() returns. 146 /// 147 /// @return An The number of bytes read an error code from 148 /// <code>pp_errors.h</code>. If the return value is 0, then end-of-file was 149 /// reached. It is valid to call Read() multiple times with a completion 150 /// callback to queue up parallel reads from the file at different offsets. 151 int32_t Read(int64_t offset, 152 char* buffer, 153 int32_t bytes_to_read, 154 const CompletionCallback& cc); 155 156 /// Read() reads from an offset in the file. A PP_ArrayOutput must be 157 /// provided so that output will be stored in its allocated buffer. This 158 /// function might perform a partial read. 159 /// 160 /// @param[in] file_io A <code>PP_Resource</code> corresponding to a file 161 /// FileIO. 162 /// @param[in] offset The offset into the file. 163 /// @param[in] max_read_length The maximum number of bytes to read from 164 /// <code>offset</code>. 165 /// @param[in] output A <code>PP_ArrayOutput</code> to hold the output data. 166 /// @param[in] callback A <code>PP_CompletionCallback</code> to be called upon 167 /// completion of Read(). 168 /// 169 /// @return The number of bytes read or an error code from 170 /// <code>pp_errors.h</code>. If the return value is 0, then end-of-file was 171 /// reached. It is valid to call Read() multiple times with a completion 172 /// callback to queue up parallel reads from the file, but pending reads 173 /// cannot be interleaved with other operations. 174 int32_t Read(int32_t offset, 175 int32_t max_read_length, 176 const CompletionCallbackWithOutput< std::vector<char> >& cc); 177 178 /// Write() writes to an offset in the file. This function might perform a 179 /// partial write. The FileIO object must have been opened with write access. 180 /// 181 /// @param[in] offset The offset into the file. 182 /// @param[in] buffer The buffer to hold the specified number of bytes read. 183 /// @param[in] bytes_to_write The number of bytes to write to 184 /// <code>offset</code>. 185 /// @param[in] cc A <code>CompletionCallback</code> to be called upon 186 /// completion of Write(). 187 /// 188 /// @return An The number of bytes written or an error code from 189 /// <code>pp_errors.h</code>. If the return value is 0, then end-of-file was 190 /// reached. It is valid to call Write() multiple times with a completion 191 /// callback to queue up parallel writes to the file at different offsets. 192 int32_t Write(int64_t offset, 193 const char* buffer, 194 int32_t bytes_to_write, 195 const CompletionCallback& cc); 196 197 /// SetLength() sets the length of the file. If the file size is extended, 198 /// then the extended area of the file is zero-filled. The FileIO object must 199 /// have been opened with write access. 200 /// 201 /// @param[in] length The length of the file to be set. 202 /// @param[in] cc A <code>CompletionCallback</code> to be called upon 203 /// completion of SetLength(). 204 /// 205 /// @return An int32_t containing an error code from 206 /// <code>pp_errors.h</code>. 207 int32_t SetLength(int64_t length, 208 const CompletionCallback& cc); 209 210 /// Flush() flushes changes to disk. This call can be very expensive! 211 /// 212 /// @param[in] cc A <code>CompletionCallback</code> to be called upon 213 /// completion of Flush(). 214 /// 215 /// @return An int32_t containing an error code from 216 /// <code>pp_errors.h</code>. 217 int32_t Flush(const CompletionCallback& cc); 218 219 /// Close() cancels any IO that may be pending, and closes the FileIO object. 220 /// Any pending callbacks will still run, reporting 221 /// <code>PP_ERROR_ABORTED</code> if pending IO was interrupted. It is not 222 /// valid to call Open() again after a call to this method. 223 /// 224 /// <strong>Note:</strong> If the FileIO object is destroyed, and it is still 225 /// open, then it will be implicitly closed, so you are not required to call 226 /// Close(). 227 void Close(); 228 229 private: 230 struct CallbackData1_0 { 231 PP_ArrayOutput output; 232 char* temp_buffer; 233 PP_CompletionCallback original_callback; 234 }; 235 236 // Provide backwards-compatibility for older Read versions. Converts the 237 // old-style "char*" output buffer of 1.0 to the new "PP_ArrayOutput" 238 // interface in 1.1. 239 // 240 // This takes a heap-allocated CallbackData1_0 struct passed as the user data 241 // and deletes it when the call completes. 242 static void CallbackConverter(void* user_data, int32_t result); 243 }; 244 245 } // namespace pp 246 247 #endif // PPAPI_CPP_FILE_IO_H_ 248