1 /**
2  * Copyright (C) 2022 The Android Open Source Project
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 <ImsMediaBitReader.h>
18 #include <ImsMediaTrace.h>
19 #include <string.h>
20 
ImsMediaBitReader()21 ImsMediaBitReader::ImsMediaBitReader()
22 {
23     mBuffer = nullptr;
24     mMaxBufferSize = 0;
25     mBytePos = 0;
26     mBitPos = 0;
27     mBitBuffer = 0;
28     mBufferEOF = false;
29 }
30 
~ImsMediaBitReader()31 ImsMediaBitReader::~ImsMediaBitReader() {}
32 
SetBuffer(uint8_t * pbBuffer,uint32_t nBufferSize)33 void ImsMediaBitReader::SetBuffer(uint8_t* pbBuffer, uint32_t nBufferSize)
34 {
35     mBytePos = 0;
36     mBitPos = 32;
37     mBitBuffer = 0;
38     mBufferEOF = false;
39     mBuffer = pbBuffer;
40     mMaxBufferSize = nBufferSize;
41 }
42 
Read(uint32_t nSize)43 uint32_t ImsMediaBitReader::Read(uint32_t nSize)
44 {
45     uint32_t value;
46     if (nSize == 0)
47         return 0;
48     if (mBuffer == nullptr || nSize > 24 || mBufferEOF)
49     {
50         IMLOGE2("[Read] nSize[%d], bBufferEOF[%d]", nSize, mBufferEOF);
51         return 0;
52     }
53 
54     // read from byte buffer
55     while ((32 - mBitPos) < nSize)
56     {
57         if (mBytePos >= mMaxBufferSize)
58         {
59             mBufferEOF = true;
60             IMLOGE2("[Read] End of Buffer : nBytePos[%d], nMaxBufferSize[%d]", mBytePos,
61                     mMaxBufferSize);
62             return 0;
63         }
64 
65         mBitPos -= 8;
66         mBitBuffer <<= 8;
67         mBitBuffer += mBuffer[mBytePos++];
68     }
69 
70     // read from bit buffer
71     value = mBitBuffer << mBitPos >> (32 - nSize);
72     mBitPos += nSize;
73     return value;
74 }
75 
ReadByteBuffer(uint8_t * pbDst,uint32_t nBitSize)76 void ImsMediaBitReader::ReadByteBuffer(uint8_t* pbDst, uint32_t nBitSize)
77 {
78     uint32_t dst_pos = 0;
79     uint32_t nByteSize;
80     uint32_t nRemainBitSize;
81     nByteSize = nBitSize >> 3;
82     nRemainBitSize = nBitSize & 0x07;
83 
84     if (mBitPos == 32)
85     {
86         memcpy(pbDst, mBuffer + mBytePos, nByteSize);
87         mBytePos += nByteSize;
88         dst_pos += nByteSize;
89     }
90     else
91     {
92         for (dst_pos = 0; dst_pos < nByteSize; dst_pos++)
93         {
94             pbDst[dst_pos] = Read(8);
95         }
96     }
97 
98     if (nRemainBitSize > 0)
99     {
100         uint32_t v;
101         v = Read(nRemainBitSize);
102         v <<= (8 - nRemainBitSize);
103         pbDst[dst_pos] = (unsigned char)v;
104     }
105 }
106 
ReadByUEMode()107 uint32_t ImsMediaBitReader::ReadByUEMode()
108 {
109     uint32_t i = 0;
110     uint32_t j = 0;
111     uint32_t k = 1;
112     uint32_t result = 0;
113 
114     while (Read(1) == 0 && mBufferEOF == false)
115     {
116         i++;
117     }
118 
119     j = Read(i);
120     result = j - 1 + (k << i);
121     return result;
122 }