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 14namespace mkvparser { 15 16MkvReader::MkvReader() : m_file(NULL), reader_owns_file_(true) {} 17 18MkvReader::MkvReader(FILE* fp) : m_file(fp), reader_owns_file_(false) { 19 GetFileSize(); 20} 21 22MkvReader::~MkvReader() { 23 if (reader_owns_file_) 24 Close(); 25 m_file = NULL; 26} 27 28int 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 49bool 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 80void MkvReader::Close() { 81 if (m_file != NULL) { 82 fclose(m_file); 83 m_file = NULL; 84 } 85} 86 87int 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 100int 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