summaryrefslogtreecommitdiff
path: root/sfntly/data/byte_array.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sfntly/data/byte_array.cc')
-rw-r--r--sfntly/data/byte_array.cc199
1 files changed, 199 insertions, 0 deletions
diff --git a/sfntly/data/byte_array.cc b/sfntly/data/byte_array.cc
new file mode 100644
index 0000000..915a40c
--- /dev/null
+++ b/sfntly/data/byte_array.cc
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/data/byte_array.h"
+
+#include <algorithm>
+
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+
+const int32_t ByteArray::COPY_BUFFER_SIZE = 8192;
+
+ByteArray::~ByteArray() {}
+
+int32_t ByteArray::Length() { return filled_length_; }
+int32_t ByteArray::Size() { return storage_length_; }
+
+int32_t ByteArray::SetFilledLength(int32_t filled_length) {
+ filled_length_ = std::min<int32_t>(filled_length, storage_length_);
+ return filled_length_;
+}
+
+int32_t ByteArray::Get(int32_t index) {
+ return InternalGet(index) & 0xff;
+}
+
+int32_t ByteArray::Get(int32_t index, ByteVector* b) {
+ assert(b);
+ return Get(index, &((*b)[0]), 0, b->size());
+}
+
+int32_t ByteArray::Get(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length) {
+ assert(b);
+ if (index < 0 || index >= filled_length_) {
+ return 0;
+ }
+ int32_t actual_length = std::min<int32_t>(length, filled_length_ - index);
+ return InternalGet(index, b, offset, actual_length);
+}
+
+void ByteArray::Put(int32_t index, byte_t b) {
+ if (index < 0 || index >= Size()) {
+#if defined (SFNTLY_NO_EXCEPTION)
+ return;
+#else
+ throw IndexOutOfBoundException(
+ "Attempt to write outside the bounds of the data");
+#endif
+ }
+ InternalPut(index, b);
+ filled_length_ = std::max<int32_t>(filled_length_, index + 1);
+}
+
+int32_t ByteArray::Put(int index, ByteVector* b) {
+ assert(b);
+ return Put(index, &((*b)[0]), 0, b->size());
+}
+
+int32_t ByteArray::Put(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length) {
+ assert(b);
+ if (index < 0 || index >= Size()) {
+#if defined (SFNTLY_NO_EXCEPTION)
+ return 0;
+#else
+ throw IndexOutOfBoundException(
+ "Attempt to write outside the bounds of the data");
+#endif
+ }
+ int32_t actual_length = std::min<int32_t>(length, Size() - index);
+ int32_t bytes_written = InternalPut(index, b, offset, actual_length);
+ filled_length_ = std::max<int32_t>(filled_length_, index + bytes_written);
+ return bytes_written;
+}
+
+int32_t ByteArray::CopyTo(ByteArray* array) {
+ return CopyTo(array, 0, Length());
+}
+
+int32_t ByteArray::CopyTo(ByteArray* array, int32_t offset, int32_t length) {
+ return CopyTo(0, array, offset, length);
+}
+
+int32_t ByteArray::CopyTo(int32_t dst_offset, ByteArray* array,
+ int32_t src_offset, int32_t length) {
+ assert(array);
+ if (array->Size() < dst_offset + length) { // insufficient space
+ return -1;
+ }
+
+ ByteVector b(COPY_BUFFER_SIZE);
+ int32_t bytes_read = 0;
+ int32_t index = 0;
+ int32_t remaining_length = length;
+ int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
+ while ((bytes_read =
+ Get(index + src_offset, &(b[0]), 0, buffer_length)) > 0) {
+ int bytes_written = array->Put(index + dst_offset, &(b[0]), 0, bytes_read);
+ UNREFERENCED_PARAMETER(bytes_written);
+ index += bytes_read;
+ remaining_length -= bytes_read;
+ buffer_length = std::min<int32_t>(b.size(), remaining_length);
+ }
+ return index;
+}
+
+int32_t ByteArray::CopyTo(OutputStream* os) {
+ return CopyTo(os, 0, Length());
+}
+
+int32_t ByteArray::CopyTo(OutputStream* os, int32_t offset, int32_t length) {
+ ByteVector b(COPY_BUFFER_SIZE);
+ int32_t bytes_read = 0;
+ int32_t index = 0;
+ int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
+ while ((bytes_read = Get(index + offset, &(b[0]), 0, buffer_length)) > 0) {
+ os->Write(&b, 0, bytes_read);
+ index += bytes_read;
+ buffer_length = std::min<int32_t>(b.size(), length - index);
+ }
+ return index;
+}
+
+bool ByteArray::CopyFrom(InputStream* is, int32_t length) {
+ ByteVector b(COPY_BUFFER_SIZE);
+ int32_t bytes_read = 0;
+ int32_t index = 0;
+ int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
+ while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
+ if (Put(index, &(b[0]), 0, bytes_read) != bytes_read) {
+#if defined (SFNTLY_NO_EXCEPTION)
+ return 0;
+#else
+ throw IOException("Error writing bytes.");
+#endif
+ }
+ index += bytes_read;
+ length -= bytes_read;
+ buffer_length = std::min<int32_t>(b.size(), length);
+ }
+ return true;
+}
+
+bool ByteArray::CopyFrom(InputStream* is) {
+ ByteVector b(COPY_BUFFER_SIZE);
+ int32_t bytes_read = 0;
+ int32_t index = 0;
+ int32_t buffer_length = COPY_BUFFER_SIZE;
+ while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
+ if (Put(index, &b[0], 0, bytes_read) != bytes_read) {
+#if defined (SFNTLY_NO_EXCEPTION)
+ return 0;
+#else
+ throw IOException("Error writing bytes.");
+#endif
+ }
+ index += bytes_read;
+ }
+ return true;
+}
+
+ByteArray::ByteArray(int32_t filled_length,
+ int32_t storage_length,
+ bool growable) {
+ Init(filled_length, storage_length, growable);
+}
+
+ByteArray::ByteArray(int32_t filled_length, int32_t storage_length) {
+ Init(filled_length, storage_length, false);
+}
+
+void ByteArray::Init(int32_t filled_length,
+ int32_t storage_length,
+ bool growable) {
+ storage_length_ = storage_length;
+ growable_ = growable;
+ SetFilledLength(filled_length);
+}
+
+} // namespace sfntly