Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
hdbyte_swapout.cc
Go to the documentation of this file.
1 
2 // This is basically copied from HDEVIO.cc in the DAQ library of
3 // sim-recon. It has been modified to remove references to the
4 // HDEVIO class. The swap_bank, swap_segment, and swap_tagsegment
5 // routines were also modified to assume the inputs were of the
6 // native endianess and that we are swapping to the opposite.
7 
8 #include <string.h>
9 
10 
11 #include <iostream>
12 using namespace std;
13 
14 #include <hdbyte_swapout.h>
15 
16 
17 
18 //---------------------------------
19 // swap_block
20 //---------------------------------
21 void swap_block_out(uint16_t *inbuff, uint16_t len, uint16_t *outbuff)
22 {
23  for(uint32_t i=0; i<len; i++, inbuff++, outbuff++){
24  uint16_t inword = *inbuff; // copy word to allow using same buffer for input and output
25  uint8_t *inptr = (uint8_t*)&inword;
26  uint8_t *outptr = (uint8_t*)&outbuff[1];
27  *(--outptr) = *inptr++;
28  *(--outptr) = *inptr++;
29  }
30 }
31 
32 //---------------------------------
33 // swap_block
34 //---------------------------------
35 void swap_block_out(uint32_t *inbuff, uint32_t len, uint32_t *outbuff)
36 {
37  for(uint32_t i=0; i<len; i++, inbuff++, outbuff++){
38  uint32_t inword = *inbuff; // copy word to allow using same buffer for input and output
39  uint8_t *inptr = (uint8_t*)&inword;
40  uint8_t *outptr = (uint8_t*)&outbuff[1];
41  *(--outptr) = *inptr++;
42  *(--outptr) = *inptr++;
43  *(--outptr) = *inptr++;
44  *(--outptr) = *inptr++;
45  }
46 }
47 
48 //---------------------------------
49 // swap_block
50 //---------------------------------
51 void swap_block_out(uint64_t *inbuff, uint64_t len, uint64_t *outbuff)
52 {
53  for(uint32_t i=0; i<len; i++, inbuff++, outbuff++){
54  uint64_t inword = *inbuff; // copy word to allow using same buffer for input and output
55  uint8_t *inptr = (uint8_t*)&inword;
56  uint8_t *outptr = (uint8_t*)&outbuff[1];
57  *(--outptr) = *inptr++;
58  *(--outptr) = *inptr++;
59  *(--outptr) = *inptr++;
60  *(--outptr) = *inptr++;
61 
62  *(--outptr) = *inptr++;
63  *(--outptr) = *inptr++;
64  *(--outptr) = *inptr++;
65  *(--outptr) = *inptr++;
66  }
67 }
68 
69 //---------------------------------
70 // swap_bank
71 //---------------------------------
72 uint32_t swap_bank_out(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)
73 {
74  /// n.b. This was modified from the original which assumed we were
75  /// swapping from wrong endianess for the process to the right one.
76  /// This routine is being used by hdl3 to do the opposite.
77  ///
78  /// Swap an EVIO bank. If the bank contains data, it is automatically
79  /// swapped according to it's type. If the bank is a container of other
80  /// containers, then this repeatedly calls the swapper methods for the
81  /// appropriate container type (bank, tagsegment, segment). This means
82  /// that this method will be recursive in the cases where it is a bank
83  /// of banks.
84 
85  if(len < 2){
86  cerr << "Attempt to swap bank with len<2" << endl;
87  return 0;
88  }
89 
90  // Swap length and header words
91  swap_block_out(inbuff, 2, outbuff);
92  uint32_t bank_len = inbuff[0];
93  if((bank_len+1) > len){
94  cerr << "WARNING: Bank length word exceeds valid words in buffer (" << bank_len+1 << " > " << len << ")" << endl;
95  return 0;
96  }
97 
98  uint32_t type = (inbuff[1]>>8) & 0xFF;
99  uint32_t Nwords = bank_len - 1; // number of 32bit payload words
100  uint32_t Nswapped = 2;
101  switch(type){
102  case 0x0a: // 64 bit unsigned int
103  case 0x08: // 64 bit double
104  case 0x09: // 64 bit signed int
105  swap_block_out((uint64_t*)&inbuff[2], Nwords/2, (uint64_t*)&outbuff[2]);
106  Nswapped += Nwords;
107  break;
108  case 0x01: // 32 bit unsigned int
109  case 0x02: // 32 bit float
110  case 0x0b: // 32 bit signed int
111  swap_block_out(&inbuff[2], Nwords, &outbuff[2]);
112  Nswapped += Nwords;
113  break;
114  case 0x05: // 16 bit unsigned int
115  case 0x04: // 16 bit signed int
116  swap_block_out((uint16_t*)&inbuff[2], Nwords*2, (uint16_t*)&outbuff[2]);
117  Nswapped += Nwords;
118  break;
119  case 0x00: // 32 bit unknown (not swapped)
120  case 0x07: // 8 bit unsigned int
121  case 0x06: // 8 bit signed int
122  memcpy((uint8_t*)&outbuff[2], (uint8_t*)&inbuff[2], Nwords*sizeof(uint32_t));
123  Nswapped += Nwords;
124  break;
125  case 0x0c:
126  while(Nswapped < (Nwords+2)){
127  uint32_t N = swap_tagsegment_out(&outbuff[Nswapped], &inbuff[Nswapped], (Nwords+2)-Nswapped);
128  if(N == 0) return Nswapped;
129  Nswapped += N;
130  }
131  break;
132  case 0x0d:
133  case 0x20:
134  while(Nswapped < (Nwords+2)){
135  uint32_t N = swap_segment_out(&outbuff[Nswapped], &inbuff[Nswapped], (Nwords+2)-Nswapped);
136  if(N == 0) return Nswapped;
137  Nswapped += N;
138  }
139  break;
140  case 0x0e:
141  case 0x10:
142  while(Nswapped < (Nwords+2)){
143  uint32_t N = swap_bank_out(&outbuff[Nswapped], &inbuff[Nswapped], (Nwords+2)-Nswapped);
144  if(N == 0) return Nswapped;
145  Nswapped += N;
146  }
147  break;
148  default:
149  cerr << "WARNING: unknown bank type (0x" << hex << type << dec << ")" << endl;
150  return 0;
151  break;
152  }
153 
154  return Nswapped;
155 }
156 
157 //---------------------------------
158 // swap_tagsegment
159 //---------------------------------
160 uint32_t swap_tagsegment_out(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)
161 {
162  /// Swap an EVIO tagsegment.
163 
164  if(len < 1){
165  cerr << "Attempt to swap segment with len<1" << endl;
166  return 0;
167  }
168 
169  // Swap header/length word
170  swap_block_out(inbuff, 1, outbuff);
171  uint32_t bank_len = inbuff[0] & 0xFFFF;
172  if((bank_len) > len){
173  cerr << "Tag Segment length word exceeds valid words in buffer (" << bank_len << " > " << len << ")" << endl;
174  return 0;
175  }
176 
177  uint32_t type = (inbuff[0]>>16) & 0x0F;
178  uint32_t Nwords = bank_len;
179  uint32_t Nswapped = 1;
180  switch(type){
181  case 0x0a: // 64 bit unsigned int
182  case 0x08: // 64 bit double
183  case 0x09: // 64 bit signed int
184  swap_block_out((uint64_t*)&inbuff[1], Nwords/2, (uint64_t*)&outbuff[1]);
185  Nswapped += Nwords;
186  break;
187  case 0x01: // 32 bit unsigned int
188  case 0x02: // 32 bit float
189  case 0x0b: // 32 bit signed int
190  swap_block_out(&inbuff[1], Nwords, &outbuff[1]);
191  Nswapped += Nwords;
192  break;
193  case 0x05: // 16 bit unsigned int
194  case 0x04: // 16 bit signed int
195  swap_block_out((uint16_t*)&inbuff[1], Nwords*2, (uint16_t*)&outbuff[1]);
196  Nswapped += Nwords;
197  break;
198  case 0x00: // 32 bit unknown (not swapped)
199  case 0x07: // 8 bit unsigned int
200  case 0x06: // 8 bit signed int
201  memcpy((uint8_t*)&outbuff[1], (uint8_t*)&inbuff[1], Nwords*sizeof(uint32_t));
202  Nswapped += Nwords;
203  break;
204  }
205 
206  return Nswapped;
207 }
208 
209 //---------------------------------
210 // swap_segment
211 //---------------------------------
212 uint32_t swap_segment_out(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)
213 {
214  /// Swap an EVIO segment.
215  ///
216  /// n.b. This was modified from the original which assumed we were
217  /// swapping from wrong endianess for the process to the right one.
218  /// This routine is being used by hdl3 to do the opposite.
219 
220  if(len < 1){
221  cerr << "Attempt to swap segment with len<1" << endl;
222  return 0;
223  }
224 
225  // Swap header/length word
226  swap_block_out(inbuff, 1, outbuff);
227  uint32_t bank_len = inbuff[0] & 0xFFFF;
228  if((bank_len) > len){
229  cerr << "Segment length word exceeds valid words in buffer (" << bank_len << " > " << len << ")" << endl;
230  return 0;
231  }
232 
233  uint32_t type = (inbuff[0]>>16) & 0x3F;
234  uint32_t Nwords = bank_len;
235  uint32_t Nswapped = 1;
236  switch(type){
237  case 0x0a: // 64 bit unsigned int
238  case 0x08: // 64 bit double
239  case 0x09: // 64 bit signed int
240  swap_block_out((uint64_t*)&inbuff[1], Nwords/2, (uint64_t*)&outbuff[1]);
241  Nswapped += Nwords;
242  break;
243  case 0x01: // 32 bit unsigned int
244  case 0x02: // 32 bit float
245  case 0x0b: // 32 bit signed int
246  swap_block_out(&inbuff[1], Nwords, &outbuff[1]);
247  Nswapped += Nwords;
248  break;
249  case 0x05: // 16 bit unsigned int
250  case 0x04: // 16 bit signed int
251  swap_block_out((uint16_t*)&inbuff[1], Nwords*2, (uint16_t*)&outbuff[1]);
252  Nswapped += Nwords;
253  break;
254  case 0x00: // 32 bit unknown (not swapped)
255  case 0x07: // 8 bit unsigned int
256  case 0x06: // 8 bit signed int
257  memcpy((uint8_t*)&outbuff[1], (uint8_t*)&inbuff[1], Nwords*sizeof(uint32_t));
258  Nswapped += Nwords;
259  break;
260  }
261 
262  return Nswapped;
263 }
void swap_block_out(uint16_t *inbuff, uint16_t len, uint16_t *outbuff)
uint32_t swap_tagsegment_out(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)
uint32_t swap_segment_out(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)
uint32_t swap_bank_out(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)