1464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/*
2464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Copyright 2011 Google Inc. All Rights Reserved.
3464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *
4464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Licensed under the Apache License, Version 2.0 (the "License");
5464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * you may not use this file except in compliance with the License.
6464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * You may obtain a copy of the License at
7464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *
8464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *      http://www.apache.org/licenses/LICENSE-2.0
9464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *
10464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Unless required by applicable law or agreed to in writing, software
11464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * distributed under the License is distributed on an "AS IS" BASIS,
12464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * See the License for the specific language governing permissions and
14464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * limitations under the License.
15464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com */
16464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
17464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#include "sfntly/data/font_input_stream.h"
18464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
19246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com#include <algorithm>
20246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
21464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comnamespace sfntly {
22464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
23464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comFontInputStream::FontInputStream(InputStream* is)
240e411afcef9fc211b3f8f70d31bc1dfa4c0f85d3arthurhsu@google.com    : stream_(is), position_(0), length_(0), bounded_(false) {
25464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
26464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
27464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comFontInputStream::FontInputStream(InputStream* is, size_t length)
2832a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com    : stream_(is), position_(0), length_(length), bounded_(true) {
29464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
30464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
31464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comFontInputStream::~FontInputStream() {
32ed8406cf320973d04bbe348c681090b1feba3d68arthurhsu@google.com  // Do not close here, underlying InputStream will close themselves.
33464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
34464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
35246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t FontInputStream::Available() {
36464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  if (stream_) {
37246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    return stream_->Available();
38464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
39464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return 0;
40464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
41464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
42246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid FontInputStream::Close() {
43464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  if (stream_) {
44246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    stream_->Close();
45464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
46464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
47464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
48246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid FontInputStream::Mark(int32_t readlimit) {
49464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  if (stream_) {
50246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    stream_->Mark(readlimit);
51464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
52464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
53464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
54246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.combool FontInputStream::MarkSupported() {
55464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  if (stream_) {
56246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    return stream_->MarkSupported();
57464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
58464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return false;
59464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
60464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
61246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comvoid FontInputStream::Reset() {
62464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  if (stream_) {
63246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    stream_->Reset();
64464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
65464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
66464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
67246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t FontInputStream::Read() {
68464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  if (!stream_ || (bounded_ && position_ >= length_)) {
69464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com    return -1;
70464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
71246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  int32_t b = stream_->Read();
72464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  if (b >= 0) {
73464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com    position_++;
74464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
75464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return b;
76464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
77464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
78246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t FontInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
79464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  if (!stream_ || offset < 0 || length < 0 ||
80464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com      (bounded_ && position_ >= length_)) {
81464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com    return -1;
82464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
83464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  int32_t bytes_to_read =
84464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com      bounded_ ? std::min<int32_t>(length, (int32_t)(length_ - position_)) :
85464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com                 length;
86246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  int32_t bytes_read = stream_->Read(b, offset, bytes_to_read);
87464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  position_ += bytes_read;
88464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return bytes_read;
89464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
90464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
91246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t FontInputStream::Read(ByteVector* b) {
92246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return Read(b, 0, b->size());
93464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
94464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
95246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t FontInputStream::ReadChar() {
96246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return Read();
97464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
98464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
99246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t FontInputStream::ReadUShort() {
100246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return 0xffff & (Read() << 8 | Read());
101464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
102464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
103246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t FontInputStream::ReadShort() {
104246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return ((Read() << 8 | Read()) << 16) >> 16;
105464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
106464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
107246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t FontInputStream::ReadUInt24() {
108246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return 0xffffff & (Read() << 16 | Read() << 8 | Read());
109464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
110464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
111246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint64_t FontInputStream::ReadULong() {
112246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return 0xffffffffL & ReadLong();
113464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
114464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
115246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t FontInputStream::ReadULongAsInt() {
116246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  int64_t ulong = ReadULong();
117464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return ((int32_t)ulong) & ~0x80000000;
118464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
119464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
120246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t FontInputStream::ReadLong() {
121246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return Read() << 24 | Read() << 16 | Read() << 8 | Read();
122464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
123464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
124246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint32_t FontInputStream::ReadFixed() {
125246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return ReadLong();
126464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
127464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
128246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint64_t FontInputStream::ReadDateTimeAsLong() {
129246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  return (int64_t)ReadULong() << 32 | ReadULong();
130464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
131464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
132246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.comint64_t FontInputStream::Skip(int64_t n) {
133464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  if (stream_) {
134246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com    int64_t skipped = stream_->Skip(n);
135464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com    position_ += skipped;
136464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com    return skipped;
137464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  }
138464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  return 0;
139464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}
140464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
141464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}  // namespace sfntly
142