| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 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 #include "ppapi/tests/test_file_mapping.h" | 
|  | 6 | 
|  | 7 #include <string.h> | 
|  | 8 | 
|  | 9 #include <limits> | 
|  | 10 #include <string> | 
|  | 11 | 
|  | 12 #include "ppapi/c/pp_errors.h" | 
|  | 13 #include "ppapi/c/ppb_file_io.h" | 
|  | 14 #include "ppapi/c/ppb_file_mapping.h" | 
|  | 15 #include "ppapi/cpp/file_io.h" | 
|  | 16 #include "ppapi/cpp/file_ref.h" | 
|  | 17 #include "ppapi/cpp/file_system.h" | 
|  | 18 #include "ppapi/cpp/instance.h" | 
|  | 19 #include "ppapi/cpp/module.h" | 
|  | 20 #include "ppapi/tests/test_utils.h" | 
|  | 21 | 
|  | 22 REGISTER_TEST_CASE(FileMapping); | 
|  | 23 | 
|  | 24 namespace { | 
|  | 25 | 
|  | 26 // TODO(dmichael): Move these to test_utils so we can share them? | 
|  | 27 int32_t ReadEntireFile(PP_Instance instance, | 
|  | 28                        pp::FileIO* file_io, | 
|  | 29                        int32_t offset, | 
|  | 30                        std::string* data, | 
|  | 31                        CallbackType callback_type) { | 
|  | 32   TestCompletionCallback callback(instance, callback_type); | 
|  | 33   char buf[256]; | 
|  | 34   int32_t read_offset = offset; | 
|  | 35 | 
|  | 36   for (;;) { | 
|  | 37     callback.WaitForResult( | 
|  | 38         file_io->Read(read_offset, buf, sizeof(buf), callback.GetCallback())); | 
|  | 39     if (callback.result() < 0) | 
|  | 40       return callback.result(); | 
|  | 41     if (callback.result() == 0) | 
|  | 42       break; | 
|  | 43     read_offset += callback.result(); | 
|  | 44     data->append(buf, callback.result()); | 
|  | 45   } | 
|  | 46 | 
|  | 47   return PP_OK; | 
|  | 48 } | 
|  | 49 | 
|  | 50 int32_t WriteEntireBuffer(PP_Instance instance, | 
|  | 51                           pp::FileIO* file_io, | 
|  | 52                           int32_t offset, | 
|  | 53                           const std::string& data, | 
|  | 54                           CallbackType callback_type) { | 
|  | 55   TestCompletionCallback callback(instance, callback_type); | 
|  | 56   int32_t write_offset = offset; | 
|  | 57   const char* buf = data.c_str(); | 
|  | 58   int32_t size = data.size(); | 
|  | 59 | 
|  | 60   while (write_offset < offset + size) { | 
|  | 61     callback.WaitForResult(file_io->Write(write_offset, | 
|  | 62                                           &buf[write_offset - offset], | 
|  | 63                                           size - write_offset + offset, | 
|  | 64                                           callback.GetCallback())); | 
|  | 65     if (callback.result() < 0) | 
|  | 66       return callback.result(); | 
|  | 67     if (callback.result() == 0) | 
|  | 68       return PP_ERROR_FAILED; | 
|  | 69     write_offset += callback.result(); | 
|  | 70   } | 
|  | 71   callback.WaitForResult(file_io->Flush(callback.GetCallback())); | 
|  | 72   return callback.result(); | 
|  | 73 } | 
|  | 74 | 
|  | 75 }  // namespace | 
|  | 76 | 
|  | 77 std::string TestFileMapping::MapAndCheckResults(uint32_t prot, | 
|  | 78                                                 uint32_t flags) { | 
|  | 79   TestCompletionCallback callback(instance_->pp_instance(), callback_type()); | 
|  | 80 | 
|  | 81   pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); | 
|  | 82   pp::FileRef file_ref(file_system, "/mapped_file"); | 
|  | 83 | 
|  | 84   callback.WaitForResult(file_system.Open(1024, callback.GetCallback())); | 
|  | 85   ASSERT_EQ(PP_OK, callback.result()); | 
|  | 86 | 
|  | 87   const int64_t page_size = | 
|  | 88       file_mapping_if_->GetMapPageSize(instance_->pp_instance()); | 
|  | 89   const int64_t kNumPages = 4; | 
|  | 90   // Make a string that's big enough that it spans all of the first |n-1| pages, | 
|  | 91   // plus a little bit of the |nth| page. | 
|  | 92   std::string file_contents((page_size * (kNumPages - 1)) + 128, 'a'); | 
|  | 93 | 
|  | 94   pp::FileIO file_io(instance_); | 
|  | 95   callback.WaitForResult(file_io.Open(file_ref, | 
|  | 96                                       PP_FILEOPENFLAG_CREATE | | 
|  | 97                                       PP_FILEOPENFLAG_TRUNCATE | | 
|  | 98                                       PP_FILEOPENFLAG_READ | | 
|  | 99                                       PP_FILEOPENFLAG_WRITE, | 
|  | 100                                       callback.GetCallback())); | 
|  | 101   ASSERT_EQ(PP_OK, callback.result()); | 
|  | 102   ASSERT_EQ(PP_OK, WriteEntireBuffer(instance_->pp_instance(), | 
|  | 103                                      &file_io, | 
|  | 104                                      0, | 
|  | 105                                      file_contents, | 
|  | 106                                      callback_type())); | 
|  | 107 | 
|  | 108   // TODO(dmichael): Use C++ interface. | 
|  | 109   void* address = NULL; | 
|  | 110   callback.WaitForResult( | 
|  | 111       file_mapping_if_->Map( | 
|  | 112           instance_->pp_instance(), | 
|  | 113           file_io.pp_resource(), | 
|  | 114           kNumPages * page_size, | 
|  | 115           prot, | 
|  | 116           flags, | 
|  | 117           0, | 
|  | 118           &address, | 
|  | 119           callback.GetCallback().pp_completion_callback())); | 
|  | 120   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 121   ASSERT_EQ(PP_OK, callback.result()); | 
|  | 122   ASSERT_NE(NULL, address); | 
|  | 123 | 
|  | 124   if (prot & PP_FILEMAPPROTECTION_READ) { | 
|  | 125     // Make sure we can read. | 
|  | 126     std::string mapped_data(static_cast<char*>(address), file_contents.size()); | 
|  | 127     // The initial data should match. | 
|  | 128     ASSERT_EQ(file_contents, mapped_data); | 
|  | 129 | 
|  | 130     // Now write some data and flush it. | 
|  | 131     const std::string file_contents2(file_contents.size(), 'x'); | 
|  | 132     ASSERT_EQ(PP_OK, WriteEntireBuffer(instance_->pp_instance(), | 
|  | 133                                        &file_io, | 
|  | 134                                        0, | 
|  | 135                                        file_contents2, | 
|  | 136                                        callback_type())); | 
|  | 137     // If the region was mapped SHARED, it should get updated. | 
|  | 138     std::string mapped_data2(static_cast<char*>(address), file_contents.size()); | 
|  | 139     if (flags & PP_FILEMAPFLAG_SHARED) | 
|  | 140       ASSERT_EQ(file_contents2, mapped_data2); | 
|  | 141     // In POSIX, it is unspecified in the PRIVATE case whether changes to the | 
|  | 142     // file are visible to the mapped region. So we can't really test anything | 
|  | 143     // here in that case. | 
|  | 144     // FIXME(dmichael): Make sure our Pepper documentation reflects this. | 
|  | 145   } | 
|  | 146   if (prot & PP_FILEMAPPROTECTION_WRITE) { | 
|  | 147     std::string old_file_contents; | 
|  | 148     ASSERT_EQ(PP_OK, ReadEntireFile(instance_->pp_instance(), | 
|  | 149                                     &file_io, | 
|  | 150                                     0, | 
|  | 151                                     &old_file_contents, | 
|  | 152                                     callback_type())); | 
|  | 153     // Write something else to the mapped region, then unmap, and see if it | 
|  | 154     // gets written to the file. (Note we have to Unmap to make sure that the | 
|  | 155     // write is committed). | 
|  | 156     memset(address, 'y', file_contents.size()); | 
|  | 157     // Note, we might not have read access to the mapped region here, so we | 
|  | 158     // make a string with the same contents without actually reading. | 
|  | 159     std::string mapped_data3(file_contents.size(), 'y'); | 
|  | 160     callback.WaitForResult( | 
|  | 161         file_mapping_if_->Unmap( | 
|  | 162             instance_->pp_instance(), address, file_contents.size(), | 
|  | 163             callback.GetCallback().pp_completion_callback())); | 
|  | 164     CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 165     ASSERT_EQ(PP_OK, callback.result()); | 
|  | 166     std::string new_file_contents; | 
|  | 167     ASSERT_EQ(PP_OK, ReadEntireFile(instance_->pp_instance(), | 
|  | 168                                     &file_io, | 
|  | 169                                     0, | 
|  | 170                                     &new_file_contents, | 
|  | 171                                     callback_type())); | 
|  | 172 | 
|  | 173     // Sanity-check that the data we wrote isn't the same as what was already | 
|  | 174     // there, otherwise our test is invalid. | 
|  | 175     ASSERT_NE(mapped_data3, old_file_contents); | 
|  | 176     // If it's SHARED, the file should match what we wrote to the mapped region. | 
|  | 177     // Otherwise, it should not have changed. | 
|  | 178     if (flags & PP_FILEMAPFLAG_SHARED) | 
|  | 179       ASSERT_EQ(mapped_data3, new_file_contents); | 
|  | 180     else | 
|  | 181       ASSERT_EQ(old_file_contents, new_file_contents); | 
|  | 182   } else { | 
|  | 183     // We didn't do the "WRITE" test, but we still want to Unmap. | 
|  | 184     callback.WaitForResult( | 
|  | 185         file_mapping_if_->Unmap( | 
|  | 186             instance_->pp_instance(), address, file_contents.size(), | 
|  | 187             callback.GetCallback().pp_completion_callback())); | 
|  | 188     CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 189     ASSERT_EQ(PP_OK, callback.result()); | 
|  | 190   } | 
|  | 191   PASS(); | 
|  | 192 } | 
|  | 193 | 
|  | 194 bool TestFileMapping::Init() { | 
|  | 195   // TODO(dmichael): Use unversioned string when this goes to stable? | 
|  | 196   file_mapping_if_ = static_cast<const PPB_FileMapping_0_1*>( | 
|  | 197       pp::Module::Get()->GetBrowserInterface(PPB_FILEMAPPING_INTERFACE_0_1)); | 
|  | 198   return !!file_mapping_if_ && CheckTestingInterface() && | 
|  | 199          EnsureRunningOverHTTP(); | 
|  | 200 } | 
|  | 201 | 
|  | 202 void TestFileMapping::RunTests(const std::string& filter) { | 
|  | 203   // TODO(dmichael): Tests to write: | 
|  | 204   //  - Unmapping partial regions | 
|  | 205 //  RUN_CALLBACK_TEST(TestFileMapping, BadParameters, filter); | 
|  | 206   RUN_CALLBACK_TEST(TestFileMapping, Map, filter); | 
|  | 207 } | 
|  | 208 | 
|  | 209 std::string TestFileMapping::TestBadParameters() { | 
|  | 210   TestCompletionCallback callback(instance_->pp_instance(), callback_type()); | 
|  | 211 | 
|  | 212   pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); | 
|  | 213   pp::FileRef file_ref(file_system, "/mapped_file"); | 
|  | 214 | 
|  | 215   callback.WaitForResult(file_system.Open(1024, callback.GetCallback())); | 
|  | 216   ASSERT_EQ(PP_OK, callback.result()); | 
|  | 217 | 
|  | 218   const int64_t page_size = | 
|  | 219       file_mapping_if_->GetMapPageSize(instance_->pp_instance()); | 
|  | 220   // const int64_t kNumPages = 4; | 
|  | 221   // Make a string that's big enough that it spans 3 pages, plus a little extra. | 
|  | 222   //std::string file_contents((page_size * (kNumPages - 1)) + 128, 'a'); | 
|  | 223   std::string file_contents(page_size, 'a'); | 
|  | 224 | 
|  | 225   pp::FileIO file_io(instance_); | 
|  | 226   callback.WaitForResult(file_io.Open(file_ref, | 
|  | 227                                       PP_FILEOPENFLAG_CREATE | | 
|  | 228                                       PP_FILEOPENFLAG_TRUNCATE | | 
|  | 229                                       PP_FILEOPENFLAG_READ | | 
|  | 230                                       PP_FILEOPENFLAG_WRITE, | 
|  | 231                                       callback.GetCallback())); | 
|  | 232   ASSERT_EQ(PP_OK, callback.result()); | 
|  | 233   ASSERT_EQ(PP_OK, WriteEntireBuffer(instance_->pp_instance(), | 
|  | 234                                      &file_io, | 
|  | 235                                      0, | 
|  | 236                                      file_contents, | 
|  | 237                                      callback_type())); | 
|  | 238 | 
|  | 239   // Bad instance. | 
|  | 240   void* address = NULL; | 
|  | 241   callback.WaitForResult( | 
|  | 242       file_mapping_if_->Map( | 
|  | 243           PP_Instance(0xbadbad), | 
|  | 244           file_io.pp_resource(), | 
|  | 245           page_size, | 
|  | 246           PP_FILEMAPPROTECTION_READ, | 
|  | 247           PP_FILEMAPFLAG_PRIVATE, | 
|  | 248           0, | 
|  | 249           &address, | 
|  | 250           callback.GetCallback().pp_completion_callback())); | 
|  | 251   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 252   ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); | 
|  | 253   ASSERT_EQ(NULL, address); | 
|  | 254 | 
|  | 255   // Bad resource. | 
|  | 256   callback.WaitForResult( | 
|  | 257       file_mapping_if_->Map( | 
|  | 258           instance_->pp_instance(), | 
|  | 259           PP_Resource(0xbadbad), | 
|  | 260           page_size, | 
|  | 261           PP_FILEMAPPROTECTION_READ, | 
|  | 262           PP_FILEMAPFLAG_PRIVATE, | 
|  | 263           0, | 
|  | 264           &address, | 
|  | 265           callback.GetCallback().pp_completion_callback())); | 
|  | 266   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 267   ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); | 
|  | 268   ASSERT_EQ(NULL, address); | 
|  | 269 | 
|  | 270   // Length too big. | 
|  | 271   callback.WaitForResult( | 
|  | 272       file_mapping_if_->Map( | 
|  | 273           instance_->pp_instance(), | 
|  | 274           file_io.pp_resource(), | 
|  | 275           std::numeric_limits<int64_t>::max(), | 
|  | 276           PP_FILEMAPPROTECTION_READ, | 
|  | 277           PP_FILEMAPFLAG_PRIVATE, | 
|  | 278           0, | 
|  | 279           &address, | 
|  | 280           callback.GetCallback().pp_completion_callback())); | 
|  | 281   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 282   ASSERT_EQ(PP_ERROR_NOMEMORY, callback.result()); | 
|  | 283   ASSERT_EQ(NULL, address); | 
|  | 284 | 
|  | 285   // Length too small. | 
|  | 286   callback.WaitForResult( | 
|  | 287       file_mapping_if_->Map( | 
|  | 288           instance_->pp_instance(), | 
|  | 289           file_io.pp_resource(), | 
|  | 290           -1, | 
|  | 291           PP_FILEMAPPROTECTION_READ, | 
|  | 292           PP_FILEMAPFLAG_PRIVATE, | 
|  | 293           0, | 
|  | 294           &address, | 
|  | 295           callback.GetCallback().pp_completion_callback())); | 
|  | 296   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 297   ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); | 
|  | 298   ASSERT_EQ(NULL, address); | 
|  | 299   // TODO(dmichael): Check & test length that is not a multiple of page size??? | 
|  | 300 | 
|  | 301   // Bad protection. | 
|  | 302   callback.WaitForResult( | 
|  | 303       file_mapping_if_->Map( | 
|  | 304           instance_->pp_instance(), | 
|  | 305           file_io.pp_resource(), | 
|  | 306           page_size, | 
|  | 307           ~PP_FILEMAPPROTECTION_READ, | 
|  | 308           PP_FILEMAPFLAG_PRIVATE, | 
|  | 309           0, | 
|  | 310           &address, | 
|  | 311           callback.GetCallback().pp_completion_callback())); | 
|  | 312   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 313   ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); | 
|  | 314   ASSERT_EQ(NULL, address); | 
|  | 315 | 
|  | 316   // No flags. | 
|  | 317   callback.WaitForResult( | 
|  | 318       file_mapping_if_->Map( | 
|  | 319           instance_->pp_instance(), | 
|  | 320           file_io.pp_resource(), | 
|  | 321           page_size, | 
|  | 322           PP_FILEMAPPROTECTION_READ, | 
|  | 323           0, | 
|  | 324           0, | 
|  | 325           &address, | 
|  | 326           callback.GetCallback().pp_completion_callback())); | 
|  | 327   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 328   ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); | 
|  | 329   ASSERT_EQ(NULL, address); | 
|  | 330 | 
|  | 331   // Both flags. | 
|  | 332   callback.WaitForResult( | 
|  | 333       file_mapping_if_->Map( | 
|  | 334           instance_->pp_instance(), | 
|  | 335           file_io.pp_resource(), | 
|  | 336           page_size, | 
|  | 337           PP_FILEMAPPROTECTION_READ, | 
|  | 338           PP_FILEMAPFLAG_SHARED | PP_FILEMAPFLAG_PRIVATE, | 
|  | 339           0, | 
|  | 340           &address, | 
|  | 341           callback.GetCallback().pp_completion_callback())); | 
|  | 342   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 343   ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); | 
|  | 344   ASSERT_EQ(NULL, address); | 
|  | 345 | 
|  | 346   // Bad flags. | 
|  | 347   callback.WaitForResult( | 
|  | 348       file_mapping_if_->Map( | 
|  | 349           instance_->pp_instance(), | 
|  | 350           file_io.pp_resource(), | 
|  | 351           page_size, | 
|  | 352           PP_FILEMAPPROTECTION_READ, | 
|  | 353           ~PP_FILEMAPFLAG_SHARED, | 
|  | 354           0, | 
|  | 355           &address, | 
|  | 356           callback.GetCallback().pp_completion_callback())); | 
|  | 357   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 358   ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); | 
|  | 359   ASSERT_EQ(NULL, address); | 
|  | 360 | 
|  | 361   // Bad offset; not a multiple of page size. | 
|  | 362   callback.WaitForResult( | 
|  | 363       file_mapping_if_->Map( | 
|  | 364           instance_->pp_instance(), | 
|  | 365           file_io.pp_resource(), | 
|  | 366           page_size, | 
|  | 367           PP_FILEMAPPROTECTION_READ, | 
|  | 368           ~PP_FILEMAPFLAG_SHARED, | 
|  | 369           1, | 
|  | 370           &address, | 
|  | 371           callback.GetCallback().pp_completion_callback())); | 
|  | 372   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 373   ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); | 
|  | 374   ASSERT_EQ(NULL, address); | 
|  | 375 | 
|  | 376   // Unmap NULL. | 
|  | 377   callback.WaitForResult( | 
|  | 378       file_mapping_if_->Unmap( | 
|  | 379           instance_->pp_instance(), | 
|  | 380           NULL, | 
|  | 381           page_size, | 
|  | 382           callback.GetCallback().pp_completion_callback())); | 
|  | 383   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 384   ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); | 
|  | 385 | 
|  | 386   // Unmap bad address. | 
|  | 387   callback.WaitForResult( | 
|  | 388       file_mapping_if_->Unmap( | 
|  | 389           instance_->pp_instance(), | 
|  | 390           reinterpret_cast<const void*>(0xdeadbeef), | 
|  | 391           page_size, | 
|  | 392           callback.GetCallback().pp_completion_callback())); | 
|  | 393   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 394   ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); | 
|  | 395 | 
|  | 396   PASS(); | 
|  | 397 } | 
|  | 398 | 
|  | 399 std::string TestFileMapping::TestMap() { | 
|  | 400   ASSERT_SUBTEST_SUCCESS(MapAndCheckResults(PP_FILEMAPPROTECTION_READ, | 
|  | 401                                             PP_FILEMAPFLAG_SHARED)); | 
|  | 402   ASSERT_SUBTEST_SUCCESS(MapAndCheckResults(PP_FILEMAPPROTECTION_WRITE, | 
|  | 403                                             PP_FILEMAPFLAG_SHARED)); | 
|  | 404   ASSERT_SUBTEST_SUCCESS( | 
|  | 405       MapAndCheckResults(PP_FILEMAPPROTECTION_WRITE | PP_FILEMAPPROTECTION_READ, | 
|  | 406                          PP_FILEMAPFLAG_SHARED)); | 
|  | 407   ASSERT_SUBTEST_SUCCESS(MapAndCheckResults(PP_FILEMAPPROTECTION_READ, | 
|  | 408                                             PP_FILEMAPFLAG_PRIVATE)); | 
|  | 409   ASSERT_SUBTEST_SUCCESS(MapAndCheckResults(PP_FILEMAPPROTECTION_WRITE, | 
|  | 410                                             PP_FILEMAPFLAG_PRIVATE)); | 
|  | 411   ASSERT_SUBTEST_SUCCESS( | 
|  | 412       MapAndCheckResults(PP_FILEMAPPROTECTION_WRITE | PP_FILEMAPPROTECTION_READ, | 
|  | 413                          PP_FILEMAPFLAG_PRIVATE)); | 
|  | 414   // FIXME(dmichael) How to test FIXED?? | 
|  | 415   PASS(); | 
|  | 416 } | 
|  | 417 | 
|  | 418 std::string TestFileMapping::TestPartialRegions() { | 
|  | 419   TestCompletionCallback callback(instance_->pp_instance(), callback_type()); | 
|  | 420 | 
|  | 421   pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); | 
|  | 422   pp::FileRef file_ref1(file_system, "/mapped_file1"); | 
|  | 423   pp::FileRef file_ref2(file_system, "/mapped_file2"); | 
|  | 424 | 
|  | 425   callback.WaitForResult(file_system.Open(1024, callback.GetCallback())); | 
|  | 426   ASSERT_EQ(PP_OK, callback.result()); | 
|  | 427 | 
|  | 428   const int64_t page_size = | 
|  | 429       file_mapping_if_->GetMapPageSize(instance_->pp_instance()); | 
|  | 430   const int64_t kNumPages = 3; | 
|  | 431   std::string file_contents1(kNumPages * page_size, 'a'); | 
|  | 432 | 
|  | 433   pp::FileIO file_io1(instance_); | 
|  | 434   callback.WaitForResult(file_io1.Open(file_ref1, | 
|  | 435                                        PP_FILEOPENFLAG_CREATE | | 
|  | 436                                        PP_FILEOPENFLAG_TRUNCATE | | 
|  | 437                                        PP_FILEOPENFLAG_READ | | 
|  | 438                                        PP_FILEOPENFLAG_WRITE, | 
|  | 439                                        callback.GetCallback())); | 
|  | 440   ASSERT_EQ(PP_OK, callback.result()); | 
|  | 441   ASSERT_EQ(PP_OK, WriteEntireBuffer(instance_->pp_instance(), | 
|  | 442                                      &file_io1, | 
|  | 443                                      0, | 
|  | 444                                      file_contents1, | 
|  | 445                                      callback_type())); | 
|  | 446 | 
|  | 447   // TODO(dmichael): Use C++ interface. | 
|  | 448   void* address = NULL; | 
|  | 449   callback.WaitForResult( | 
|  | 450       file_mapping_if_->Map( | 
|  | 451           instance_->pp_instance(), | 
|  | 452           file_io1.pp_resource(), | 
|  | 453           kNumPages * page_size, | 
|  | 454           PP_FILEMAPPROTECTION_WRITE | PP_FILEMAPPROTECTION_READ, | 
|  | 455           PP_FILEMAPFLAG_SHARED, | 
|  | 456           0, | 
|  | 457           &address, | 
|  | 458           callback.GetCallback().pp_completion_callback())); | 
|  | 459   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 460   ASSERT_EQ(PP_OK, callback.result()); | 
|  | 461   ASSERT_NE(NULL, address); | 
|  | 462 | 
|  | 463   // Unmap only the middle page. | 
|  | 464   void* address_of_middle_page = | 
|  | 465       reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(address) + page_size); | 
|  | 466   callback.WaitForResult( | 
|  | 467       file_mapping_if_->Unmap( | 
|  | 468           instance_->pp_instance(), | 
|  | 469           address_of_middle_page, | 
|  | 470           page_size, | 
|  | 471           callback.GetCallback().pp_completion_callback())); | 
|  | 472   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 473   ASSERT_EQ(PP_OK, callback.result()); | 
|  | 474 | 
|  | 475   // Write another file, map it in to the middle hole that was left above. | 
|  | 476   pp::FileIO file_io2(instance_); | 
|  | 477   callback.WaitForResult(file_io2.Open(file_ref2, | 
|  | 478                                        PP_FILEOPENFLAG_CREATE | | 
|  | 479                                        PP_FILEOPENFLAG_TRUNCATE | | 
|  | 480                                        PP_FILEOPENFLAG_READ | | 
|  | 481                                        PP_FILEOPENFLAG_WRITE, | 
|  | 482                                        callback.GetCallback())); | 
|  | 483   ASSERT_EQ(PP_OK, callback.result()); | 
|  | 484   // This second file will have 1 page worth of data. | 
|  | 485   std::string file_contents2(page_size, 'b'); | 
|  | 486   ASSERT_EQ(PP_OK, WriteEntireBuffer(instance_->pp_instance(), | 
|  | 487                                      &file_io2, | 
|  | 488                                      0, | 
|  | 489                                      file_contents2, | 
|  | 490                                      callback_type())); | 
|  | 491   callback.WaitForResult( | 
|  | 492       file_mapping_if_->Map( | 
|  | 493           instance_->pp_instance(), | 
|  | 494           file_io2.pp_resource(), | 
|  | 495           page_size, | 
|  | 496           PP_FILEMAPPROTECTION_WRITE | PP_FILEMAPPROTECTION_READ, | 
|  | 497           PP_FILEMAPFLAG_SHARED | PP_FILEMAPFLAG_FIXED, | 
|  | 498           0, | 
|  | 499           &address_of_middle_page, | 
|  | 500           callback.GetCallback().pp_completion_callback())); | 
|  | 501   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 502   ASSERT_EQ(PP_OK, callback.result()); | 
|  | 503   PASS(); | 
|  | 504 | 
|  | 505   // Write something else to the mapped region, then unmap, and see if it | 
|  | 506   // gets written to both files. (Note we have to Unmap to make sure that the | 
|  | 507   // write is committed). | 
|  | 508   memset(address, 'c', kNumPages * page_size); | 
|  | 509   // TODO(dmichael): I'm actually unmapping two different files in one call. | 
|  | 510   // Seems like that should be OK, right? | 
|  | 511   callback.WaitForResult( | 
|  | 512       file_mapping_if_->Unmap( | 
|  | 513           instance_->pp_instance(), address, kNumPages * page_size, | 
|  | 514           callback.GetCallback().pp_completion_callback())); | 
|  | 515   CHECK_CALLBACK_BEHAVIOR(callback); | 
|  | 516   ASSERT_EQ(PP_OK, callback.result()); | 
|  | 517   // The first and third page should have been written with 'c', but the | 
|  | 518   // second page should be untouched. | 
|  | 519   std::string expected_file_contents1 = std::string(page_size, 'c') + | 
|  | 520                                         std::string(page_size, 'a') + | 
|  | 521                                         std::string(page_size, 'c'); | 
|  | 522   std::string new_file_contents1; | 
|  | 523   ASSERT_EQ(PP_OK, ReadEntireFile(instance_->pp_instance(), | 
|  | 524                                   &file_io1, | 
|  | 525                                   0, | 
|  | 526                                   &new_file_contents1, | 
|  | 527                                   callback_type())); | 
|  | 528   ASSERT_EQ(expected_file_contents1, new_file_contents1); | 
|  | 529 | 
|  | 530   // The second file should have been entirely over-written. | 
|  | 531   std::string expected_file_contents2 = std::string(page_size, 'c'); | 
|  | 532   std::string new_file_contents2; | 
|  | 533   ASSERT_EQ(PP_OK, ReadEntireFile(instance_->pp_instance(), | 
|  | 534                                   &file_io2, | 
|  | 535                                   0, | 
|  | 536                                   &new_file_contents2, | 
|  | 537                                   callback_type())); | 
|  | 538   ASSERT_EQ(expected_file_contents2, new_file_contents2); | 
|  | 539 | 
|  | 540   // TODO(dmichael): Test non-zero offset | 
|  | 541 } | 
|  | 542 | 
| OLD | NEW | 
|---|