file_input_stream.cc revision fa606d4385cc0cc97f319dc25c97f46b2d44f1b9
173b526fb4af0f60634f0078583d92b931d5c0eebnethercote/*
273b526fb4af0f60634f0078583d92b931d5c0eebnethercote * Copyright 2011 Google Inc. All Rights Reserved.
34de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn *
473b526fb4af0f60634f0078583d92b931d5c0eebnethercote * Licensed under the Apache License, Version 2.0 (the "License");
573b526fb4af0f60634f0078583d92b931d5c0eebnethercote * you may not use this file except in compliance with the License.
673b526fb4af0f60634f0078583d92b931d5c0eebnethercote * You may obtain a copy of the License at
7b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn *
8b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn *      http://www.apache.org/licenses/LICENSE-2.0
973b526fb4af0f60634f0078583d92b931d5c0eebnethercote *
109f207460d70d38c46c9e81996a3dcdf90961c6dbnjn * Unless required by applicable law or agreed to in writing, software
1173b526fb4af0f60634f0078583d92b931d5c0eebnethercote * distributed under the License is distributed on an "AS IS" BASIS,
1273b526fb4af0f60634f0078583d92b931d5c0eebnethercote * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1373b526fb4af0f60634f0078583d92b931d5c0eebnethercote * See the License for the specific language governing permissions and
1473b526fb4af0f60634f0078583d92b931d5c0eebnethercote * limitations under the License.
1573b526fb4af0f60634f0078583d92b931d5c0eebnethercote */
1673b526fb4af0f60634f0078583d92b931d5c0eebnethercote
1773b526fb4af0f60634f0078583d92b931d5c0eebnethercote#if defined (WIN32)
1873b526fb4af0f60634f0078583d92b931d5c0eebnethercote#include <windows.h>
1973b526fb4af0f60634f0078583d92b931d5c0eebnethercote#endif
2073b526fb4af0f60634f0078583d92b931d5c0eebnethercote
2173b526fb4af0f60634f0078583d92b931d5c0eebnethercote#include "sfntly/port/file_input_stream.h"
2273b526fb4af0f60634f0078583d92b931d5c0eebnethercote#include "sfntly/port/exception_type.h"
2373b526fb4af0f60634f0078583d92b931d5c0eebnethercote
2473b526fb4af0f60634f0078583d92b931d5c0eebnethercotenamespace sfntly {
2573b526fb4af0f60634f0078583d92b931d5c0eebnethercote
2673b526fb4af0f60634f0078583d92b931d5c0eebnethercoteFileInputStream::FileInputStream() : file_(NULL), position_(0), length_(0) {
2773b526fb4af0f60634f0078583d92b931d5c0eebnethercote}
2873b526fb4af0f60634f0078583d92b931d5c0eebnethercote
2973b526fb4af0f60634f0078583d92b931d5c0eebnethercoteFileInputStream::~FileInputStream() {
3073b526fb4af0f60634f0078583d92b931d5c0eebnethercote  close();
3173b526fb4af0f60634f0078583d92b931d5c0eebnethercote}
3273b526fb4af0f60634f0078583d92b931d5c0eebnethercote
3373b526fb4af0f60634f0078583d92b931d5c0eebnethercoteint32_t FileInputStream::available() {
3473b526fb4af0f60634f0078583d92b931d5c0eebnethercote  return length_ - position_;
3573b526fb4af0f60634f0078583d92b931d5c0eebnethercote}
3673b526fb4af0f60634f0078583d92b931d5c0eebnethercote
3773b526fb4af0f60634f0078583d92b931d5c0eebnethercotebool FileInputStream::open(const char* file_path) {
3873b526fb4af0f60634f0078583d92b931d5c0eebnethercote  assert(file_path);
3973b526fb4af0f60634f0078583d92b931d5c0eebnethercote  if (file_) {
4073b526fb4af0f60634f0078583d92b931d5c0eebnethercote    close();
4173b526fb4af0f60634f0078583d92b931d5c0eebnethercote  }
4273b526fb4af0f60634f0078583d92b931d5c0eebnethercote#if defined (WIN32)
4373b526fb4af0f60634f0078583d92b931d5c0eebnethercote  fopen_s(&file_, file_path, "rb");
4473b526fb4af0f60634f0078583d92b931d5c0eebnethercote#else
4573b526fb4af0f60634f0078583d92b931d5c0eebnethercote  file_ = fopen(file_path, "rb");
4673b526fb4af0f60634f0078583d92b931d5c0eebnethercote#endif
47ac7924c7eedce947578c571ae419c4c84eaa5aefnjn  if (file_ == NULL) {
48edef146c47eda894495d2b3b71b32b10349f8d91sewardj    return false;
494de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn  }
504de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn
51ac7924c7eedce947578c571ae419c4c84eaa5aefnjn  fseek(file_, 0, SEEK_END);
52ac7924c7eedce947578c571ae419c4c84eaa5aefnjn  length_ = ftell(file_);
53ac7924c7eedce947578c571ae419c4c84eaa5aefnjn  fseek(file_, 0, SEEK_SET);
54ac7924c7eedce947578c571ae419c4c84eaa5aefnjn  return true;
55ac7924c7eedce947578c571ae419c4c84eaa5aefnjn}
5673b526fb4af0f60634f0078583d92b931d5c0eebnethercote
5773b526fb4af0f60634f0078583d92b931d5c0eebnethercotevoid FileInputStream::close() {
5873b526fb4af0f60634f0078583d92b931d5c0eebnethercote  if (file_) {
5973b526fb4af0f60634f0078583d92b931d5c0eebnethercote    fclose(file_);
604cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj    length_ = 0;
614cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj    position_ = 0;
624cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj  }
634cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj}
644cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj
654cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardjvoid FileInputStream::mark(int32_t readlimit) {
664cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj  // NOP
674cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj  UNREFERENCED_PARAMETER(readlimit);
684cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj}
694cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj
704cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardjbool FileInputStream::markSupported() {
714cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj  return false;
724cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj}
734cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj
744cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardjint32_t FileInputStream::read() {
754de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn  if (!file_) {
764de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn#if defined (SFNTLY_NO_EXCEPTION)
7773b526fb4af0f60634f0078583d92b931d5c0eebnethercote    return 0;
7873b526fb4af0f60634f0078583d92b931d5c0eebnethercote#else
7973b526fb4af0f60634f0078583d92b931d5c0eebnethercote    throw IOException("no opened file");
8073b526fb4af0f60634f0078583d92b931d5c0eebnethercote#endif
8173b526fb4af0f60634f0078583d92b931d5c0eebnethercote  }
824de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn  if (feof(file_)) {
834cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#if defined (SFNTLY_NO_EXCEPTION)
844de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn    return 0;
854cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#else
8685665ca6fa29dd64754dabe50eb98f25896e752acerion    throw IOException("eof reached");
874cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#endif
882c48c7b0a453d32375a4df17e153011b797ef28csewardj  }
894cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj  byte_t value;
904de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn  fread(&value, 1, 1, file_);
914de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn  position_++;
924de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn  return value;
9373b526fb4af0f60634f0078583d92b931d5c0eebnethercote}
9473b526fb4af0f60634f0078583d92b931d5c0eebnethercote
9573b526fb4af0f60634f0078583d92b931d5c0eebnethercoteint32_t FileInputStream::read(ByteVector* b) {
9673b526fb4af0f60634f0078583d92b931d5c0eebnethercote  return read(b, 0, b->capacity());
9773b526fb4af0f60634f0078583d92b931d5c0eebnethercote}
9873b526fb4af0f60634f0078583d92b931d5c0eebnethercote
9973b526fb4af0f60634f0078583d92b931d5c0eebnethercoteint32_t FileInputStream::read(ByteVector* b, int32_t offset, int32_t length) {
10073b526fb4af0f60634f0078583d92b931d5c0eebnethercote  assert(b);
10173b526fb4af0f60634f0078583d92b931d5c0eebnethercote  assert(b->size() >= (size_t)(offset + length));
10273b526fb4af0f60634f0078583d92b931d5c0eebnethercote  if (!file_) {
10373b526fb4af0f60634f0078583d92b931d5c0eebnethercote#if defined (SFNTLY_NO_EXCEPTION)
10473b526fb4af0f60634f0078583d92b931d5c0eebnethercote    return 0;
10573b526fb4af0f60634f0078583d92b931d5c0eebnethercote#else
106f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote    throw IOException("no opened file");
107f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote#endif
108f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote  }
109f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote  if (feof(file_)) {
110f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote#if defined (SFNTLY_NO_EXCEPTION)
111f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote    return 0;
112f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote#else
113f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote    throw IOException("eof reached");
114f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote#endif
115f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote  }
116f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote  size_t read_count = std::min<size_t>(length_ - position_, length);
117f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote  int32_t actual_read = fread(&((*b)[offset]), 1, read_count, file_);
118f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote  position_ += actual_read;
119f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote  return actual_read;
120f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote}
121f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote
122f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercotevoid FileInputStream::reset() {
123f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote  // NOP
124f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote}
12573b526fb4af0f60634f0078583d92b931d5c0eebnethercote
126330abb517e58fd0ee96fda7fb8563e32e029a63enethercoteint64_t FileInputStream::skip(int64_t n) {
12773b526fb4af0f60634f0078583d92b931d5c0eebnethercote  if (!file_) {
12873b526fb4af0f60634f0078583d92b931d5c0eebnethercote#if defined (SFNTLY_NO_EXCEPTION)
12973b526fb4af0f60634f0078583d92b931d5c0eebnethercote    return 0;
13073b526fb4af0f60634f0078583d92b931d5c0eebnethercote#else
13173b526fb4af0f60634f0078583d92b931d5c0eebnethercote    throw IOException("no opened file");
132f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote#endif
13373b526fb4af0f60634f0078583d92b931d5c0eebnethercote  }
13473b526fb4af0f60634f0078583d92b931d5c0eebnethercote  if (n < 0) {
13573b526fb4af0f60634f0078583d92b931d5c0eebnethercote    return 0;
13673b526fb4af0f60634f0078583d92b931d5c0eebnethercote  }
13773b526fb4af0f60634f0078583d92b931d5c0eebnethercote  size_t skip_count = std::min<size_t>(length_ - position_, (size_t)n);
13873b526fb4af0f60634f0078583d92b931d5c0eebnethercote  fseek(file_, skip_count, SEEK_CUR);
13992b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote  position_ += skip_count;
140330abb517e58fd0ee96fda7fb8563e32e029a63enethercote  return skip_count;
14173b526fb4af0f60634f0078583d92b931d5c0eebnethercote}
14273b526fb4af0f60634f0078583d92b931d5c0eebnethercote
14373b526fb4af0f60634f0078583d92b931d5c0eebnethercotevoid FileInputStream::unread(ByteVector* b) {
14473b526fb4af0f60634f0078583d92b931d5c0eebnethercote  unread(b, 0, b->capacity());
14573b526fb4af0f60634f0078583d92b931d5c0eebnethercote}
146c6851dde1b46166417a2bdb096c05818f5f07f09nethercote
147c6851dde1b46166417a2bdb096c05818f5f07f09nethercotevoid FileInputStream::unread(ByteVector* b, int32_t offset, int32_t length) {
148c6851dde1b46166417a2bdb096c05818f5f07f09nethercote  assert(b);
14973b526fb4af0f60634f0078583d92b931d5c0eebnethercote  assert(b->size() >= size_t(offset + length));
15073b526fb4af0f60634f0078583d92b931d5c0eebnethercote  if (!file_) {
15173b526fb4af0f60634f0078583d92b931d5c0eebnethercote#if defined (SFNTLY_NO_EXCEPTION)
15273b526fb4af0f60634f0078583d92b931d5c0eebnethercote    return;
15373b526fb4af0f60634f0078583d92b931d5c0eebnethercote#else
15473b526fb4af0f60634f0078583d92b931d5c0eebnethercote    throw IOException("no opened file");
15573b526fb4af0f60634f0078583d92b931d5c0eebnethercote#endif
1565b653bc2c60f6913e5bb6c2ebabfcf705a90c012nethercote  }
1575b653bc2c60f6913e5bb6c2ebabfcf705a90c012nethercote  size_t unread_count = std::min<size_t>(position_, length);
1587f7e4d1ac0c4ea8bf771e5490b69d0e4d619dfe9nethercote  fseek(file_, position_ - unread_count, SEEK_SET);
1597f7e4d1ac0c4ea8bf771e5490b69d0e4d619dfe9nethercote  read(b, offset, length);
16073b526fb4af0f60634f0078583d92b931d5c0eebnethercote  fseek(file_, position_ - unread_count, SEEK_SET);
16173b526fb4af0f60634f0078583d92b931d5c0eebnethercote}
16273b526fb4af0f60634f0078583d92b931d5c0eebnethercote
16373b526fb4af0f60634f0078583d92b931d5c0eebnethercote}  // namespace sfntly
1644de47b1c9bfe84ddd76a9e71e486c5085c51e3a8njn