130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/*
230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Copyright 2011 Google Inc. All Rights Reserved.
330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *
430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Licensed under the Apache License, Version 2.0 (the "License");
530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * you may not use this file except in compliance with the License.
630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * You may obtain a copy of the License at
730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *
830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *      http://www.apache.org/licenses/LICENSE-2.0
930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *
1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Unless required by applicable law or agreed to in writing, software
1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * distributed under the License is distributed on an "AS IS" BASIS,
1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * See the License for the specific language governing permissions and
1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * limitations under the License.
1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun */
1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/data/font_input_stream.h"
1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <algorithm>
2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly {
2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunFontInputStream::FontInputStream(InputStream* is)
2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    : stream_(is), position_(0), length_(0), bounded_(false) {
2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunFontInputStream::FontInputStream(InputStream* is, size_t length)
2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    : stream_(is), position_(0), length_(length), bounded_(true) {
2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunFontInputStream::~FontInputStream() {
3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Do not close here, underlying InputStream will close themselves.
3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t FontInputStream::Available() {
3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (stream_) {
3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    return stream_->Available();
3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return 0;
4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid FontInputStream::Close() {
4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (stream_) {
4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    stream_->Close();
4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid FontInputStream::Mark(int32_t readlimit) {
4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (stream_) {
5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    stream_->Mark(readlimit);
5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool FontInputStream::MarkSupported() {
5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (stream_) {
5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    return stream_->MarkSupported();
5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return false;
5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid FontInputStream::Reset() {
6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (stream_) {
6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    stream_->Reset();
6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t FontInputStream::Read() {
6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (!stream_ || (bounded_ && position_ >= length_)) {
6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    return -1;
7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t b = stream_->Read();
7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (b >= 0) {
7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    position_++;
7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return b;
7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t FontInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (!stream_ || offset < 0 || length < 0 ||
8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      (bounded_ && position_ >= length_)) {
8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    return -1;
8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t bytes_to_read =
8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      bounded_ ? std::min<int32_t>(length, (int32_t)(length_ - position_)) :
8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                 length;
8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t bytes_read = stream_->Read(b, offset, bytes_to_read);
8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  position_ += bytes_read;
8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return bytes_read;
8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t FontInputStream::Read(ByteVector* b) {
9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return Read(b, 0, b->size());
9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t FontInputStream::ReadChar() {
9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return Read();
9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t FontInputStream::ReadUShort() {
10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return 0xffff & (Read() << 8 | Read());
10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t FontInputStream::ReadShort() {
10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return ((Read() << 8 | Read()) << 16) >> 16;
10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t FontInputStream::ReadUInt24() {
10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return 0xffffff & (Read() << 16 | Read() << 8 | Read());
10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint64_t FontInputStream::ReadULong() {
11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return 0xffffffffL & ReadLong();
11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t FontInputStream::ReadULongAsInt() {
11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int64_t ulong = ReadULong();
11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return ((int32_t)ulong) & ~0x80000000;
11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t FontInputStream::ReadLong() {
12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return Read() << 24 | Read() << 16 | Read() << 8 | Read();
12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t FontInputStream::ReadFixed() {
12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return ReadLong();
12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint64_t FontInputStream::ReadDateTimeAsLong() {
12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return (int64_t)ReadULong() << 32 | ReadULong();
13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint64_t FontInputStream::Skip(int64_t n) {
13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (stream_) {
13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int64_t skipped = stream_->Skip(n);
13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    position_ += skipped;
13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    return skipped;
13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return 0;
13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}  // namespace sfntly
142