| // Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 
 | // | 
 | // Use of this source code is governed by a BSD-style license | 
 | // that can be found in the LICENSE file in the root of the source | 
 | // tree. An additional intellectual property rights grant can be found | 
 | // in the file PATENTS.  All contributing project authors may | 
 | // be found in the AUTHORS file in the root of the source tree. | 
 | #include "mkvparser/mkvreader.h" | 
 |  | 
 | #include <sys/types.h> | 
 |  | 
 | #include <cassert> | 
 |  | 
 | namespace mkvparser { | 
 |  | 
 | MkvReader::MkvReader() : m_file(NULL), reader_owns_file_(true) {} | 
 |  | 
 | MkvReader::MkvReader(FILE* fp) : m_file(fp), reader_owns_file_(false) { | 
 |   GetFileSize(); | 
 | } | 
 |  | 
 | MkvReader::~MkvReader() { | 
 |   if (reader_owns_file_) | 
 |     Close(); | 
 |   m_file = NULL; | 
 | } | 
 |  | 
 | int MkvReader::Open(const char* fileName) { | 
 |   if (fileName == NULL) | 
 |     return -1; | 
 |  | 
 |   if (m_file) | 
 |     return -1; | 
 |  | 
 | #ifdef _MSC_VER | 
 |   const errno_t e = fopen_s(&m_file, fileName, "rb"); | 
 |  | 
 |   if (e) | 
 |     return -1;  // error | 
 | #else | 
 |   m_file = fopen(fileName, "rb"); | 
 |  | 
 |   if (m_file == NULL) | 
 |     return -1; | 
 | #endif | 
 |   return !GetFileSize(); | 
 | } | 
 |  | 
 | bool MkvReader::GetFileSize() { | 
 |   if (m_file == NULL) | 
 |     return false; | 
 | #ifdef _MSC_VER | 
 |   int status = _fseeki64(m_file, 0L, SEEK_END); | 
 |  | 
 |   if (status) | 
 |     return false;  // error | 
 |  | 
 |   m_length = _ftelli64(m_file); | 
 | #else | 
 |   fseek(m_file, 0L, SEEK_END); | 
 |   m_length = ftell(m_file); | 
 | #endif | 
 |   assert(m_length >= 0); | 
 |  | 
 |   if (m_length < 0) | 
 |     return false; | 
 |  | 
 | #ifdef _MSC_VER | 
 |   status = _fseeki64(m_file, 0L, SEEK_SET); | 
 |  | 
 |   if (status) | 
 |     return false;  // error | 
 | #else | 
 |   fseek(m_file, 0L, SEEK_SET); | 
 | #endif | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | void MkvReader::Close() { | 
 |   if (m_file != NULL) { | 
 |     fclose(m_file); | 
 |     m_file = NULL; | 
 |   } | 
 | } | 
 |  | 
 | int MkvReader::Length(long long* total, long long* available) { | 
 |   if (m_file == NULL) | 
 |     return -1; | 
 |  | 
 |   if (total) | 
 |     *total = m_length; | 
 |  | 
 |   if (available) | 
 |     *available = m_length; | 
 |  | 
 |   return 0; | 
 | } | 
 |  | 
 | int MkvReader::Read(long long offset, long len, unsigned char* buffer) { | 
 |   if (m_file == NULL) | 
 |     return -1; | 
 |  | 
 |   if (offset < 0) | 
 |     return -1; | 
 |  | 
 |   if (len < 0) | 
 |     return -1; | 
 |  | 
 |   if (len == 0) | 
 |     return 0; | 
 |  | 
 |   if (offset >= m_length) | 
 |     return -1; | 
 |  | 
 | #ifdef _MSC_VER | 
 |   const int status = _fseeki64(m_file, offset, SEEK_SET); | 
 |  | 
 |   if (status) | 
 |     return -1;  // error | 
 | #elif defined(_WIN32) | 
 |   fseeko64(m_file, static_cast<off_t>(offset), SEEK_SET); | 
 | #else | 
 |   fseeko(m_file, static_cast<off_t>(offset), SEEK_SET); | 
 | #endif | 
 |  | 
 |   const size_t size = fread(buffer, 1, len, m_file); | 
 |  | 
 |   if (size < size_t(len)) | 
 |     return -1;  // error | 
 |  | 
 |   return 0;  // success | 
 | } | 
 |  | 
 | }  // namespace mkvparser |