Home | History | Annotate | Download | only in mkvparser
      1 // Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style license
      4 // that can be found in the LICENSE file in the root of the source
      5 // tree. An additional intellectual property rights grant can be found
      6 // in the file PATENTS.  All contributing project authors may
      7 // be found in the AUTHORS file in the root of the source tree.
      8 #include "mkvparser/mkvreader.h"
      9 
     10 #include <sys/types.h>
     11 
     12 #include <cassert>
     13 
     14 namespace mkvparser {
     15 
     16 MkvReader::MkvReader() : m_file(NULL), reader_owns_file_(true) {}
     17 
     18 MkvReader::MkvReader(FILE* fp) : m_file(fp), reader_owns_file_(false) {
     19   GetFileSize();
     20 }
     21 
     22 MkvReader::~MkvReader() {
     23   if (reader_owns_file_)
     24     Close();
     25   m_file = NULL;
     26 }
     27 
     28 int MkvReader::Open(const char* fileName) {
     29   if (fileName == NULL)
     30     return -1;
     31 
     32   if (m_file)
     33     return -1;
     34 
     35 #ifdef _MSC_VER
     36   const errno_t e = fopen_s(&m_file, fileName, "rb");
     37 
     38   if (e)
     39     return -1;  // error
     40 #else
     41   m_file = fopen(fileName, "rb");
     42 
     43   if (m_file == NULL)
     44     return -1;
     45 #endif
     46   return !GetFileSize();
     47 }
     48 
     49 bool MkvReader::GetFileSize() {
     50   if (m_file == NULL)
     51     return false;
     52 #ifdef _MSC_VER
     53   int status = _fseeki64(m_file, 0L, SEEK_END);
     54 
     55   if (status)
     56     return false;  // error
     57 
     58   m_length = _ftelli64(m_file);
     59 #else
     60   fseek(m_file, 0L, SEEK_END);
     61   m_length = ftell(m_file);
     62 #endif
     63   assert(m_length >= 0);
     64 
     65   if (m_length < 0)
     66     return false;
     67 
     68 #ifdef _MSC_VER
     69   status = _fseeki64(m_file, 0L, SEEK_SET);
     70 
     71   if (status)
     72     return false;  // error
     73 #else
     74   fseek(m_file, 0L, SEEK_SET);
     75 #endif
     76 
     77   return true;
     78 }
     79 
     80 void MkvReader::Close() {
     81   if (m_file != NULL) {
     82     fclose(m_file);
     83     m_file = NULL;
     84   }
     85 }
     86 
     87 int MkvReader::Length(long long* total, long long* available) {
     88   if (m_file == NULL)
     89     return -1;
     90 
     91   if (total)
     92     *total = m_length;
     93 
     94   if (available)
     95     *available = m_length;
     96 
     97   return 0;
     98 }
     99 
    100 int MkvReader::Read(long long offset, long len, unsigned char* buffer) {
    101   if (m_file == NULL)
    102     return -1;
    103 
    104   if (offset < 0)
    105     return -1;
    106 
    107   if (len < 0)
    108     return -1;
    109 
    110   if (len == 0)
    111     return 0;
    112 
    113   if (offset >= m_length)
    114     return -1;
    115 
    116 #ifdef _MSC_VER
    117   const int status = _fseeki64(m_file, offset, SEEK_SET);
    118 
    119   if (status)
    120     return -1;  // error
    121 #else
    122   fseeko(m_file, static_cast<off_t>(offset), SEEK_SET);
    123 #endif
    124 
    125   const size_t size = fread(buffer, 1, len, m_file);
    126 
    127   if (size < size_t(len))
    128     return -1;  // error
    129 
    130   return 0;  // success
    131 }
    132 
    133 }  // namespace mkvparser
    134