| 2503 | |
| 2504 | # Set the decimal value |
| 2505 | def set(self, value): |
| 2506 | assert ((self._buffer.offset + self.fbe_offset + self.fbe_size) <= self._buffer.size), "Model is broken!" |
| 2507 | if (self._buffer.offset + self.fbe_offset + self.fbe_size) > self._buffer.size: |
| 2508 | return 0 |
| 2509 | |
| 2510 | # Extract decimal parts |
| 2511 | parts = value.as_tuple() |
| 2512 | negative = True if parts.sign == 1 else False |
| 2513 | number = int(''.join(map(str, parts.digits))) |
| 2514 | scale = -parts.exponent |
| 2515 | |
| 2516 | # Check for decimal number overflow |
| 2517 | if (number.bit_length() < 0) or (number.bit_length() > 96): |
| 2518 | # Value too big for .NET Decimal (bit length is limited to [0, 96]) |
| 2519 | self.write_count(self.fbe_offset, 0, self.fbe_size) |
| 2520 | return self.fbe_size |
| 2521 | |
| 2522 | # Check for decimal scale overflow |
| 2523 | if (scale < 0) or (scale > 28): |
| 2524 | # Value scale exceeds .NET Decimal limit of [0, 28] |
| 2525 | self.write_count(self.fbe_offset, 0, self.fbe_size) |
| 2526 | return self.fbe_size |
| 2527 | |
| 2528 | # Write unscaled value to bytes 0-11 |
| 2529 | self.write_bytes(self.fbe_offset, number.to_bytes(12, "little")) |
| 2530 | |
| 2531 | # Write scale at byte 14 |
| 2532 | self.write_byte(self.fbe_offset + 14, scale) |
| 2533 | |
| 2534 | # Write signum at byte 15 |
| 2535 | self.write_byte(self.fbe_offset + 15, 0x80 if negative else 0) |
| 2536 | return self.fbe_size |
| 2537 | |
| 2538 | |
| 2539 | # Fast Binary Encoding bytes final model |