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 #if defined (WIN32)
18 #include <windows.h>
19 #endif
20
21 #include <string.h>
22
23 #include <algorithm>
24
25 #include "sfntly/port/memory_input_stream.h"
26 #include "sfntly/port/exception_type.h"
27
28 namespace sfntly {
29
MemoryInputStream()30 MemoryInputStream::MemoryInputStream()
31 : buffer_(NULL),
32 position_(0),
33 length_(0) {
34 }
35
~MemoryInputStream()36 MemoryInputStream::~MemoryInputStream() {
37 Close();
38 }
39
Available()40 int32_t MemoryInputStream::Available() {
41 return length_ - position_;
42 }
43
Close()44 void MemoryInputStream::Close() {
45 }
46
Mark(int32_t readlimit)47 void MemoryInputStream::Mark(int32_t readlimit) {
48 // NOP
49 UNREFERENCED_PARAMETER(readlimit);
50 }
51
MarkSupported()52 bool MemoryInputStream::MarkSupported() {
53 return false;
54 }
55
Read()56 int32_t MemoryInputStream::Read() {
57 if (!buffer_) {
58 #if !defined (SFNTLY_NO_EXCEPTION)
59 throw IOException("no memory attached");
60 #endif
61 return 0;
62 }
63 if (position_ >= length_) {
64 #if !defined (SFNTLY_NO_EXCEPTION)
65 throw IOException("eof reached");
66 #endif
67 return 0;
68 }
69 byte_t value = buffer_[position_++];
70 return value;
71 }
72
Read(ByteVector * b)73 int32_t MemoryInputStream::Read(ByteVector* b) {
74 return Read(b, 0, b->size());
75 }
76
Read(ByteVector * b,int32_t offset,int32_t length)77 int32_t MemoryInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
78 assert(b);
79 if (!buffer_) {
80 #if !defined (SFNTLY_NO_EXCEPTION)
81 throw IOException("no memory attached");
82 #endif
83 return 0;
84 }
85 if (position_ >= length_) {
86 #if !defined (SFNTLY_NO_EXCEPTION)
87 throw IOException("eof reached");
88 #endif
89 return 0;
90 }
91 size_t read_count = std::min<size_t>(length_ - position_, length);
92 if (b->size() < (size_t)(offset + read_count)) {
93 b->resize((size_t)(offset + read_count));
94 }
95 memcpy(&((*b)[offset]), buffer_ + position_, read_count);
96 position_ += read_count;
97 return read_count;
98 }
99
Reset()100 void MemoryInputStream::Reset() {
101 // NOP
102 }
103
Skip(int64_t n)104 int64_t MemoryInputStream::Skip(int64_t n) {
105 if (!buffer_) {
106 #if !defined (SFNTLY_NO_EXCEPTION)
107 throw IOException("no memory attached");
108 #endif
109 return 0;
110 }
111 int64_t skip_count = 0;
112 if (n < 0) { // move backwards
113 skip_count = std::max<int64_t>(0 - (int64_t)position_, n);
114 position_ -= (size_t)(0 - skip_count);
115 } else {
116 skip_count = std::min<size_t>(length_ - position_, (size_t)n);
117 position_ += (size_t)skip_count;
118 }
119 return skip_count;
120 }
121
Unread(ByteVector * b)122 void MemoryInputStream::Unread(ByteVector* b) {
123 Unread(b, 0, b->size());
124 }
125
Unread(ByteVector * b,int32_t offset,int32_t length)126 void MemoryInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) {
127 assert(b);
128 assert(b->size() >= size_t(offset + length));
129 if (!buffer_) {
130 #if !defined (SFNTLY_NO_EXCEPTION)
131 throw IOException("no memory attached");
132 #endif
133 return;
134 }
135 size_t unread_count = std::min<size_t>(position_, length);
136 position_ -= unread_count;
137 Read(b, offset, length);
138 position_ -= unread_count;
139 }
140
Attach(const byte_t * buffer,size_t length)141 bool MemoryInputStream::Attach(const byte_t* buffer, size_t length) {
142 assert(buffer);
143 assert(length);
144 buffer_ = buffer;
145 length_ = length;
146 return true;
147 }
148
149 } // namespace sfntly
150