Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit c28a5de

Browse files
bshafferchingor13
authored andcommitted
Enables bignums for span IDs (#192)
* enables bignums for span IDs * only uses baseConvert if the span ID is sufficiently large * fix cs * correct variable name * minor optimization
1 parent c8b4fc6 commit c28a5de

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

src/Trace/Propagator/CloudTraceFormatter.php

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function deserialize($header)
4242
return new SpanContext(
4343
strtolower($matches[1]),
4444
array_key_exists(2, $matches) && !empty($matches[2])
45-
? dechex((int)($matches[2]))
45+
? $this->decToHex($matches[2])
4646
: null,
4747
array_key_exists(3, $matches) ? $matches[3] == '1' : null,
4848
true
@@ -61,11 +61,65 @@ public function serialize(SpanContext $context)
6161
{
6262
$ret = '' . $context->traceId();
6363
if ($context->spanId()) {
64-
$ret .= '/' . hexdec($context->spanId());
64+
$ret .= '/' . $this->hexToDec($context->spanId());
6565
}
6666
if ($context->enabled() !== null) {
6767
$ret .= ';o=' . ($context->enabled() ? '1' : '0');
6868
}
6969
return $ret;
7070
}
71+
72+
private function decToHex($numstring)
73+
{
74+
$int = (int) $numstring;
75+
if ($this->isBigNum($int)) {
76+
return $this->baseConvert($numstring, 10, 16);
77+
}
78+
return dechex($int);
79+
}
80+
81+
private function hexToDec($numstring)
82+
{
83+
$dec = hexdec($numstring);
84+
if ($this->isBigNum($dec)) {
85+
return $this->baseConvert($numstring, 16, 10);
86+
}
87+
return $dec;
88+
}
89+
90+
private function isBigNum($number)
91+
{
92+
return $number >= PHP_INT_MAX;
93+
}
94+
95+
private function baseConvert($numstring, $fromBase, $toBase)
96+
{
97+
$chars = "0123456789abcdefghijklmnopqrstuvwxyz";
98+
$newstring = substr($chars, 0, $toBase);
99+
100+
$length = strlen($numstring);
101+
$result = '';
102+
103+
for ($i = 0; $i < $length; $i++) {
104+
$number[$i] = strpos($chars, $numstring{$i});
105+
}
106+
107+
do {
108+
$divide = 0;
109+
$newlen = 0;
110+
for ($i = 0; $i < $length; $i++) {
111+
$divide = $divide * $fromBase + $number[$i];
112+
if ($divide >= $toBase) {
113+
$number[$newlen++] = (int)($divide / $toBase);
114+
$divide = $divide % $toBase;
115+
} elseif ($newlen > 0) {
116+
$number[$newlen++] = 0;
117+
}
118+
}
119+
$length = $newlen;
120+
$result = $newstring{$divide} . $result;
121+
} while ($newlen != 0);
122+
123+
return $result;
124+
}
71125
}

tests/unit/Trace/Propagator/CloudTraceFormatterTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public function traceHeaders()
7171
['123456789012345678901234567890ab', null, false, '123456789012345678901234567890ab;o=0'],
7272
['123456789012345678901234567890ab', null, true, '123456789012345678901234567890ab;o=1'],
7373
['123456789012345678901234567890ab', null, null, '123456789012345678901234567890ab'],
74+
['123456789012345678901234567890ab', 'adced0062fba0812', null, '123456789012345678901234567890ab/12524176338753030162'],
7475
];
7576
}
7677

@@ -83,6 +84,7 @@ public function upperTraceHeaders()
8384
['123456789012345678901234567890ab', null, false, '123456789012345678901234567890AB;o=0'],
8485
['123456789012345678901234567890ab', null, true, '123456789012345678901234567890AB;o=1'],
8586
['123456789012345678901234567890ab', null, null, '123456789012345678901234567890AB'],
87+
['123456789012345678901234567890ab', 'adced0062fba0812', null, '123456789012345678901234567890ab/12524176338753030162'],
8688
];
8789
}
8890
}

0 commit comments

Comments
 (0)