My Project
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
bitStack.c
Go to the documentation of this file.
1 /*==============================================================================
2  File Name: bitStacker.cpp
3  Author : ccortiz
4 
5  Description:
6  Class for stack and unstack bits in a byte buffer.
7  ==============================================================================
8 */
9 
10 #include "bitStack.h"
11 #include <stdio.h>
12 
13 #if _ALLOW_MALLOC_ == 0
14 /* Reserve maximum amount of memory allowed for BITSTACK. */
15 struct c_bitStack_Privates bitStack_Instances[_MAX_BITSTACK_INSTANCES_];
16 #else
17 #include <stdlib.h>
18 #endif
19 
20 /* Private functions. */
21 static void swap16(uint16 *data);
22 static void swap32(uint32 *data);
23 static enum endianness getSystemEndianness(void);
24 static void resetUnstack(uint16 bitStackDescriptor);
25 
26 enum endianness endianType; /*Indica el endianness del sistema.*/
28 uint16 nBitStackObjs = 0; /*Indica el numero de instancias realizadas de la clase bitStack.*/
29 
30 int new_bitStack(void){
31  bitStack_PrivatesPtr newObj;
32 
34 
36  /* No more instances allowed. */
37  return -1;
38  }
39 
40 #if _ALLOW_MALLOC_==0
41  newObj =&bitStack_Instances[nObjs];
42 #else
43  newObj = (bitStack_PrivatesPtr)malloc(sizeof(struct c_bitStack_Privates));
44 #endif
45 
46  if (newObj==0){
47  return -1;
48  }
49  else{
50  /* Inicializa variables del objeto. */
51 
52  bitStack_Objs[nBitStackObjs] = newObj;
53  }
54 
55  nBitStackObjs++;
56 
57  /* Configure the default endianness for outputs. */
59 
61  newObj->unstackIndex=0;
62 
63  return nBitStackObjs-1;
64 }
65 
66 void clearStack(uint16 bitStackDescriptor){
67  uint32 i = 0;
68 
69  bitStack_Objs[bitStackDescriptor]->auxUsedBits = 0;
70  bitStack_Objs[bitStackDescriptor]->stackSize = 0;
71 
72  for (i=0; i<_MAX_DATA_STACK_SIZE_; i++){
73  bitStack_Objs[bitStackDescriptor]->dataStack[i] = 0;
74  }
75 
76  /* Reset unstack variables. */
77  resetUnstack(bitStackDescriptor);
78 }
79 
80 void resetUnstack(uint16 bitStackDescriptor){
81  bitStack_Objs[bitStackDescriptor]->firstUnstak = _TRUE_;
82 }
83 
85  sint32 i = 1;
86  char *p = (char *) &i;
87 
88  if (p[0] == 1) {
89  return _LITTLE_ENDIAN_;
90  } else {
91  return _BIG_ENDIAN_;
92  }
93 }
94 
95 sint32 stackData(uint16 bitStackDescriptor, unsigned char* data, uint32 dataLength){
96 
97  char dataBuffer[8];
98 
99  byte bitState;
100  byte dataByte;
101  byte auxByte;
102  uint32 dataUsedBits = 0;
103  uint32 byteCounter=0;
104  uint32 i=0;
105 
106  memcpy(dataBuffer, data, (dataLength/8) + (((dataLength%8)>0)?1:0) );
107 
108  if (dataLength==16 || dataLength==32){
109  if (endianType != bitStack_Objs[bitStackDescriptor]->outputEndianness){
110  if (dataLength==32){
111  swap32((uint32*)dataBuffer);
112  }
113  else{
114  swap16((uint16*)dataBuffer);
115  }
116  }
117  }
118  else{
119 
120  if (endianType==_BIG_ENDIAN_){
121  if (dataLength>16 && dataLength<32){
122  swap32((uint32*)dataBuffer);
123  }
124  else{
125  if (dataLength>8 && dataLength<16){
126  swap16((uint16*)dataBuffer);
127  }
128  else{
129  /*Aqui habria que contemplar el caso de campos de entre 32 y 64 bits*/
130  }
131  }
132  }
133  }
134 
135 
136  dataByte = *dataBuffer;
137  auxByte = bitStack_Objs[bitStackDescriptor]->dataStack[bitStack_Objs[bitStackDescriptor]->stackSize];
138 
139  for (i=0; i<dataLength; i++){
140  bitState = dataByte & 0x1;
141  auxByte = auxByte | (bitState<<bitStack_Objs[bitStackDescriptor]->auxUsedBits);
142  bitStack_Objs[bitStackDescriptor]->auxUsedBits++;
143  dataUsedBits++;
144 
145  if (bitStack_Objs[bitStackDescriptor]->auxUsedBits==8){
146  bitStack_Objs[bitStackDescriptor]->auxUsedBits = 0;
147  bitStack_Objs[bitStackDescriptor]->dataStack[bitStack_Objs[bitStackDescriptor]->stackSize++] = auxByte;
148  auxByte = 0;
149  }
150 
151  if (dataUsedBits==8 && (i+1)<dataLength)
152  {
153  dataUsedBits = 0;
154  byteCounter++;
155  dataByte = *(dataBuffer + byteCounter);
156  }
157  else{
158  dataByte=dataByte>>1;
159  }
160  }
161 
162  if (bitStack_Objs[bitStackDescriptor]->auxUsedBits!=0){
163  bitStack_Objs[bitStackDescriptor]->dataStack[bitStack_Objs[bitStackDescriptor]->stackSize] = auxByte;
164  }
165 
166  return 0;
167 }
168 
169 
170 uint32 unstackData(uint16 bitStackDescriptor, uint8 nBits){
171 
172  uint32 aux=0;
173  uint32 i=0;
174  uint32 j=0;
175 
176  if (bitStack_Objs[bitStackDescriptor]->firstUnstak){
177  bitStack_Objs[bitStackDescriptor]->firstUnstak= _FALSE_;
178  bitStack_Objs[bitStackDescriptor]->unstackedBit=0;
179  bitStack_Objs[bitStackDescriptor]->unstackedByte = bitStack_Objs[bitStackDescriptor]->dataStack[0];
180  bitStack_Objs[bitStackDescriptor]->unstackIndex=0;
181  }
182 
183  if (nBits>32){
184  _DBGMSG_("ERROR! Can't unstack more than 64bit at time.");
185  return 0;
186  }
187 
188  if (bitStack_Objs[bitStackDescriptor]->unstackIndex >= getStackSize(bitStackDescriptor)){
189  _DBGMSG_("ERROR! Empty Buffer!");
190  return 0;
191  }
192 
193  for (i=0; i<nBits; i++){
194  aux = aux >>1;
195 
196  if (bitStack_Objs[bitStackDescriptor]->unstackedByte & 0x1){
197  aux = aux | 0x80000000L;
198  }
199 
200  bitStack_Objs[bitStackDescriptor]->unstackedByte = bitStack_Objs[bitStackDescriptor]->unstackedByte >> 1;
201 
202  bitStack_Objs[bitStackDescriptor]->unstackedBit++;
203  if (bitStack_Objs[bitStackDescriptor]->unstackedBit >= 8){
204  bitStack_Objs[bitStackDescriptor]->unstackedBit=0;
205  if (bitStack_Objs[bitStackDescriptor]->unstackIndex<getStackSize(bitStackDescriptor)){
206  bitStack_Objs[bitStackDescriptor]->unstackIndex++;
207  bitStack_Objs[bitStackDescriptor]->unstackedByte = bitStack_Objs[bitStackDescriptor]->dataStack[bitStack_Objs[bitStackDescriptor]->unstackIndex];
208  }
209  else{
210  bitStack_Objs[bitStackDescriptor]->unstackedByte=0;
211  }
212  }
213  }
214 
215  for (j=0; j<(32-nBits); j++){
216  aux = aux >> 1;
217  }
218 
219  /* Make swappings. */
220  if (bitStack_Objs[bitStackDescriptor]->outputEndianness == _BIG_ENDIAN_){
221  if (nBits==16){
222  uint16 data = aux;
223  swap16(&data);
224  aux = data;
225  }
226 
227  if (nBits==32){
228  uint32 data = aux;
229  swap32(&data);
230  aux = data;
231  }
232  }
233  return aux;
234 }
235 
236 void showStack(uint16 bitStackDescriptor){
237 
238  uint32 i=0;
239 
240  for (i=0; i<getStackSize(bitStackDescriptor); i++){
241  printf("%.2X ",(uint32)(bitStack_Objs[bitStackDescriptor]->dataStack[i]));
242  }
243 }
244 
245 uint32 getStackSize(uint16 bitStackDescriptor){
246 
247  uint32 showLength = bitStack_Objs[bitStackDescriptor]->stackSize;
248 
249  if (bitStack_Objs[bitStackDescriptor]->auxUsedBits>0){
250  showLength++;
251  }
252 
253  return showLength;
254 }
255 
256 void setOutputEndianness(uint16 bitStackDescriptor, enum endianness endianType){
257  bitStack_Objs[bitStackDescriptor]->outputEndianness = endianType;
258 }
259 
260 byte_ptr getDataBuffer(uint16 bitStackDescriptor){
261  return bitStack_Objs[bitStackDescriptor]->dataStack;
262 }
263 
264 sint32 setDataBuffer(uint16 bitStackDescriptor, byte_ptr data,uint16 dataLength){
265  if (dataLength<_MAX_DATA_STACK_SIZE_){
266  memcpy(bitStack_Objs[bitStackDescriptor]->dataStack,data,dataLength);
267  bitStack_Objs[bitStackDescriptor]->stackSize = dataLength;
268  return 0;
269  }
270 
271  return -1;
272 }
273 
274 void swap16(uint16 *data){
275  byte b0 = ((*data)&0x00FF)>>0;
276  byte b1 = ((*data)&0xFF00)>>8;
277  *data = (b1) | (b0<<8);
278 }
279 
280 void swap32(uint32 *data){
281  byte b0 = ((*data)&0x000000FF)>>0;
282  byte b1 = ((*data)&0x0000FF00)>>8;
283  byte b2 = ((*data)&0x00FF0000)>>16;
284  byte b3 = ((*data)&0xFF000000)>>24;
285  *data = b3 | (b2<<8) | (b1<<16) | (b0<<24);
286 }
287