Skip to content

Commit d2b5163

Browse files
committed
refactor: enhance XML documentation across Buffer classes and senders
1 parent 6564091 commit d2b5163

File tree

7 files changed

+226
-55
lines changed

7 files changed

+226
-55
lines changed

src/net-questdb-client/Buffers/BufferStreamContent.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ namespace QuestDB.Buffers;
3232
/// </summary>
3333
internal class BufferStreamContent : HttpContent
3434
{
35+
/// <summary>
36+
/// Initializes a new instance of the <see cref="BufferStreamContent"/> class.
37+
/// </summary>
38+
/// <param name="buffer">The buffer to wrap for HTTP streaming.</param>
3539
public BufferStreamContent(IBuffer buffer)
3640
{
3741
Buffer = buffer;

src/net-questdb-client/Buffers/BufferV1.cs

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ public class BufferV1 : IBuffer
4646
private bool _noSymbols = true;
4747
private bool _quoted;
4848

49-
/// <summary />
49+
/// <summary>
50+
/// Initializes a new instance of BufferV1 for writing ILP (InfluxDB Line Protocol) messages.
51+
/// </summary>
52+
/// <param name="bufferSize">Initial size of each buffer chunk, in bytes.</param>
53+
/// <param name="maxNameLen">Maximum allowed UTF-8 byte length for table and column names.</param>
54+
/// <param name="maxBufSize">Maximum total buffer size across all chunks, in bytes.</param>
5055
public BufferV1(int bufferSize, int maxNameLen, int maxBufSize)
5156
{
5257
Chunk = new byte[bufferSize];
@@ -76,13 +81,13 @@ public IBuffer Transaction(ReadOnlySpan<char> tableName)
7681
if (WithinTransaction)
7782
{
7883
throw new IngressError(ErrorCode.InvalidApiCall,
79-
"Cannot start another transaction - only one allowed at a time.");
84+
"Cannot start another transaction - only one allowed at a time.");
8085
}
8186

8287
if (Length > 0)
8388
{
8489
throw new IngressError(ErrorCode.InvalidApiCall,
85-
"Buffer must be clear before you can start a transaction.");
90+
"Buffer must be clear before you can start a transaction.");
8691
}
8792

8893
GuardInvalidTableName(tableName);
@@ -250,7 +255,7 @@ public IBuffer Table(ReadOnlySpan<char> name)
250255
if (WithinTransaction && name != _currentTableName)
251256
{
252257
throw new IngressError(ErrorCode.InvalidApiCall,
253-
"Transactions can only be for one table.");
258+
"Transactions can only be for one table.");
254259
}
255260

256261
GuardTableAlreadySet();
@@ -372,7 +377,7 @@ public IBuffer ColumnNanos(ReadOnlySpan<char> name, long timestampNanos)
372377
return this;
373378
}
374379

375-
/// <summary />
380+
/// <inheritdoc />
376381
public IBuffer EncodeUtf8(ReadOnlySpan<char> name)
377382
{
378383
foreach (var c in name)
@@ -390,15 +395,15 @@ public IBuffer EncodeUtf8(ReadOnlySpan<char> name)
390395
return this;
391396
}
392397

393-
/// <summary />
398+
/// <inheritdoc />
394399
[MethodImpl(MethodImplOptions.AggressiveInlining)]
395400
public IBuffer PutAscii(char c)
396401
{
397402
Put((byte)c);
398403
return this;
399404
}
400405

401-
/// <summary />
406+
/// <inheritdoc />
402407
[MethodImpl(MethodImplOptions.AggressiveInlining)]
403408
public void Put(ReadOnlySpan<char> chars)
404409
{
@@ -415,7 +420,7 @@ public IBuffer Put(long value)
415420
if (value == long.MinValue)
416421
{
417422
throw new IngressError(ErrorCode.InvalidApiCall, "Special case, long.MinValue cannot be handled by QuestDB",
418-
new ArgumentOutOfRangeException());
423+
new ArgumentOutOfRangeException());
419424
}
420425

421426
Span<byte> num = stackalloc byte[20];
@@ -443,26 +448,26 @@ public IBuffer Put(long value)
443448
return this;
444449
}
445450

