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