Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
swap_bank.cc
Go to the documentation of this file.
1 
2 #include <swap_bank.h>
3 
4 #include <string.h>
5 
6 #include <iostream>
7 using namespace std;
8 
9 #include <JANA/JException.h>
10 using namespace jana;
11 
12 //---------------------------------
13 // swap_bank
14 //---------------------------------
15 uint32_t swap_bank(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)
16 {
17  /// Swap an EVIO bank. If the bank contains data, it is automatically
18  /// swapped according to it's type. If the bank is a container of other
19  /// containers, then this repeatedly calls the swapper methods for the
20  /// appropriate container type (bank, tagsegment, segment). This means
21  /// that this method will be recursive in the cases where it is a bank
22  /// of banks.
23 
24  if(len < 2) throw JException("Attempt to swap bank with len<2", __FILE__, __LINE__);
25 
26  // Swap length and header words
27  swap_block(inbuff, 2, outbuff);
28  uint32_t bank_len = outbuff[0];
29  if((bank_len+1) > len){
30  stringstream ss;
31  ss << "WARNING: Bank length word exceeds valid words in buffer (" << bank_len+1 << " > " << len << ")";
32  throw JException(ss.str(), __FILE__, __LINE__);
33  }
34  if( bank_len < 1 ){
35  throw JException("EVIO bank length word is zero in swap_bank!", __FILE__, __LINE__);
36  }
37 
38  uint32_t type = (outbuff[1]>>8) & 0xFF;
39  uint32_t Nwords = bank_len - 1;
40  uint32_t Nswapped = 2;
41  switch(type){
42  case 0x0a: // 64 bit unsigned int
43  case 0x08: // 64 bit double
44  case 0x09: // 64 bit signed int
45  swap_block((uint64_t*)&inbuff[2], Nwords/2, (uint64_t*)&outbuff[2]);
46  Nswapped += Nwords;
47  break;
48  case 0x01: // 32 bit unsigned int
49  case 0x02: // 32 bit float
50  case 0x0b: // 32 bit signed int
51  swap_block(&inbuff[2], Nwords, &outbuff[2]);
52  Nswapped += Nwords;
53  break;
54  case 0x05: // 16 bit unsigned int
55  case 0x04: // 16 bit signed int
56  swap_block((uint16_t*)&inbuff[2], Nwords*2, (uint16_t*)&outbuff[2]);
57  Nswapped += Nwords;
58  break;
59  case 0x00: // 32 bit unknown (not swapped)
60  case 0x07: // 8 bit unsigned int
61  case 0x06: // 8 bit signed int
62  if( inbuff!=outbuff ) memcpy((uint8_t*)&outbuff[2], (uint8_t*)&inbuff[2], Nwords*sizeof(uint32_t));
63  Nswapped += Nwords;
64  break;
65  case 0x0c:
66  while(Nswapped < (Nwords+2)){
67  uint32_t N = swap_tagsegment(&outbuff[Nswapped], &inbuff[Nswapped], (Nwords+2)-Nswapped);
68  if(N == 0) return Nswapped;
69  Nswapped += N;
70  }
71  break;
72  case 0x0d:
73  case 0x20:
74  while(Nswapped < (Nwords+2)){
75  uint32_t N = swap_segment(&outbuff[Nswapped], &inbuff[Nswapped], (Nwords+2)-Nswapped);
76  if(N == 0) return Nswapped;
77  Nswapped += N;
78  }
79  break;
80  case 0x0e:
81  case 0x10:
82  while(Nswapped < (Nwords+2)){
83  uint32_t N = swap_bank(&outbuff[Nswapped], &inbuff[Nswapped], (Nwords+2)-Nswapped);
84  if(N == 0) return Nswapped;
85  Nswapped += N;
86  }
87  break;
88  default:
89  stringstream ss;
90  ss << "WARNING: unknown bank type (0x" << hex << type << dec << ")";
91  throw JException(ss.str(), __FILE__, __LINE__);
92 
93  break;
94  }
95 
96  return Nswapped;
97 }
98 
99 //---------------------------------
100 // swap_tagsegment
101 //---------------------------------
102 uint32_t swap_tagsegment(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)
103 {
104  /// Swap an EVIO tagsegment.
105 
106  if(len < 1) throw JException("Attempt to swap segment with len<1");
107 
108  // Swap header/length word
109  swap_block(inbuff, 1, outbuff);
110  uint32_t bank_len = outbuff[0] & 0xFFFF;
111  if((bank_len) > len){
112  stringstream ss;
113  ss << "Segment length word exceeds valid words in buffer (" << bank_len << " > " << len << ")";
114  throw JException(ss.str(), __FILE__, __LINE__);
115  }
116 
117  uint32_t type = (outbuff[0]>>16) & 0x0F;
118  uint32_t Nwords = bank_len;
119  uint32_t Nswapped = 1;
120  switch(type){
121  case 0x0a: // 64 bit unsigned int
122  case 0x08: // 64 bit double
123  case 0x09: // 64 bit signed int
124  swap_block((uint64_t*)&inbuff[1], Nwords/2, (uint64_t*)&outbuff[1]);
125  Nswapped += Nwords;
126  break;
127  case 0x01: // 32 bit unsigned int
128  case 0x02: // 32 bit float
129  case 0x0b: // 32 bit signed int
130  swap_block(&inbuff[1], Nwords, &outbuff[1]);
131  Nswapped += Nwords;
132  break;
133  case 0x05: // 16 bit unsigned int
134  case 0x04: // 16 bit signed int
135  swap_block((uint16_t*)&inbuff[1], Nwords*2, (uint16_t*)&outbuff[1]);
136  Nswapped += Nwords;
137  break;
138  case 0x00: // 32 bit unknown (not swapped)
139  case 0x07: // 8 bit unsigned int
140  case 0x06: // 8 bit signed int
141  if( inbuff!=outbuff ) memcpy((uint8_t*)&outbuff[1], (uint8_t*)&inbuff[1], Nwords*sizeof(uint32_t));
142  Nswapped += Nwords;
143  break;
144  }
145 
146  return Nswapped;
147 }
148 
149 //---------------------------------
150 // swap_segment
151 //---------------------------------
152 uint32_t swap_segment(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)
153 {
154  /// Swap an EVIO segment.
155 
156  if(len < 1) throw JException("Attempt to swap segment with len<1");
157 
158  // Swap header/length word
159  swap_block(inbuff, 1, outbuff);
160  uint32_t bank_len = outbuff[0] & 0xFFFF;
161  if((bank_len) > len){
162  stringstream ss;
163  ss << "Segment length word exceeds valid words in buffer (" << bank_len << " > " << len << ")";
164  throw JException(ss.str(), __FILE__, __LINE__);
165  }
166 
167  uint32_t type = (outbuff[0]>>16) & 0x3F;
168  uint32_t Nwords = bank_len;
169  uint32_t Nswapped = 1;
170  switch(type){
171  case 0x0a: // 64 bit unsigned int
172  case 0x08: // 64 bit double
173  case 0x09: // 64 bit signed int
174  swap_block((uint64_t*)&inbuff[1], Nwords/2, (uint64_t*)&outbuff[1]);
175  Nswapped += Nwords;
176  break;
177  case 0x01: // 32 bit unsigned int
178  case 0x02: // 32 bit float
179  case 0x0b: // 32 bit signed int
180  swap_block(&inbuff[1], Nwords, &outbuff[1]);
181  Nswapped += Nwords;
182  break;
183  case 0x05: // 16 bit unsigned int
184  case 0x04: // 16 bit signed int
185  swap_block((uint16_t*)&inbuff[1], Nwords*2, (uint16_t*)&outbuff[1]);
186  Nswapped += Nwords;
187  break;
188  case 0x00: // 32 bit unknown (not swapped)
189  case 0x07: // 8 bit unsigned int
190  case 0x06: // 8 bit signed int
191  if( inbuff!=outbuff ) memcpy((uint8_t*)&outbuff[1], (uint8_t*)&inbuff[1], Nwords*sizeof(uint32_t));
192  Nswapped += Nwords;
193  break;
194  }
195 
196  return Nswapped;
197 }
uint32_t swap_bank(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)
Definition: swap_bank.cc:15
void swap_block(uint16_t *inbuff, uint16_t len, uint16_t *outbuff)
Definition: swap_bank.h:45
uint32_t swap_tagsegment(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)
Definition: swap_bank.cc:102
uint32_t swap_segment(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)
Definition: swap_bank.cc:152