10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStream.h" 20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include <unistd.h> 30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//#define TRACE_FDSTREAM 50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFDStream::SkFDStream(int fileDesc, bool closeWhenDone) 70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : fFD(fileDesc), fCloseWhenDone(closeWhenDone) { 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFDStream::~SkFDStream() { 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fFD >= 0 && fCloseWhenDone) { 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ::close(fFD); 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkFDStream::rewind() { 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fFD >= 0) { 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project off_t value = ::lseek(fFD, 0, SEEK_SET); 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef TRACE_FDSTREAM 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (value) { 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf("xxxxxxxxxxxxxx rewind failed %d\n", value); 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return value == 0; 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkFDStream::read(void* buffer, size_t size) { 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fFD >= 0) { 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (buffer == NULL && size == 0) { // request total size 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project off_t curr = ::lseek(fFD, 0, SEEK_CUR); 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (curr < 0) { 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef TRACE_FDSTREAM 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf("xxxxxxxxxxxxx lseek failed 0 CURR\n"); 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; // error 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project off_t size = ::lseek(fFD, 0, SEEK_END); 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (size < 0) { 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef TRACE_FDSTREAM 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf("xxxxxxxxxxxxx lseek failed 0 END\n"); 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project size = 0; // error 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (::lseek(fFD, curr, SEEK_SET) != curr) { 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // can't restore, error 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef TRACE_FDSTREAM 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf("xxxxxxxxxxxxx lseek failed %d SET\n", curr); 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return size; 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else if (NULL == buffer) { // skip 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project off_t oldCurr = ::lseek(fFD, 0, SEEK_CUR); 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (oldCurr < 0) { 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef TRACE_FDSTREAM 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf("xxxxxxxxxxxxx lseek1 failed %d CUR\n", oldCurr); 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; // error; 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project off_t newCurr = ::lseek(fFD, size, SEEK_CUR); 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (newCurr < 0) { 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef TRACE_FDSTREAM 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf("xxxxxxxxxxxxx lseek2 failed %d CUR\n", newCurr); 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; // error; 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // return the actual amount we skipped 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return newCurr - oldCurr; 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { // read 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ssize_t actual = ::read(fFD, buffer, size); 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // our API can't return an error, so we return 0 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (actual < 0) { 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef TRACE_FDSTREAM 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDebugf("xxxxxxxxxxxxx read failed %d actual %d\n", size, actual); 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project actual = 0; 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return actual; 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 86