fb-cpp 0.0.2
A modern C++ wrapper for the Firebird database API
Loading...
Searching...
No Matches
RequestMessageFormat.h
1/*
2 * MIT License
3 *
4 * Copyright (c) 2026 Adriano dos Santos Fernandes
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25#ifndef FBCPP_REQUEST_MESSAGE_FORMAT_H
26#define FBCPP_REQUEST_MESSAGE_FORMAT_H
27
28#include "../config.h"
29#include "fb-cpp-export.h"
30#include "../fb-api.h"
31#include "../types.h"
32#include "../Descriptor.h"
33#include "../Exception.h"
34#include <cstdint>
35#include <optional>
36#include <string>
37#include <vector>
38
39#if FB_CPP_USE_BOOST_MULTIPRECISION != 0
40#include <boost/multiprecision/cpp_int.hpp>
41#endif
42
43
47namespace fbcpp::request
48{
61 class FB_CPP_EXPORT RequestMessageFormat final
62 {
63 public:
67 RequestMessageFormat& addBool(bool isNullable)
68 {
69 return addField(DescriptorAdjustedType::BOOLEAN, 1u, 1u, 0, 0, 0, isNullable);
70 }
71
76 {
77 return addField(DescriptorAdjustedType::INT16, 2u, 2u, 0, 0, 0, isNullable);
78 }
79
83 RequestMessageFormat& addScaledInt16(bool isNullable, int scale)
84 {
85 return addField(DescriptorAdjustedType::INT16, 2u, 2u, scale, 0, 0, isNullable);
86 }
87
92 {
93 return addField(DescriptorAdjustedType::INT32, 4u, 4u, 0, 0, 0, isNullable);
94 }
95
99 RequestMessageFormat& addScaledInt32(bool isNullable, int scale)
100 {
101 return addField(DescriptorAdjustedType::INT32, 4u, 4u, scale, 0, 0, isNullable);
102 }
103
108 {
109 return addField(DescriptorAdjustedType::INT64, 8u, 8u, 0, 0, 0, isNullable);
110 }
111
115 RequestMessageFormat& addScaledInt64(bool isNullable, int scale)
116 {
117 return addField(DescriptorAdjustedType::INT64, 8u, 8u, scale, 0, 0, isNullable);
118 }
119
123 RequestMessageFormat& addScaledOpaqueInt128(bool isNullable, int scale)
124 {
125 return addField(DescriptorAdjustedType::INT128, 16u, 8u, scale, 0, 0, isNullable);
126 }
127
128#if FB_CPP_USE_BOOST_MULTIPRECISION != 0
132 RequestMessageFormat& addScaledBoostInt128(bool isNullable, int scale)
133 {
134 return addField(DescriptorAdjustedType::INT128, 16u, 8u, scale, 0, 0, isNullable);
135 }
136#endif
137
142 {
143 return addField(DescriptorAdjustedType::FLOAT, 4u, 4u, 0, 0, 0, isNullable);
144 }
145
150 {
151 return addField(DescriptorAdjustedType::DOUBLE, 8u, 8u, 0, 0, 0, isNullable);
152 }
153
158 {
159 return addField(DescriptorAdjustedType::DECFLOAT16, 8u, 8u, 0, 0, 0, isNullable);
160 }
161
166 {
167 return addField(DescriptorAdjustedType::DECFLOAT34, 16u, 8u, 0, 0, 0, isNullable);
168 }
169
174 {
175 return addField(DescriptorAdjustedType::DATE, 4u, 4u, 0, 0, 0, isNullable);
176 }
177
182 {
183 return addField(DescriptorAdjustedType::TIME, 4u, 4u, 0, 0, 0, isNullable);
184 }
185
190 {
191 return addField(DescriptorAdjustedType::TIMESTAMP, 8u, 4u, 0, 0, 0, isNullable);
192 }
193
198 {
199 return addField(DescriptorAdjustedType::TIME_TZ, 6u, 4u, 0, 0, 0, isNullable);
200 }
201
206 {
207 return addField(DescriptorAdjustedType::TIMESTAMP_TZ, 10u, 4u, 0, 0, 0, isNullable);
208 }
209
214 {
215 return addField(DescriptorAdjustedType::BLOB, 8u, 4u, 0, 0, 0, isNullable);
216 }
217
222 RequestMessageFormat& addString(bool isNullable, unsigned length, std::optional<unsigned> charSetId = {})
223 {
224 if (length == 0u || length > 65535u - sizeof(std::uint16_t))
225 throw FbCppException("Invalid string length");
226
227 return addField(DescriptorAdjustedType::STRING, length + sizeof(std::uint16_t), sizeof(std::uint16_t), 0,
228 charSetId.value_or(0u), 0, isNullable);
229 }
230
231 public:
235 unsigned getCount() const noexcept
236 {
237 return static_cast<unsigned>(descriptors.size());
238 }
239
243 const std::vector<Descriptor>& getDescriptors() const noexcept
244 {
245 return descriptors;
246 }
247
251 unsigned getLength() const noexcept
252 {
253 return length;
254 }
255
261 unsigned getBlrFieldIndex(unsigned index) const
262 {
263 if (index >= blrFieldIndexes.size())
264 throw std::out_of_range("index out of range");
265
266 return blrFieldIndexes[index];
267 }
268
273 std::vector<std::byte> buildBlrMessageClause(unsigned messageNumber) const;
274
275 private:
276 RequestMessageFormat& addField(DescriptorAdjustedType adjustedType, unsigned dataLength, unsigned alignment,
277 int scale, unsigned charSetId, int subType, bool isNullable);
278
279 static void appendByte(std::vector<std::byte>& blr, std::uint8_t value)
280 {
281 blr.push_back(static_cast<std::byte>(value));
282 }
283
284 static void appendWord(std::vector<std::byte>& blr, std::uint16_t value)
285 {
286 blr.push_back(static_cast<std::byte>(value & 0xffu));
287 blr.push_back(static_cast<std::byte>((value >> 8) & 0xffu));
288 }
289
290 void appendBlrDataType(std::vector<std::byte>& blr, const Descriptor& descriptor) const;
291
292 private:
293 std::vector<Descriptor> descriptors;
294 std::vector<unsigned> blrFieldIndexes;
295 unsigned nullableCount = 0;
296 unsigned length = 0;
297 };
298} // namespace fbcpp::request
299
300
301#endif // FBCPP_REQUEST_MESSAGE_FORMAT_H
Base exception class for all fb-cpp exceptions.
Definition Exception.h:231
Describes the fields of a Firebird request message.
RequestMessageFormat & addScaledInt16(bool isNullable, int scale)
Appends a scaled 16-bit signed integer field, optionally nullable.
RequestMessageFormat & addInt16(bool isNullable)
Appends a 16-bit signed integer field, optionally nullable.
RequestMessageFormat & addDouble(bool isNullable)
Appends a double precision floating-point field, optionally nullable.
RequestMessageFormat & addDecFloat16(bool isNullable)
Appends a 16-digit decimal floating-point field, optionally nullable.
RequestMessageFormat & addScaledOpaqueInt128(bool isNullable, int scale)
Appends a scaled 128-bit integer field in Firebird's representation, optionally nullable.
RequestMessageFormat & addScaledBoostInt128(bool isNullable, int scale)
Appends a scaled 128-bit integer field expressed with Boost.Multiprecision, optionally nullable.
RequestMessageFormat & addTimeTz(bool isNullable)
Appends a time-of-day field with timezone, optionally nullable.
unsigned getCount() const noexcept
Returns the number of fields.
RequestMessageFormat & addScaledInt32(bool isNullable, int scale)
Appends a scaled 32-bit signed integer field, optionally nullable.
unsigned getLength() const noexcept
Returns the total message length in bytes.
RequestMessageFormat & addBool(bool isNullable)
Appends a boolean field, optionally nullable.
RequestMessageFormat & addInt64(bool isNullable)
Appends a 64-bit signed integer field, optionally nullable.
RequestMessageFormat & addDate(bool isNullable)
Appends a date field, optionally nullable.
RequestMessageFormat & addBlobId(bool isNullable)
Appends a blob identifier field, optionally nullable.
RequestMessageFormat & addTimestamp(bool isNullable)
Appends a timestamp field without timezone, optionally nullable.
RequestMessageFormat & addScaledInt64(bool isNullable, int scale)
Appends a scaled 64-bit signed integer field, optionally nullable.
RequestMessageFormat & addDecFloat34(bool isNullable)
Appends a 34-digit decimal floating-point field, optionally nullable.
unsigned getBlrFieldIndex(unsigned index) const
Returns the index of the field inside the BLR message, which interleaves null indicators as extra ent...
const std::vector< Descriptor > & getDescriptors() const noexcept
Returns the descriptors of the appended fields, in declaration order.
RequestMessageFormat & addTimestampTz(bool isNullable)
Appends a timestamp field with timezone, optionally nullable.
RequestMessageFormat & addString(bool isNullable, unsigned length, std::optional< unsigned > charSetId={})
Appends a variable-length string field with the given maximum length in bytes, optionally nullable.
RequestMessageFormat & addTime(bool isNullable)
Appends a time-of-day field without timezone, optionally nullable.
RequestMessageFormat & addInt32(bool isNullable)
Appends a 32-bit signed integer field, optionally nullable.
RequestMessageFormat & addFloat(bool isNullable)
Appends a single precision floating-point field, optionally nullable.
fb-cpp request namespace.
Definition Request.cpp:32
DescriptorAdjustedType
Descriptor adjusted type.
Definition Descriptor.h:161