Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Side by Side Diff: src/core/SkData.cpp

Issue 14336003: Move MMap to SkData. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Work on Linux. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « include/core/SkData.h ('k') | src/core/SkStream.cpp » ('j') | src/core/SkStream.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698