1464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com/*
2464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Copyright (C) 2011 The sfntly Open Source Project
3464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *
4464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Licensed under the Apache License, Version 2.0 (the "License");
5464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * you may not use this file except in compliance with the License.
6464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * You may obtain a copy of the License at
7464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *
8464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *      http://www.apache.org/licenses/LICENSE-2.0
9464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com *
10464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * Unless required by applicable law or agreed to in writing, software
11464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * distributed under the License is distributed on an "AS IS" BASIS,
12464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * See the License for the specific language governing permissions and
14464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com * limitations under the License.
15464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com */
16464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
175af34fd773f8cfee82321393504f558ddf67c628arthurhsu@google.com#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_BYTE_ARRAY_H_
185af34fd773f8cfee82321393504f558ddf67c628arthurhsu@google.com#define SFNTLY_CPP_SRC_SFNTLY_DATA_BYTE_ARRAY_H_
19464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
20464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#include "sfntly/port/refcount.h"
21464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#include "sfntly/port/type.h"
22464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#include "sfntly/port/input_stream.h"
23464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com#include "sfntly/port/output_stream.h"
24464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
25464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comnamespace sfntly {
26464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
2732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com// An abstraction to a contiguous array of bytes.
28464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com// C++ port of this class assumes that the data are stored in a linear region
29464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com// like std::vector.
30464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comclass ByteArray : virtual public RefCount {
31464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com public:
32464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  virtual ~ByteArray();
33464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
3432a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Gets the current filled and readable length of the array.
35246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  int32_t Length();
36464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
3732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Gets the maximum size of the array. This is the maximum number of bytes that
38464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // the array can hold and all of it may not be filled with data or even fully
39464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // allocated yet.
40246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  int32_t Size();
41464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
4232a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Determines whether or not this array is growable or of fixed size.
43246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  bool growable() { return growable_; }
4432a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com
45246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  int32_t SetFilledLength(int32_t filled_length);
46464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
4732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Gets the byte from the given index.
4832a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param index the index into the byte array
4932a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @return the byte or -1 if reading beyond the bounds of the data
5032a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  virtual int32_t Get(int32_t index);
51464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
5232a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Gets the bytes from the given index and fill the buffer with them. As many
53464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // bytes as will fit into the buffer are read unless that would go past the
54464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // end of the array.
5532a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param index the index into the byte array
5632a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param b the buffer to put the bytes read into
5732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @return the number of bytes read from the buffer
58246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual int32_t Get(int32_t index, ByteVector* b);
59464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
6032a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Gets the bytes from the given index and fill the buffer with them starting
61464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // at the offset given. As many bytes as the specified length are read unless
62464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // that would go past the end of the array.
63464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param index the index into the byte array
64464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param b the buffer to put the bytes read into
65464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param offset the location in the buffer to start putting the bytes
66464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param length the number of bytes to put into the buffer
6732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @return the number of bytes read from the buffer
68246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual int32_t Get(int32_t index,
6932a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com                      byte_t* b,
70246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                      int32_t offset,
71464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com                      int32_t length);
72464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
7332a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Puts the specified byte into the array at the given index unless that would
74464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // be beyond the length of the array and it isn't growable.
7532a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  virtual void Put(int32_t index, byte_t b);
76464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
7732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Puts the specified bytes into the array at the given index. The entire
78464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // buffer is put into the array unless that would extend beyond the length and
79464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // the array isn't growable.
80246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual int32_t Put(int32_t index, ByteVector* b);
81464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
8232a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Puts the specified bytes into the array at the given index. All of the bytes
83464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // specified are put into the array unless that would extend beyond the length
84464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // and the array isn't growable. The bytes to be put into the array are those
85464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // in the buffer from the given offset and for the given length.
86464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param index the index into the ByteArray
87464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param b the bytes to put into the array
88464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param offset the offset in the bytes to start copying from
89464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param length the number of bytes to copy into the array
90464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @return the number of bytes actually written
91246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual int32_t Put(int32_t index,
9232a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com                      byte_t* b,
93246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                      int32_t offset,
94464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com                      int32_t length);
95464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
9632a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Fully copies this ByteArray to another ByteArray to the extent that the
97464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // destination array has storage for the data copied.
98246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual int32_t CopyTo(ByteArray* array);
99464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
10032a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Copies a segment of this ByteArray to another ByteArray.
101464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param array the destination
102464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param offset the offset in this ByteArray to start copying from
103464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param length the maximum length in bytes to copy
104464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @return the number of bytes copied
105246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length);
106464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
10732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Copies this ByteArray to another ByteArray.
108464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param dstOffset the offset in the destination array to start copying to
109464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param array the destination
110464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param srcOffset the offset in this ByteArray to start copying from
111464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @param length the maximum length in bytes to copy
112464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  // @return the number of bytes copied
113246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual int32_t CopyTo(int32_t dst_offset,
114246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                         ByteArray* array,
115246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                         int32_t src_offset,
116246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                         int32_t length);
117464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
11832a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Copies this ByteArray to an OutputStream.
11932a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param os the destination
12032a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @return the number of bytes copied
121246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual int32_t CopyTo(OutputStream* os);
12232a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com
12332a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Copies this ByteArray to an OutputStream.
12432a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param os the destination
12532a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param offset
12632a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param length
12732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @return the number of bytes copied
128246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
12932a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com
13032a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Copies from the InputStream into this ByteArray.
13132a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param is the source
13232a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param length the number of bytes to copy
133246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual bool CopyFrom(InputStream* is, int32_t length);
13432a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com
13532a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Copies everything from the InputStream into this ByteArray.
13632a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param is the source
137246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual bool CopyFrom(InputStream* is);
138464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
139464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com protected:
140246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  // filledLength the length that is "filled" and readable counting from offset.
141246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  // storageLength the maximum storage size of the underlying data.
142246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  // growable is the storage growable - storageLength is the max growable size.
143246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  ByteArray(int32_t filled_length, int32_t storage_length, bool growable);
144246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  ByteArray(int32_t filled_length, int32_t storage_length);
145246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  void Init(int32_t filled_length, int32_t storage_length, bool growable);
146246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
14732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Internal subclass API
14832a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com
14932a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Stores the byte at the index given.
15032a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param index the location to store at
15132a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param b the byte to store
15232a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  virtual void InternalPut(int32_t index, byte_t b) = 0;
15332a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com
15432a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Stores the array of bytes at the given index.
15532a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param index the location to store at
15632a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param b the bytes to store
15732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param offset the offset to start from in the byte array
15832a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param length the length of the byte array to store from the offset
15932a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @return the number of bytes actually stored
160246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual int32_t InternalPut(int32_t index,
16132a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com                              byte_t* b,
162246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                              int32_t offset,
163464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com                              int32_t length) = 0;
16432a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com
16532a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Gets the byte at the index given.
16632a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param index the location to get from
16732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @return the byte stored at the index
168246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual byte_t InternalGet(int32_t index) = 0;
16932a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com
17032a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Gets the bytes at the index given of the given length.
17132a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param index the location to start getting from
17232a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param b the array to put the bytes into
17332a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param offset the offset in the array to put the bytes into
17432a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @param length the length of bytes to read
17532a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // @return the number of bytes actually ready
176246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual int32_t InternalGet(int32_t index,
17732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com                              byte_t* b,
178246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com                              int32_t offset,
179464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com                              int32_t length) = 0;
18032a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com
18132a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Close this instance of the ByteArray.
182246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual void Close() = 0;
183246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com
184246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  // C++ port only, raw pointer to the first element of storage.
185246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  virtual byte_t* Begin() = 0;
186464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
18732a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  // Java toString() not ported.
18832a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com
189246300f7fab1f2539c3207ce5ec28cc355465be8arthurhsu@google.com  static const int32_t COPY_BUFFER_SIZE;
190464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
191464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com private:
19232a01c7c6e7be46dda9bfc78de9ce32d99e4c8b7arthurhsu@google.com  //bool bound_;  // unused, comment out
193464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  int32_t filled_length_;
194464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  int32_t storage_length_;
195464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com  bool growable_;
196464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com};
197464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.comtypedef Ptr<ByteArray> ByteArrayPtr;
198464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
199464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com}  // namespace sfntly
200464987db923362e596195f9eebd34fc508c9a41arthurhsu@google.com
2015af34fd773f8cfee82321393504f558ddf67c628arthurhsu@google.com#endif  // SFNTLY_CPP_SRC_SFNTLY_DATA_BYTE_ARRAY_H_
202