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