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