1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkTypes.h"
9 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
10 
11 #include "SkCGUtils.h"
12 #include "SkStream.h"
13 
14 // These are used by CGDataProviderCreateWithData
15 
unref_proc(void * info,const void * addr,size_t size)16 static void unref_proc(void* info, const void* addr, size_t size) {
17     SkASSERT(info);
18     ((SkRefCnt*)info)->unref();
19 }
20 
delete_stream_proc(void * info,const void * addr,size_t size)21 static void delete_stream_proc(void* info, const void* addr, size_t size) {
22     SkASSERT(info);
23     SkStream* stream = (SkStream*)info;
24     SkASSERT(stream->getMemoryBase() == addr);
25     SkASSERT(stream->getLength() == size);
26     delete stream;
27 }
28 
29 // These are used by CGDataProviderSequentialCallbacks
30 
get_bytes_proc(void * info,void * buffer,size_t bytes)31 static size_t get_bytes_proc(void* info, void* buffer, size_t bytes) {
32     SkASSERT(info);
33     return ((SkStream*)info)->read(buffer, bytes);
34 }
35 
skip_forward_proc(void * info,off_t bytes)36 static off_t skip_forward_proc(void* info, off_t bytes) {
37     return ((SkStream*)info)->skip((size_t) bytes);
38 }
39 
rewind_proc(void * info)40 static void rewind_proc(void* info) {
41     SkASSERT(info);
42     ((SkStream*)info)->rewind();
43 }
44 
45 // Used when info is an SkStream.
release_info_proc(void * info)46 static void release_info_proc(void* info) {
47     SkASSERT(info);
48     delete (SkStream*)info;
49 }
50 
SkCreateDataProviderFromStream(SkStream * stream)51 CGDataProviderRef SkCreateDataProviderFromStream(SkStream* stream) {
52     // TODO: Replace with SkStream::getData() when that is added. Then we only
53     // have one version of CGDataProviderCreateWithData (i.e. same release proc)
54     const void* addr = stream->getMemoryBase();
55     if (addr) {
56         // special-case when the stream is just a block of ram
57         return CGDataProviderCreateWithData(stream, addr, stream->getLength(),
58                                             delete_stream_proc);
59     }
60 
61     CGDataProviderSequentialCallbacks rec;
62     sk_bzero(&rec, sizeof(rec));
63     rec.version = 0;
64     rec.getBytes = get_bytes_proc;
65     rec.skipForward = skip_forward_proc;
66     rec.rewind = rewind_proc;
67     rec.releaseInfo = release_info_proc;
68     return CGDataProviderCreateSequential(stream, &rec);
69 }
70 
71 ///////////////////////////////////////////////////////////////////////////////
72 
73 #include "SkData.h"
74 
SkCreateDataProviderFromData(SkData * data)75 CGDataProviderRef SkCreateDataProviderFromData(SkData* data) {
76     data->ref();
77     return CGDataProviderCreateWithData(data, data->data(), data->size(),
78                                             unref_proc);
79 }
80 
81 #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
82