446-
/// <summary />
451+
/// <inheritdoc />
447452
public virtual IBuffer Column<T>(ReadOnlySpan<char> name, ReadOnlySpan<T> value) where T : struct
448453
{
449454
throw new IngressError(ErrorCode.ProtocolVersionError, "Protocol Version V1 does not support ARRAY types");
450455
}
451456

452-
/// <summary />
457+
/// <inheritdoc />
453458
public virtual IBuffer Column(ReadOnlySpan<char> name, Array? value)
454459
{
455460
throw new IngressError(ErrorCode.ProtocolVersionError, "Protocol Version V1 does not support ARRAY types");
456461
}
457462

458-
/// <summary />
463+
/// <inheritdoc />
459464
public virtual IBuffer Column<T>(ReadOnlySpan<char> name, IEnumerable<T> value, IEnumerable<int> shape)
460465
where T : struct
461466
{
462467
throw new IngressError(ErrorCode.ProtocolVersionError, "Protocol Version V1 does not support ARRAY types");
463468
}
464469

465-
/// <summary />
470+
/// <inheritdoc />
466471
[MethodImpl(MethodImplOptions.AggressiveInlining)]
467472
public IBuffer Put(byte value)
468473
{
@@ -527,10 +532,16 @@ private void GuardExceededMaxBufferSize()
527532
if (Length > _maxBufSize)
528533
{
529534
throw new IngressError(ErrorCode.InvalidApiCall,
530-
$"Exceeded maximum buffer size. Current: {Length} Maximum: {_maxBufSize}");
535+
$"Exceeded maximum buffer size. Current: {Length} Maximum: {_maxBufSize}");
531536
}
532537
}
533538

539+
/// <summary>
540+
/// Writes the column name to the buffer and prepares for writing the column value by appending the appropriate separator and equals sign.
541+
/// </summary>
542+
/// <param name="columnName">The column name to write.</param>
543+
/// <returns>The buffer instance for fluent chaining.</returns>
544+
/// <exception cref="IngressError">Thrown if the table is not set, the column name is invalid, or the name exceeds the maximum length.</exception>
534545
internal IBuffer Column(ReadOnlySpan<char> columnName)
535546
{
536547
GuardFsFileNameLimit(columnName);
@@ -550,16 +561,26 @@ internal IBuffer Column(ReadOnlySpan<char> columnName)
550561
return EncodeUtf8(columnName).PutAscii('=');
551562
}
552563

564+
/// <summary>
565+
/// Validates that the requested additional byte count does not exceed the chunk size.
566+
/// </summary>
567+
/// <param name="additional">The number of additional bytes requested.</param>
568+
/// <exception cref="IngressError">Thrown with <see cref="ErrorCode.InvalidApiCall"/> if the requested size exceeds the chunk length.</exception>
553569
[MethodImpl(MethodImplOptions.AggressiveInlining)]
554570
internal void GuardAgainstOversizedChunk(int additional)
555571
{
556572
if (additional > Chunk.Length)
557573
{
558574
throw new IngressError(ErrorCode.InvalidApiCall,
559-
"tried to allocate oversized chunk: " + additional + " bytes");
575+
"tried to allocate oversized chunk: " + additional + " bytes");
560576
}
561577
}
562578

579+
/// <summary>
580+
/// Ensures that the current chunk has enough space to write the specified number of additional bytes; switches to the next buffer chunk if needed.
581+
/// </summary>
582+
/// <param name="additional">The number of additional bytes required.</param>
583+
/// <exception cref="IngressError">Thrown if the requested size exceeds the chunk size.</exception>
563584
[MethodImpl(MethodImplOptions.AggressiveInlining)]
564585
internal void EnsureCapacity(int additional)
565586
{
@@ -571,11 +592,9 @@ internal void EnsureCapacity(int additional)
571592
}
572593

573594
/// <summary>
574-
/// Encodes the specified character as UTF-8 into the current chunk and advances the write position by the number of bytes written.
595+
/// Writes a non-ASCII character as UTF-8 to the buffer, switching to the next buffer chunk if insufficient space remains.
575596
/// </summary>
576-
/// <remarks>
577-
/// If the current chunk has fewer than four bytes free, switches to the next buffer before writing.
578-
/// </remarks>
597+
/// <param name="c">The character to encode and write.</param>
579598
private void PutUtf8(char c)
580599
{
581600
if (Position + 4 >= Chunk.Length)
@@ -589,6 +608,13 @@ private void PutUtf8(char c)
589608
Advance(byteLength);
590609
}
591610

