1 /*
2  * Copyright 2011 Google Inc. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "sfntly/data/font_input_stream.h"
18 
19 #include <algorithm>
20 
21 namespace sfntly {
22 
FontInputStream(InputStream * is)23 FontInputStream::FontInputStream(InputStream* is)
24     : stream_(is), position_(0), length_(0), bounded_(false) {
25 }
26 
FontInputStream(InputStream * is,size_t length)27 FontInputStream::FontInputStream(InputStream* is, size_t length)
28     : stream_(is), position_(0), length_(length), bounded_(true) {
29 }
30 
~FontInputStream()31 FontInputStream::~FontInputStream() {
32   // Do not close here, underlying InputStream will close themselves.
33 }
34 
Length()35 int32_t FontInputStream::Length() {
36   if (bounded_)
37     return length_;
38   if (stream_)
39     return stream_->Length();
40   return 0;
41 }
42 
Available()43 int32_t FontInputStream::Available() {
44   if (stream_)
45     return stream_->Available();
46   return 0;
47 }
48 
Close()49 void FontInputStream::Close() {
50   if (stream_) {
51     stream_->Close();
52   }
53 }
54 
Mark(int32_t readlimit)55 void FontInputStream::Mark(int32_t readlimit) {
56   if (stream_) {
57     stream_->Mark(readlimit);
58   }
59 }
60 
MarkSupported()61 bool FontInputStream::MarkSupported() {
62   if (stream_) {
63     return stream_->MarkSupported();
64   }
65   return false;
66 }
67 
Reset()68 void FontInputStream::Reset() {
69   if (stream_) {
70     stream_->Reset();
71   }
72 }
73 
Read()74 int32_t FontInputStream::Read() {
75   if (!stream_ || (bounded_ && position_ >= length_)) {
76     return -1;
77   }
78   int32_t b = stream_->Read();
79   if (b >= 0) {
80     position_++;
81   }
82   return b;
83 }
84 
Read(std::vector<uint8_t> * b,int32_t offset,int32_t length)85 int32_t FontInputStream::Read(std::vector<uint8_t>* b, int32_t offset, int32_t length) {
86   if (!stream_ || offset < 0 || length < 0 ||
87       (bounded_ && position_ >= length_)) {
88     return -1;
89   }
90   int32_t bytes_to_read =
91       bounded_ ? std::min<int32_t>(length, (int32_t)(length_ - position_)) :
92                  length;
93   int32_t bytes_read = stream_->Read(b, offset, bytes_to_read);
94   position_ += bytes_read;
95   return bytes_read;
96 }
97 
Read(std::vector<uint8_t> * b)98 int32_t FontInputStream::Read(std::vector<uint8_t>* b) {
99   return Read(b, 0, b->size());
100 }
101 
ReadChar()102 int32_t FontInputStream::ReadChar() {
103   return Read();
104 }
105 
ReadUShort()106 int32_t FontInputStream::ReadUShort() {
107   return 0xffff & (Read() << 8 | Read());
108 }
109 
ReadShort()110 int32_t FontInputStream::ReadShort() {
111   return ((Read() << 8 | Read()) << 16) >> 16;
112 }
113 
ReadUInt24()114 int32_t FontInputStream::ReadUInt24() {
115   return 0xffffff & (Read() << 16 | Read() << 8 | Read());
116 }
117 
ReadULong()118 int64_t FontInputStream::ReadULong() {
119   return 0xffffffffL & ReadLong();
120 }
121 
ReadULongAsInt()122 int32_t FontInputStream::ReadULongAsInt() {
123   int64_t ulong = ReadULong();
124   return ((int32_t)ulong) & ~0x80000000;
125 }
126 
ReadLong()127 int32_t FontInputStream::ReadLong() {
128   return Read() << 24 | Read() << 16 | Read() << 8 | Read();
129 }
130 
ReadFixed()131 int32_t FontInputStream::ReadFixed() {
132   return ReadLong();
133 }
134 
ReadDateTimeAsLong()135 int64_t FontInputStream::ReadDateTimeAsLong() {
136   return (int64_t)ReadULong() << 32 | ReadULong();
137 }
138 
Skip(int64_t n)139 int64_t FontInputStream::Skip(int64_t n) {
140   if (stream_) {
141     int64_t skipped = stream_->Skip(n);
142     position_ += skipped;
143     return skipped;
144   }
145   return 0;
146 }
147 
148 }  // namespace sfntly
149