Line data Source code
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/byte_array.h"
18 :
19 : #include <algorithm>
20 :
21 : #include "sfntly/port/exception_type.h"
22 :
23 : namespace sfntly {
24 :
25 : const int32_t ByteArray::COPY_BUFFER_SIZE = 8192;
26 :
27 0 : ByteArray::~ByteArray() {}
28 :
29 0 : int32_t ByteArray::Length() { return filled_length_; }
30 0 : int32_t ByteArray::Size() { return storage_length_; }
31 :
32 0 : int32_t ByteArray::SetFilledLength(int32_t filled_length) {
33 0 : filled_length_ = std::min<int32_t>(filled_length, storage_length_);
34 0 : return filled_length_;
35 : }
36 :
37 0 : int32_t ByteArray::Get(int32_t index) {
38 0 : if (index < 0 || index >= Length())
39 0 : return -1;
40 0 : return InternalGet(index) & 0xff;
41 : }
42 :
43 0 : int32_t ByteArray::Get(int32_t index, ByteVector* b) {
44 0 : assert(b);
45 0 : return Get(index, &((*b)[0]), 0, b->size());
46 : }
47 :
48 0 : int32_t ByteArray::Get(int32_t index,
49 : byte_t* b,
50 : int32_t offset,
51 : int32_t length) {
52 0 : assert(b);
53 0 : if (index < 0 || index >= filled_length_) {
54 0 : return 0;
55 : }
56 0 : int32_t actual_length = std::min<int32_t>(length, filled_length_ - index);
57 0 : return InternalGet(index, b, offset, actual_length);
58 : }
59 :
60 0 : void ByteArray::Put(int32_t index, byte_t b) {
61 0 : if (index < 0 || index >= Size()) {
62 : #if defined (SFNTLY_NO_EXCEPTION)
63 0 : return;
64 : #else
65 : throw IndexOutOfBoundException(
66 : "Attempt to write outside the bounds of the data");
67 : #endif
68 : }
69 0 : InternalPut(index, b);
70 0 : filled_length_ = std::max<int32_t>(filled_length_, index + 1);
71 : }
72 :
73 0 : int32_t ByteArray::Put(int index, ByteVector* b) {
74 0 : assert(b);
75 0 : return Put(index, &((*b)[0]), 0, b->size());
76 : }
77 :
78 0 : int32_t ByteArray::Put(int32_t index,
79 : byte_t* b,
80 : int32_t offset,
81 : int32_t length) {
82 0 : assert(b);
83 0 : if (index < 0 || index >= Size()) {
84 : #if defined (SFNTLY_NO_EXCEPTION)
85 0 : return 0;
86 : #else
87 : throw IndexOutOfBoundException(
88 : "Attempt to write outside the bounds of the data");
89 : #endif
90 : }
91 0 : int32_t actual_length = std::min<int32_t>(length, Size() - index);
92 0 : int32_t bytes_written = InternalPut(index, b, offset, actual_length);
93 0 : filled_length_ = std::max<int32_t>(filled_length_, index + bytes_written);
94 0 : return bytes_written;
95 : }
96 :
97 0 : int32_t ByteArray::CopyTo(ByteArray* array) {
98 0 : return CopyTo(array, 0, Length());
99 : }
100 :
101 0 : int32_t ByteArray::CopyTo(ByteArray* array, int32_t offset, int32_t length) {
102 0 : return CopyTo(0, array, offset, length);
103 : }
104 :
105 0 : int32_t ByteArray::CopyTo(int32_t dst_offset, ByteArray* array,
106 : int32_t src_offset, int32_t length) {
107 0 : assert(array);
108 0 : if (array->Size() < dst_offset + length) { // insufficient space
109 0 : return -1;
110 : }
111 :
112 0 : ByteVector b(COPY_BUFFER_SIZE);
113 0 : int32_t bytes_read = 0;
114 0 : int32_t index = 0;
115 0 : int32_t remaining_length = length;
116 0 : int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
117 0 : while ((bytes_read =
118 0 : Get(index + src_offset, &(b[0]), 0, buffer_length)) > 0) {
119 0 : int bytes_written = array->Put(index + dst_offset, &(b[0]), 0, bytes_read);
120 : UNREFERENCED_PARAMETER(bytes_written);
121 0 : index += bytes_read;
122 0 : remaining_length -= bytes_read;
123 0 : buffer_length = std::min<int32_t>(b.size(), remaining_length);
124 : }
125 0 : return index;
126 : }
127 :
128 0 : int32_t ByteArray::CopyTo(OutputStream* os) {
129 0 : return CopyTo(os, 0, Length());
130 : }
131 :
132 0 : int32_t ByteArray::CopyTo(OutputStream* os, int32_t offset, int32_t length) {
133 0 : ByteVector b(COPY_BUFFER_SIZE);
134 0 : int32_t bytes_read = 0;
135 0 : int32_t index = 0;
136 0 : int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
137 0 : while ((bytes_read = Get(index + offset, &(b[0]), 0, buffer_length)) > 0) {
138 0 : os->Write(&b, 0, bytes_read);
139 0 : index += bytes_read;
140 0 : buffer_length = std::min<int32_t>(b.size(), length - index);
141 : }
142 0 : return index;
143 : }
144 :
145 0 : bool ByteArray::CopyFrom(InputStream* is, int32_t length) {
146 0 : ByteVector b(COPY_BUFFER_SIZE);
147 0 : int32_t bytes_read = 0;
148 0 : int32_t index = 0;
149 0 : int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
150 0 : while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
151 0 : if (Put(index, &(b[0]), 0, bytes_read) != bytes_read) {
152 : #if defined (SFNTLY_NO_EXCEPTION)
153 0 : return 0;
154 : #else
155 : throw IOException("Error writing bytes.");
156 : #endif
157 : }
158 0 : index += bytes_read;
159 0 : length -= bytes_read;
160 0 : buffer_length = std::min<int32_t>(b.size(), length);
161 : }
162 0 : return true;
163 : }
164 :
165 0 : bool ByteArray::CopyFrom(InputStream* is) {
166 0 : ByteVector b(COPY_BUFFER_SIZE);
167 0 : int32_t bytes_read = 0;
168 0 : int32_t index = 0;
169 0 : int32_t buffer_length = COPY_BUFFER_SIZE;
170 0 : while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
171 0 : if (Put(index, &b[0], 0, bytes_read) != bytes_read) {
172 : #if defined (SFNTLY_NO_EXCEPTION)
173 0 : return 0;
174 : #else
175 : throw IOException("Error writing bytes.");
176 : #endif
177 : }
178 0 : index += bytes_read;
179 : }
180 0 : return true;
181 : }
182 :
183 0 : ByteArray::ByteArray(int32_t filled_length,
184 : int32_t storage_length,
185 0 : bool growable) {
186 0 : Init(filled_length, storage_length, growable);
187 0 : }
188 :
189 0 : ByteArray::ByteArray(int32_t filled_length, int32_t storage_length) {
190 0 : Init(filled_length, storage_length, false);
191 0 : }
192 :
193 0 : void ByteArray::Init(int32_t filled_length,
194 : int32_t storage_length,
195 : bool growable) {
196 0 : storage_length_ = storage_length;
197 0 : growable_ = growable;
198 0 : SetFilledLength(filled_length);
199 0 : }
200 :
201 : } // namespace sfntly
|