1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2010 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker *
4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker *
8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker *
10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker */
16*d57664e9SAndroid Build Coastguard Worker
17*d57664e9SAndroid Build Coastguard Worker #include "Utils.h"
18*d57664e9SAndroid Build Coastguard Worker #include "SkData.h"
19*d57664e9SAndroid Build Coastguard Worker #include "SkRefCnt.h"
20*d57664e9SAndroid Build Coastguard Worker #include "SkStream.h"
21*d57664e9SAndroid Build Coastguard Worker
22*d57664e9SAndroid Build Coastguard Worker #include <inttypes.h>
23*d57664e9SAndroid Build Coastguard Worker #include <log/log.h>
24*d57664e9SAndroid Build Coastguard Worker
25*d57664e9SAndroid Build Coastguard Worker using namespace android;
26*d57664e9SAndroid Build Coastguard Worker
AssetStreamAdaptor(Asset * asset)27*d57664e9SAndroid Build Coastguard Worker AssetStreamAdaptor::AssetStreamAdaptor(Asset* asset)
28*d57664e9SAndroid Build Coastguard Worker : fAsset(asset)
29*d57664e9SAndroid Build Coastguard Worker {
30*d57664e9SAndroid Build Coastguard Worker }
31*d57664e9SAndroid Build Coastguard Worker
rewind()32*d57664e9SAndroid Build Coastguard Worker bool AssetStreamAdaptor::rewind() {
33*d57664e9SAndroid Build Coastguard Worker off64_t pos = fAsset->seek(0, SEEK_SET);
34*d57664e9SAndroid Build Coastguard Worker if (pos == (off64_t)-1) {
35*d57664e9SAndroid Build Coastguard Worker ALOGD("----- fAsset->seek(rewind) failed\n");
36*d57664e9SAndroid Build Coastguard Worker return false;
37*d57664e9SAndroid Build Coastguard Worker }
38*d57664e9SAndroid Build Coastguard Worker return true;
39*d57664e9SAndroid Build Coastguard Worker }
40*d57664e9SAndroid Build Coastguard Worker
getLength() const41*d57664e9SAndroid Build Coastguard Worker size_t AssetStreamAdaptor::getLength() const {
42*d57664e9SAndroid Build Coastguard Worker return fAsset->getLength();
43*d57664e9SAndroid Build Coastguard Worker }
44*d57664e9SAndroid Build Coastguard Worker
isAtEnd() const45*d57664e9SAndroid Build Coastguard Worker bool AssetStreamAdaptor::isAtEnd() const {
46*d57664e9SAndroid Build Coastguard Worker return fAsset->getRemainingLength() == 0;
47*d57664e9SAndroid Build Coastguard Worker }
48*d57664e9SAndroid Build Coastguard Worker
onDuplicate() const49*d57664e9SAndroid Build Coastguard Worker SkStreamRewindable* AssetStreamAdaptor::onDuplicate() const {
50*d57664e9SAndroid Build Coastguard Worker // Cannot create a duplicate, since each AssetStreamAdaptor
51*d57664e9SAndroid Build Coastguard Worker // would be modifying the Asset.
52*d57664e9SAndroid Build Coastguard Worker //return new AssetStreamAdaptor(fAsset);
53*d57664e9SAndroid Build Coastguard Worker return NULL;
54*d57664e9SAndroid Build Coastguard Worker }
55*d57664e9SAndroid Build Coastguard Worker
hasPosition() const56*d57664e9SAndroid Build Coastguard Worker bool AssetStreamAdaptor::hasPosition() const {
57*d57664e9SAndroid Build Coastguard Worker return fAsset->seek(0, SEEK_CUR) != -1;
58*d57664e9SAndroid Build Coastguard Worker }
59*d57664e9SAndroid Build Coastguard Worker
getPosition() const60*d57664e9SAndroid Build Coastguard Worker size_t AssetStreamAdaptor::getPosition() const {
61*d57664e9SAndroid Build Coastguard Worker const off64_t offset = fAsset->seek(0, SEEK_CUR);
62*d57664e9SAndroid Build Coastguard Worker if (offset == -1) {
63*d57664e9SAndroid Build Coastguard Worker ALOGD("---- fAsset->seek(0, SEEK_CUR) failed\n");
64*d57664e9SAndroid Build Coastguard Worker return 0;
65*d57664e9SAndroid Build Coastguard Worker }
66*d57664e9SAndroid Build Coastguard Worker
67*d57664e9SAndroid Build Coastguard Worker return offset;
68*d57664e9SAndroid Build Coastguard Worker }
69*d57664e9SAndroid Build Coastguard Worker
seek(size_t position)70*d57664e9SAndroid Build Coastguard Worker bool AssetStreamAdaptor::seek(size_t position) {
71*d57664e9SAndroid Build Coastguard Worker if (fAsset->seek(position, SEEK_SET) == -1) {
72*d57664e9SAndroid Build Coastguard Worker ALOGD("---- fAsset->seek(0, SEEK_SET) failed\n");
73*d57664e9SAndroid Build Coastguard Worker return false;
74*d57664e9SAndroid Build Coastguard Worker }
75*d57664e9SAndroid Build Coastguard Worker
76*d57664e9SAndroid Build Coastguard Worker return true;
77*d57664e9SAndroid Build Coastguard Worker }
78*d57664e9SAndroid Build Coastguard Worker
move(long offset)79*d57664e9SAndroid Build Coastguard Worker bool AssetStreamAdaptor::move(long offset) {
80*d57664e9SAndroid Build Coastguard Worker if (fAsset->seek(offset, SEEK_CUR) == -1) {
81*d57664e9SAndroid Build Coastguard Worker ALOGD("---- fAsset->seek(%li, SEEK_CUR) failed\n", offset);
82*d57664e9SAndroid Build Coastguard Worker return false;
83*d57664e9SAndroid Build Coastguard Worker }
84*d57664e9SAndroid Build Coastguard Worker
85*d57664e9SAndroid Build Coastguard Worker return true;
86*d57664e9SAndroid Build Coastguard Worker }
87*d57664e9SAndroid Build Coastguard Worker
read(void * buffer,size_t size)88*d57664e9SAndroid Build Coastguard Worker size_t AssetStreamAdaptor::read(void* buffer, size_t size) {
89*d57664e9SAndroid Build Coastguard Worker ssize_t amount;
90*d57664e9SAndroid Build Coastguard Worker
91*d57664e9SAndroid Build Coastguard Worker if (NULL == buffer) {
92*d57664e9SAndroid Build Coastguard Worker if (0 == size) {
93*d57664e9SAndroid Build Coastguard Worker return 0;
94*d57664e9SAndroid Build Coastguard Worker }
95*d57664e9SAndroid Build Coastguard Worker // asset->seek returns new total offset
96*d57664e9SAndroid Build Coastguard Worker // we want to return amount that was skipped
97*d57664e9SAndroid Build Coastguard Worker
98*d57664e9SAndroid Build Coastguard Worker off64_t oldOffset = fAsset->seek(0, SEEK_CUR);
99*d57664e9SAndroid Build Coastguard Worker if (-1 == oldOffset) {
100*d57664e9SAndroid Build Coastguard Worker ALOGD("---- fAsset->seek(oldOffset) failed\n");
101*d57664e9SAndroid Build Coastguard Worker return 0;
102*d57664e9SAndroid Build Coastguard Worker }
103*d57664e9SAndroid Build Coastguard Worker off64_t newOffset = fAsset->seek(size, SEEK_CUR);
104*d57664e9SAndroid Build Coastguard Worker if (-1 == newOffset) {
105*d57664e9SAndroid Build Coastguard Worker ALOGD("---- fAsset->seek(%zu) failed\n", size);
106*d57664e9SAndroid Build Coastguard Worker return 0;
107*d57664e9SAndroid Build Coastguard Worker }
108*d57664e9SAndroid Build Coastguard Worker amount = newOffset - oldOffset;
109*d57664e9SAndroid Build Coastguard Worker } else {
110*d57664e9SAndroid Build Coastguard Worker amount = fAsset->read(buffer, size);
111*d57664e9SAndroid Build Coastguard Worker }
112*d57664e9SAndroid Build Coastguard Worker
113*d57664e9SAndroid Build Coastguard Worker if (amount < 0) {
114*d57664e9SAndroid Build Coastguard Worker amount = 0;
115*d57664e9SAndroid Build Coastguard Worker }
116*d57664e9SAndroid Build Coastguard Worker return amount;
117*d57664e9SAndroid Build Coastguard Worker }
118*d57664e9SAndroid Build Coastguard Worker
CopyAssetToData(Asset * asset)119*d57664e9SAndroid Build Coastguard Worker sk_sp<SkData> android::CopyAssetToData(Asset* asset) {
120*d57664e9SAndroid Build Coastguard Worker if (NULL == asset) {
121*d57664e9SAndroid Build Coastguard Worker return NULL;
122*d57664e9SAndroid Build Coastguard Worker }
123*d57664e9SAndroid Build Coastguard Worker
124*d57664e9SAndroid Build Coastguard Worker const off64_t seekReturnVal = asset->seek(0, SEEK_SET);
125*d57664e9SAndroid Build Coastguard Worker if ((off64_t)-1 == seekReturnVal) {
126*d57664e9SAndroid Build Coastguard Worker ALOGD("---- copyAsset: asset rewind failed\n");
127*d57664e9SAndroid Build Coastguard Worker return NULL;
128*d57664e9SAndroid Build Coastguard Worker }
129*d57664e9SAndroid Build Coastguard Worker
130*d57664e9SAndroid Build Coastguard Worker const off64_t size = asset->getLength();
131*d57664e9SAndroid Build Coastguard Worker if (size <= 0) {
132*d57664e9SAndroid Build Coastguard Worker ALOGD("---- copyAsset: asset->getLength() returned %" PRId64 "\n", size);
133*d57664e9SAndroid Build Coastguard Worker return NULL;
134*d57664e9SAndroid Build Coastguard Worker }
135*d57664e9SAndroid Build Coastguard Worker
136*d57664e9SAndroid Build Coastguard Worker sk_sp<SkData> data(SkData::MakeUninitialized(size));
137*d57664e9SAndroid Build Coastguard Worker const off64_t len = asset->read(data->writable_data(), size);
138*d57664e9SAndroid Build Coastguard Worker if (len != size) {
139*d57664e9SAndroid Build Coastguard Worker ALOGD("---- copyAsset: asset->read(%" PRId64 ") returned %" PRId64 "\n", size, len);
140*d57664e9SAndroid Build Coastguard Worker return NULL;
141*d57664e9SAndroid Build Coastguard Worker }
142*d57664e9SAndroid Build Coastguard Worker
143*d57664e9SAndroid Build Coastguard Worker return data;
144*d57664e9SAndroid Build Coastguard Worker }
145*d57664e9SAndroid Build Coastguard Worker
nullObjectReturn(const char msg[])146*d57664e9SAndroid Build Coastguard Worker jobject android::nullObjectReturn(const char msg[]) {
147*d57664e9SAndroid Build Coastguard Worker if (msg) {
148*d57664e9SAndroid Build Coastguard Worker ALOGD("--- %s\n", msg);
149*d57664e9SAndroid Build Coastguard Worker }
150*d57664e9SAndroid Build Coastguard Worker return NULL;
151*d57664e9SAndroid Build Coastguard Worker }
152*d57664e9SAndroid Build Coastguard Worker
isSeekable(int descriptor)153*d57664e9SAndroid Build Coastguard Worker bool android::isSeekable(int descriptor) {
154*d57664e9SAndroid Build Coastguard Worker return ::lseek64(descriptor, 0, SEEK_CUR) != -1;
155*d57664e9SAndroid Build Coastguard Worker }
156*d57664e9SAndroid Build Coastguard Worker
get_env_or_die(JavaVM * jvm)157*d57664e9SAndroid Build Coastguard Worker JNIEnv* android::get_env_or_die(JavaVM* jvm) {
158*d57664e9SAndroid Build Coastguard Worker JNIEnv* env;
159*d57664e9SAndroid Build Coastguard Worker if (jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
160*d57664e9SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", jvm);
161*d57664e9SAndroid Build Coastguard Worker }
162*d57664e9SAndroid Build Coastguard Worker return env;
163*d57664e9SAndroid Build Coastguard Worker }
164*d57664e9SAndroid Build Coastguard Worker
requireEnv(JavaVM * jvm)165*d57664e9SAndroid Build Coastguard Worker JNIEnv* android::requireEnv(JavaVM* jvm) {
166*d57664e9SAndroid Build Coastguard Worker JNIEnv* env;
167*d57664e9SAndroid Build Coastguard Worker if (jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
168*d57664e9SAndroid Build Coastguard Worker if (jvm->AttachCurrentThreadAsDaemon(&env, nullptr) != JNI_OK) {
169*d57664e9SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("Failed to AttachCurrentThread!");
170*d57664e9SAndroid Build Coastguard Worker }
171*d57664e9SAndroid Build Coastguard Worker }
172*d57664e9SAndroid Build Coastguard Worker return env;
173*d57664e9SAndroid Build Coastguard Worker }
174