Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 * Use of this source code is governed by a BSD-style license that can be |
| 3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
| 4 */ | 4 */ |
| 5 #include "nacl_io/mount_node_mem.h" | 5 #include "nacl_io/mount_node_mem.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include "nacl_io/osstat.h" | 10 #include "nacl_io/osstat.h" |
| 11 #include "utils/auto_lock.h" | 11 #include "utils/auto_lock.h" |
| 12 | 12 |
| 13 #define BLOCK_SIZE (1 << 16) | 13 #define BLOCK_SIZE (1 << 16) |
| 14 #define BLOCK_MASK (BLOCK_SIZE - 1) | 14 #define BLOCK_MASK (BLOCK_SIZE - 1) |
| 15 | 15 |
| 16 MountNodeMem::MountNodeMem(Mount *mount) | 16 MountNodeMem::MountNodeMem(Mount* mount) |
| 17 : MountNode(mount), | 17 : MountNode(mount), data_(NULL), capacity_(0) { |
| 18 data_(NULL), | |
| 19 capacity_(0) { | |
| 20 stat_.st_mode |= S_IFREG; | 18 stat_.st_mode |= S_IFREG; |
| 21 } | 19 } |
| 22 | 20 |
| 23 MountNodeMem::~MountNodeMem() { | 21 MountNodeMem::~MountNodeMem() { free(data_); } |
| 24 free(data_); | |
| 25 } | |
| 26 | 22 |
| 27 int MountNodeMem::Read(size_t offs, void *buf, size_t count) { | 23 Error MountNodeMem::Read(size_t offs, void* buf, size_t count, int* out_bytes) { |
| 24 *out_bytes = 0; | |
| 25 | |
| 28 AutoLock lock(&lock_); | 26 AutoLock lock(&lock_); |
| 29 if (count == 0) return 0; | 27 if (count == 0) |
| 30 if (offs + count > GetSize()) { | 28 return 0; |
| 31 count = GetSize() - offs; | 29 |
| 30 size_t size = stat_.st_size; | |
| 31 | |
| 32 if (offs + count > size) { | |
| 33 count = size - offs; | |
| 32 } | 34 } |
| 33 | 35 |
| 34 memcpy(buf, &data_[offs], count); | 36 memcpy(buf, &data_[offs], count); |
| 35 return static_cast<int>(count); | 37 *out_bytes = static_cast<int>(count); |
| 38 return 0; | |
| 36 } | 39 } |
| 37 | 40 |
| 38 int MountNodeMem::Write(size_t offs, const void *buf, size_t count) { | 41 Error MountNodeMem::Write(size_t offs, |
| 42 const void* buf, | |
| 43 size_t count, | |
| 44 int* out_bytes) { | |
| 45 *out_bytes = 0; | |
| 46 | |
| 39 AutoLock lock(&lock_); | 47 AutoLock lock(&lock_); |
| 40 | 48 |
| 41 if (count == 0) return 0; | 49 if (count == 0) |
| 50 return 0; | |
| 42 | 51 |
| 43 if (count + offs > GetSize()) { | 52 if (count + offs > stat_.st_size) { |
| 44 FTruncate(count + offs); | 53 Error error = FTruncate(count + offs); |
| 45 count = GetSize() - offs; | 54 if (error) |
| 55 return error; | |
| 56 | |
| 57 count = stat_.st_size - offs; | |
| 46 } | 58 } |
| 47 | 59 |
| 48 memcpy(&data_[offs], buf, count); | 60 memcpy(&data_[offs], buf, count); |
| 49 return static_cast<int>(count); | 61 *out_bytes = static_cast<int>(count); |
| 62 return 0; | |
| 50 } | 63 } |
| 51 | 64 |
| 52 int MountNodeMem::FTruncate(off_t size) { | 65 Error MountNodeMem::FTruncate(off_t new_size) { |
| 53 size_t need = (size + BLOCK_MASK) & ~BLOCK_MASK; | 66 size_t need = (new_size + BLOCK_MASK) & ~BLOCK_MASK; |
| 67 size_t old_size = stat_.st_size; | |
|
noelallen1
2013/06/07 21:48:43
Losing virtual behavior or GetSize, is that what y
binji
2013/06/07 23:23:11
Fair point, though any derived class (none of whic
| |
| 54 | 68 |
| 55 // If the current capacity is correct, just adjust and return | 69 // If the current capacity is correct, just adjust and return |
| 56 if (need == capacity_) { | 70 if (need == capacity_) { |
| 57 stat_.st_size = static_cast<off_t>(size); | 71 stat_.st_size = static_cast<off_t>(new_size); |
| 58 return 0; | 72 return 0; |
| 59 } | 73 } |
| 60 | 74 |
| 61 // Attempt to realloc the block | 75 // Attempt to realloc the block |
| 62 char *newdata = static_cast<char *>(realloc(data_, need)); | 76 char* newdata = static_cast<char*>(realloc(data_, need)); |
| 63 if (newdata != NULL) { | 77 if (newdata != NULL) { |
| 64 // Zero out new space. | 78 // Zero out new space. |
| 65 if (size > GetSize()) | 79 if (new_size > old_size) |
| 66 memset(newdata + GetSize(), 0, size - GetSize()); | 80 memset(newdata + old_size, 0, new_size - old_size); |
| 67 | 81 |
| 68 data_ = newdata; | 82 data_ = newdata; |
| 69 capacity_ = need; | 83 capacity_ = need; |
| 70 stat_.st_size = static_cast<off_t>(size); | 84 stat_.st_size = static_cast<off_t>(new_size); |
| 71 return 0; | 85 return 0; |
| 72 } | 86 } |
| 73 | 87 |
| 74 // If we failed, then adjust size according to what we keep | 88 // If we failed, then adjust size according to what we keep |
| 75 if (size > capacity_) size = capacity_; | 89 if (new_size > capacity_) |
| 90 new_size = capacity_; | |
| 76 | 91 |
| 77 // Update the size and return the new size | 92 // Update the size and return the new size |
| 78 stat_.st_size = static_cast<off_t>(size); | 93 stat_.st_size = static_cast<off_t>(new_size); |
| 79 errno = EIO; | 94 return EIO; |
| 80 return -1; | |
| 81 } | 95 } |
| OLD | NEW |