Parse the messages of a blr request. For specified message, allocate a format (Format) block.
| 184 | |
| 185 | // Parse the messages of a blr request. For specified message, allocate a format (Format) block. |
| 186 | void Routine::parseMessages(thread_db* tdbb, CompilerScratch* csb, BlrReader blrReader) |
| 187 | { |
| 188 | if (blrReader.getLength() < 2) |
| 189 | status_exception::raise(Arg::Gds(isc_metadata_corrupt)); |
| 190 | |
| 191 | csb->csb_blr_reader = blrReader; |
| 192 | |
| 193 | const SSHORT version = csb->csb_blr_reader.getByte(); |
| 194 | |
| 195 | switch (version) |
| 196 | { |
| 197 | case blr_version4: |
| 198 | case blr_version5: |
| 199 | //case blr_version6: |
| 200 | break; |
| 201 | |
| 202 | default: |
| 203 | status_exception::raise( |
| 204 | Arg::Gds(isc_metadata_corrupt) << |
| 205 | Arg::Gds(isc_wroblrver2) << Arg::Num(blr_version4) << Arg::Num(blr_version5/*6*/) << |
| 206 | Arg::Num(version)); |
| 207 | } |
| 208 | |
| 209 | if (csb->csb_blr_reader.getByte() != blr_begin) |
| 210 | status_exception::raise(Arg::Gds(isc_metadata_corrupt)); |
| 211 | |
| 212 | while (csb->csb_blr_reader.getByte() == blr_message) |
| 213 | { |
| 214 | const USHORT msgNumber = csb->csb_blr_reader.getByte(); |
| 215 | USHORT count = csb->csb_blr_reader.getWord(); |
| 216 | Format* format = Format::newFormat(*tdbb->getDefaultPool(), count); |
| 217 | |
| 218 | USHORT padField; |
| 219 | const bool shouldPad = csb->csb_message_pad.get(msgNumber, padField); |
| 220 | |
| 221 | USHORT maxAlignment = 0; |
| 222 | ULONG offset = 0; |
| 223 | USHORT i = 0; |
| 224 | |
| 225 | for (Format::fmt_desc_iterator desc = format->fmt_desc.begin(); i < count; ++i, ++desc) |
| 226 | { |
| 227 | const USHORT align = PAR_desc(tdbb, csb, &*desc); |
| 228 | if (align) |
| 229 | offset = FB_ALIGN(offset, align); |
| 230 | |
| 231 | desc->dsc_address = (UCHAR*)(IPTR) offset; |
| 232 | offset += desc->dsc_length; |
| 233 | |
| 234 | maxAlignment = MAX(maxAlignment, align); |
| 235 | |
| 236 | if (maxAlignment && shouldPad && i + 1 == padField) |
| 237 | offset = FB_ALIGN(offset, maxAlignment); |
| 238 | } |
| 239 | |
| 240 | format->fmt_length = offset; |
| 241 | |
| 242 | switch (msgNumber) |
| 243 | { |