Home | History | Annotate | Download | only in images
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #include "SkStream.h"
      9 #include <unistd.h>
     10 
     11 //#define TRACE_FDSTREAM
     12 
     13 SkFDStream::SkFDStream(int fileDesc, bool closeWhenDone)
     14     : fFD(fileDesc), fCloseWhenDone(closeWhenDone) {
     15 }
     16 
     17 SkFDStream::~SkFDStream() {
     18     if (fFD >= 0 && fCloseWhenDone) {
     19         ::close(fFD);
     20     }
     21 }
     22 
     23 bool SkFDStream::rewind() {
     24     if (fFD >= 0) {
     25         off_t value = ::lseek(fFD, 0, SEEK_SET);
     26 #ifdef TRACE_FDSTREAM
     27         if (value) {
     28             SkDebugf("xxxxxxxxxxxxxx rewind failed %d\n", value);
     29         }
     30 #endif
     31         return value == 0;
     32     }
     33     return false;
     34 }
     35 
     36 size_t SkFDStream::read(void* buffer, size_t size) {
     37     if (fFD >= 0) {
     38         if (buffer == NULL && size == 0) {  // request total size
     39             off_t curr = ::lseek(fFD, 0, SEEK_CUR);
     40             if (curr < 0) {
     41 #ifdef TRACE_FDSTREAM
     42                 SkDebugf("xxxxxxxxxxxxx lseek failed 0 CURR\n");
     43 #endif
     44                 return 0;   // error
     45             }
     46             off_t size = ::lseek(fFD, 0, SEEK_END);
     47             if (size < 0) {
     48 #ifdef TRACE_FDSTREAM
     49                 SkDebugf("xxxxxxxxxxxxx lseek failed 0 END\n");
     50 #endif
     51                 size = 0;   // error
     52             }
     53             if (::lseek(fFD, curr, SEEK_SET) != curr) {
     54                 // can't restore, error
     55 #ifdef TRACE_FDSTREAM
     56                 SkDebugf("xxxxxxxxxxxxx lseek failed %d SET\n", curr);
     57 #endif
     58                 return 0;
     59             }
     60             return size;
     61         } else if (NULL == buffer) {        // skip
     62             off_t oldCurr = ::lseek(fFD, 0, SEEK_CUR);
     63             if (oldCurr < 0) {
     64 #ifdef TRACE_FDSTREAM
     65                 SkDebugf("xxxxxxxxxxxxx lseek1 failed %d CUR\n", oldCurr);
     66 #endif
     67                 return 0;   // error;
     68             }
     69             off_t newCurr = ::lseek(fFD, size, SEEK_CUR);
     70             if (newCurr < 0) {
     71 #ifdef TRACE_FDSTREAM
     72                 SkDebugf("xxxxxxxxxxxxx lseek2 failed %d CUR\n", newCurr);
     73 #endif
     74                 return 0;   // error;
     75             }
     76             // return the actual amount we skipped
     77             return newCurr - oldCurr;
     78         } else {                            // read
     79             ssize_t actual = ::read(fFD, buffer, size);
     80             // our API can't return an error, so we return 0
     81             if (actual < 0) {
     82 #ifdef TRACE_FDSTREAM
     83                 SkDebugf("xxxxxxxxxxxxx read failed %d actual %d\n", size, actual);
     84 #endif
     85                 actual = 0;
     86             }
     87             return actual;
     88         }
     89     }
     90     return 0;
     91 }
     92 
     93