611+
/// <summary>
612+
/// Writes an ASCII character to the buffer, applying ILP escaping rules based on context (quoted or unquoted).
613+
/// </summary>
614+
/// <param name="c">The ASCII character to write.</param>
615+
/// <remarks>
616+
/// Escapes space, comma, equals, newline, carriage return, quote, and backslash characters according to ILP protocol requirements.
617+
/// </remarks>
592618
private void PutSpecial(char c)
593619
{
594620
switch (c)
@@ -702,7 +728,7 @@ private static void GuardInvalidTableName(ReadOnlySpan<char> tableName)
702728
if (tableName.IsEmpty)
703729
{
704730
throw new IngressError(ErrorCode.InvalidName,
705-
"Table names must have a non-zero length.");
731+
"Table names must have a non-zero length.");
706732
}
707733

708734
var prev = '\0';
@@ -715,7 +741,7 @@ private static void GuardInvalidTableName(ReadOnlySpan<char> tableName)
715741
if (i == 0 || i == tableName.Length - 1 || prev == '.')
716742
{
717743
throw new IngressError(ErrorCode.InvalidName,
718-
$"Bad string {tableName}. Found invalid dot `.` at position {i}.");
744+
$"Bad string {tableName}. Found invalid dot `.` at position {i}.");
719745
}
720746

721747
break;
@@ -750,10 +776,10 @@ private static void GuardInvalidTableName(ReadOnlySpan<char> tableName)
750776
case '\x000f':
751777
case '\x007f':
752778
throw new IngressError(ErrorCode.InvalidName,
753-
$"Bad string {tableName}. Table names can't contain a {c} character, which was found at byte position {i}");
779+
$"Bad string {tableName}. Table names can't contain a {c} character, which was found at byte position {i}");
754780
case '\xfeff':
755781
throw new IngressError(ErrorCode.InvalidName,
756-
$"Bad string {tableName}. Table names can't contain a UTF-8 BOM character, was was found at byte position {i}.");
782+
$"Bad string {tableName}. Table names can't contain a UTF-8 BOM character, was was found at byte position {i}.");
757783
}
758784

759785
prev = c;
@@ -770,7 +796,7 @@ private static void GuardInvalidColumnName(ReadOnlySpan<char> columnName)
770796
if (columnName.IsEmpty)
771797
{
772798
throw new IngressError(ErrorCode.InvalidName,
773-
"Column names must have a non-zero length.");
799+
"Column names must have a non-zero length.");
774800
}
775801

776802
for (var i = 0; i < columnName.Length; i++)
@@ -811,10 +837,10 @@ private static void GuardInvalidColumnName(ReadOnlySpan<char> columnName)
811837
case '\x000f':
812838
case '\x007f':
813839
throw new IngressError(ErrorCode.InvalidName,
814-
$"Bad string {columnName}. Column names can't contain a {c} character, which was found at byte position {i}");
840+
$"Bad string {columnName}. Column names can't contain a {c} character, which was found at byte position {i}");
815841
case '\xfeff':
816842
throw new IngressError(ErrorCode.InvalidName,
817-
$"Bad string {columnName}. Column names can't contain a UTF-8 BOM character, was was found at byte position {i}.");
843+
$"Bad string {columnName}. Column names can't contain a UTF-8 BOM character, was was found at byte position {i}.");
818844
}
819845
}
820846
}
@@ -833,7 +859,7 @@ private void GuardFsFileNameLimit(ReadOnlySpan<char> name)
833859
if (Encoding.UTF8.GetBytes(name.ToString()).Length > _maxNameLen)
834860
{
835861
throw new IngressError(ErrorCode.InvalidApiCall,
836-
$"Name is too long, must be under {_maxNameLen} bytes.");
862+
$"Name is too long, must be under {_maxNameLen} bytes.");
837863
}
838864
}
839865

0 commit comments

Comments
 (0)