/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkStream.h" #include <unistd.h> //#define TRACE_FDSTREAM SkFDStream::SkFDStream(int fileDesc, bool closeWhenDone) : fFD(fileDesc), fCloseWhenDone(closeWhenDone) { } SkFDStream::~SkFDStream() { if (fFD >= 0 && fCloseWhenDone) { ::close(fFD); } } bool SkFDStream::rewind() { if (fFD >= 0) { off_t value = ::lseek(fFD, 0, SEEK_SET); #ifdef TRACE_FDSTREAM if (value) { SkDebugf("xxxxxxxxxxxxxx rewind failed %d\n", value); } #endif return value == 0; } return false; } size_t SkFDStream::read(void* buffer, size_t size) { if (fFD >= 0) { if (buffer == NULL && size == 0) { // request total size off_t curr = ::lseek(fFD, 0, SEEK_CUR); if (curr < 0) { #ifdef TRACE_FDSTREAM SkDebugf("xxxxxxxxxxxxx lseek failed 0 CURR\n"); #endif return 0; // error } off_t size = ::lseek(fFD, 0, SEEK_END); if (size < 0) { #ifdef TRACE_FDSTREAM SkDebugf("xxxxxxxxxxxxx lseek failed 0 END\n"); #endif size = 0; // error } if (::lseek(fFD, curr, SEEK_SET) != curr) { // can't restore, error #ifdef TRACE_FDSTREAM SkDebugf("xxxxxxxxxxxxx lseek failed %d SET\n", curr); #endif return 0; } return (size_t) size; } else if (NULL == buffer) { // skip off_t oldCurr = ::lseek(fFD, 0, SEEK_CUR); if (oldCurr < 0) { #ifdef TRACE_FDSTREAM SkDebugf("xxxxxxxxxxxxx lseek1 failed %d CUR\n", oldCurr); #endif return 0; // error; } off_t newCurr = ::lseek(fFD, size, SEEK_CUR); if (newCurr < 0) { #ifdef TRACE_FDSTREAM SkDebugf("xxxxxxxxxxxxx lseek2 failed %d CUR\n", newCurr); #endif return 0; // error; } // return the actual amount we skipped return (size_t) (newCurr - oldCurr); } else { // read ssize_t actual = ::read(fFD, buffer, size); // our API can't return an error, so we return 0 if (actual < 0) { #ifdef TRACE_FDSTREAM SkDebugf("xxxxxxxxxxxxx read failed %d actual %d\n", size, actual); #endif actual = 0; } return actual; } } return 0; }