1 
2 /*
3  * Copyright (C) 2009 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include "rsContext.h"
19 #include "rsStream.h"
20 
21 namespace android {
22 namespace renderscript {
23 
IStream(const uint8_t * buf,bool use64)24 IStream::IStream(const uint8_t *buf, bool use64) {
25     mData = buf;
26     mPos = 0;
27     mUse64 = use64;
28 }
29 
loadByteArray(void * dest,size_t numBytes)30 void IStream::loadByteArray(void *dest, size_t numBytes) {
31     memcpy(dest, mData + mPos, numBytes);
32     mPos += numBytes;
33 }
34 
loadOffset()35 uint64_t IStream::loadOffset() {
36     uint64_t tmp;
37     if (mUse64) {
38         mPos = (mPos + 7) & (~7);
39         tmp = reinterpret_cast<const uint64_t *>(&mData[mPos])[0];
40         mPos += sizeof(uint64_t);
41         return tmp;
42     }
43     return loadU32();
44 }
45 
loadString()46 const char * IStream::loadString() {
47     uint32_t len = loadU32();
48     const char *s = rsuCopyString((const char *)&mData[mPos], len);
49     mPos += len;
50     return s;
51 }
52 
53 // Output stream implementation
OStream(uint64_t len,bool use64)54 OStream::OStream(uint64_t len, bool use64) {
55     mData = (uint8_t*)malloc(len);
56     mLength = len;
57     mPos = 0;
58     mUse64 = use64;
59 }
60 
~OStream()61 OStream::~OStream() {
62     free(mData);
63 }
64 
addByteArray(const void * src,size_t numBytes)65 void OStream::addByteArray(const void *src, size_t numBytes) {
66     // We need to potentially grow more than once if the number of byes we write is substantial
67     while (mPos + numBytes >= mLength) {
68         growSize();
69     }
70     memcpy(mData + mPos, src, numBytes);
71     mPos += numBytes;
72 }
73 
addOffset(uint64_t v)74 void OStream::addOffset(uint64_t v) {
75     if (mUse64) {
76         mPos = (mPos + 7) & (~7);
77         if (mPos + sizeof(v) >= mLength) {
78             growSize();
79         }
80         mData[mPos++] = (uint8_t)(v & 0xff);
81         mData[mPos++] = (uint8_t)((v >> 8) & 0xff);
82         mData[mPos++] = (uint8_t)((v >> 16) & 0xff);
83         mData[mPos++] = (uint8_t)((v >> 24) & 0xff);
84         mData[mPos++] = (uint8_t)((v >> 32) & 0xff);
85         mData[mPos++] = (uint8_t)((v >> 40) & 0xff);
86         mData[mPos++] = (uint8_t)((v >> 48) & 0xff);
87         mData[mPos++] = (uint8_t)((v >> 56) & 0xff);
88     } else {
89         addU32(v);
90     }
91 }
92 
addString(const char * s,size_t len)93 void OStream::addString(const char *s, size_t len) {
94     addU32(len);
95     if (mPos + len*sizeof(char) >= mLength) {
96         growSize();
97     }
98     char *stringData = reinterpret_cast<char *>(&mData[mPos]);
99     memcpy(stringData, s, len);
100     mPos += len*sizeof(char);
101 }
102 
addString(const char * s)103 void OStream::addString(const char *s) {
104     addString(s, strlen(s));
105 }
106 
growSize()107 void OStream::growSize() {
108     uint8_t *newData = (uint8_t*)malloc(mLength*2);
109     memcpy(newData, mData, mLength*sizeof(uint8_t));
110     mLength = mLength * 2;
111     free(mData);
112     mData = newData;
113 }
114 
115 } // namespace renderscript
116 } // namespace android
117