OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkData.h" | 8 #include "SkData.h" |
9 #include "SkFlattenableBuffers.h" | 9 #include "SkFlattenableBuffers.h" |
| 10 #include "SkOSFile.h" |
10 | 11 |
11 #if SK_MMAP_SUPPORT | 12 #if SK_MMAP_SUPPORT |
12 #include <unistd.h> | 13 #include <unistd.h> |
13 #include <sys/mman.h> | 14 #include <sys/mman.h> |
14 #include <fcntl.h> | 15 #include <fcntl.h> |
15 #include <errno.h> | 16 #include <errno.h> |
| 17 #include <unistd.h> |
| 18 #else |
| 19 #include <io.h> |
16 #endif | 20 #endif |
17 | 21 |
18 SK_DEFINE_INST_COUNT(SkData) | 22 SK_DEFINE_INST_COUNT(SkData) |
19 | 23 |
20 SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) { | 24 SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) { |
21 fPtr = ptr; | 25 fPtr = ptr; |
22 fSize = size; | 26 fSize = size; |
23 fReleaseProc = proc; | 27 fReleaseProc = proc; |
24 fReleaseProcContext = context; | 28 fReleaseProcContext = context; |
25 } | 29 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 ReleaseProc proc, void* context) { | 91 ReleaseProc proc, void* context) { |
88 return new SkData(data, length, proc, context); | 92 return new SkData(data, length, proc, context); |
89 } | 93 } |
90 | 94 |
91 // assumes context is a SkData | 95 // assumes context is a SkData |
92 static void sk_dataref_releaseproc(const void*, size_t, void* context) { | 96 static void sk_dataref_releaseproc(const void*, size_t, void* context) { |
93 SkData* src = reinterpret_cast<SkData*>(context); | 97 SkData* src = reinterpret_cast<SkData*>(context); |
94 src->unref(); | 98 src->unref(); |
95 } | 99 } |
96 | 100 |
| 101 #if SK_MMAP_SUPPORT |
| 102 |
| 103 static void sk_munmap_releaseproc(const void* addr, size_t length, void*) { |
| 104 munmap(const_cast<void*>(addr), length); |
| 105 } |
| 106 |
| 107 SkData* SkData::NewFromFILE(SkFILE* f) { |
| 108 size_t size = sk_fgetsize(f); |
| 109 if (0 == size) { |
| 110 return NULL; |
| 111 } |
| 112 |
| 113 int fd = fileno((FILE*)f); |
| 114 if (fd < 0) { |
| 115 return NULL; |
| 116 } |
| 117 |
| 118 void* addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); |
| 119 if (MAP_FAILED == addr) { |
| 120 return NULL; |
| 121 } |
| 122 |
| 123 return SkData::NewWithProc(addr, size, sk_munmap_releaseproc, NULL); |
| 124 } |
| 125 |
| 126 #elif SK_BUILD_FOR_WIN32 |
| 127 |
| 128 template <typename HandleType, HandleType InvalidValue, BOOL (WINAPI * Close)(Ha
ndleType)> |
| 129 class SkAutoTHandle : SkNoncopyable { |
| 130 public: |
| 131 SkAutoTHandle(HandleType handle) : fHandle(handle) { } |
| 132 ~SkAutoTHandle() { Close(fHandle); } |
| 133 operator HandleType() { return fHandle; } |
| 134 bool isValid() { return InvalidValue != fHandle; } |
| 135 private: |
| 136 HandleType fHandle; |
| 137 }; |
| 138 typedef SkAutoTHandle<HANDLE, INVALID_HANDLE_VALUE, CloseHandle> SkAutoWinFile; |
| 139 typedef SkAutoTHandle<HANDLE, NULL, CloseHandle> SkAutoWinMMap; |
| 140 |
| 141 static void sk_munmap_releaseproc(const void* addr, size_t, void*) { |
| 142 UnmapViewOfFile(addr); |
| 143 } |
| 144 |
| 145 SkData* SkData::NewFromFILE(SkFILE* f) { |
| 146 size_t size = sk_fgetsize(f); |
| 147 if (0 == size) { |
| 148 return NULL; |
| 149 } |
| 150 |
| 151 int fileno = _fileno((FILE*)f); |
| 152 if (fileno < 0) { |
| 153 return NULL; |
| 154 } |
| 155 |
| 156 HANDLE file = (HANDLE)_get_osfhandle(fileno); |
| 157 if (INVALID_HANDLE_VALUE == file) { |
| 158 return NULL; |
| 159 } |
| 160 |
| 161 SkAutoWinMMap mmap(CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL))
; |
| 162 if (!mmap.isValid()) { |
| 163 //TODO: use SK_TRACEHR(GetLastError(), "Could not create file mapping.")
to report. |
| 164 return NULL; |
| 165 } |
| 166 |
| 167 // Eventually call UnmapViewOfFile |
| 168 void* addr = MapViewOfFile(mmap, FILE_MAP_READ, 0, 0, 0); |
| 169 if (NULL == addr) { |
| 170 //TODO: use SK_TRACEHR(GetLastError(), "Could not map view of file.") to
report. |
| 171 return NULL; |
| 172 } |
| 173 |
| 174 return SkData::NewWithProc(addr, size, sk_munmap_releaseproc, NULL); |
| 175 } |
| 176 |
| 177 #else |
| 178 |
| 179 SkData* SkData::NewFromFILE(SkFILE* f) { |
| 180 return NULL; |
| 181 } |
| 182 |
| 183 #endif |
| 184 |
97 SkData* SkData::NewSubset(const SkData* src, size_t offset, size_t length) { | 185 SkData* SkData::NewSubset(const SkData* src, size_t offset, size_t length) { |
98 /* | 186 /* |
99 We could, if we wanted/need to, just make a deep copy of src's data, | 187 We could, if we wanted/need to, just make a deep copy of src's data, |
100 rather than referencing it. This would duplicate the storage (of the | 188 rather than referencing it. This would duplicate the storage (of the |
101 subset amount) but would possibly allow src to go out of scope sooner. | 189 subset amount) but would possibly allow src to go out of scope sooner. |
102 */ | 190 */ |
103 | 191 |
104 size_t available = src->size(); | 192 size_t available = src->size(); |
105 if (offset >= available || 0 == length) { | 193 if (offset >= available || 0 == length) { |
106 return SkData::NewEmpty(); | 194 return SkData::NewEmpty(); |
(...skipping 13 matching lines...) Expand all Loading... |
120 size_t size; | 208 size_t size; |
121 if (NULL == cstr) { | 209 if (NULL == cstr) { |
122 cstr = ""; | 210 cstr = ""; |
123 size = 1; | 211 size = 1; |
124 } else { | 212 } else { |
125 size = strlen(cstr) + 1; | 213 size = strlen(cstr) + 1; |
126 } | 214 } |
127 return NewWithCopy(cstr, size); | 215 return NewWithCopy(cstr, size); |
128 } | 216 } |
129 | 217 |
130 #if SK_MMAP_SUPPORT | |
131 static void sk_munmap_releaseproc(const void* addr, size_t length, void*) { | |
132 munmap(const_cast<void*>(addr), length); | |
133 } | |
134 | |
135 SkData* SkData::NewFromMMap(const void* addr, size_t length) { | |
136 return SkNEW_ARGS(SkData, (addr, length, sk_munmap_releaseproc, NULL)); | |
137 } | |
138 #else | |
139 SkData* SkData::NewFromMMap(const void* addr, size_t length) { | |
140 return NULL; | |
141 } | |
142 #endif | |
143 | |
144 /////////////////////////////////////////////////////////////////////////////// | 218 /////////////////////////////////////////////////////////////////////////////// |
145 | 219 |
146 void SkData::flatten(SkFlattenableWriteBuffer& buffer) const { | 220 void SkData::flatten(SkFlattenableWriteBuffer& buffer) const { |
147 buffer.writeByteArray(fPtr, fSize); | 221 buffer.writeByteArray(fPtr, fSize); |
148 } | 222 } |
149 | 223 |
150 SkData::SkData(SkFlattenableReadBuffer& buffer) { | 224 SkData::SkData(SkFlattenableReadBuffer& buffer) { |
151 fSize = buffer.getArrayCount(); | 225 fSize = buffer.getArrayCount(); |
152 fReleaseProcContext = NULL; | 226 fReleaseProcContext = NULL; |
153 | 227 |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 } | 388 } |
315 | 389 |
316 SkDataSet* SkDataSet::NewEmpty() { | 390 SkDataSet* SkDataSet::NewEmpty() { |
317 static SkDataSet* gEmptySet; | 391 static SkDataSet* gEmptySet; |
318 if (NULL == gEmptySet) { | 392 if (NULL == gEmptySet) { |
319 gEmptySet = SkNEW_ARGS(SkDataSet, (NULL, 0)); | 393 gEmptySet = SkNEW_ARGS(SkDataSet, (NULL, 0)); |
320 } | 394 } |
321 gEmptySet->ref(); | 395 gEmptySet->ref(); |
322 return gEmptySet; | 396 return gEmptySet; |
323 } | 397 } |
OLD | NEW |