I had a very difficult time figuring this thing out, due to the documentation on the UPS format being overly general.
So, here's the code, in all its glory (use as you wish, no credit required):
#include <cstddef>
#include <vector>
#define vector std::vector
typedef unsigned long long Hex64;
typedef unsigned char Hex08;
Hex64 decodeUPS(vector<Hex08>& data, size_t& current_address)
{
Hex64 ups = 0x0000000000000000LL;
Hex64 shift = 1;
while(true)
{
Hex08 x = (data[current_address++] & 0xFF);
ups += ((x & 0x7F) * shift);
if(x & 0x80) break;
shift <<= 7;
ups += shift;
}
return ups;
}
void encodeUPS(vector<Hex08>& data, Hex64 ups)
{
while(true)
{
Hex64 x = (ups & 0x000000000000007FLL);
ups >>= 7;
if(ups == 0)
{
data.push_back( (0x80 | x) & 0xFF );
break;
}
data.push_back( x & 0xFF );
ups--;
}
}
#include <vector>
#define vector std::vector
typedef unsigned long long Hex64;
typedef unsigned char Hex08;
Hex64 decodeUPS(vector<Hex08>& data, size_t& current_address)
{
Hex64 ups = 0x0000000000000000LL;
Hex64 shift = 1;
while(true)
{
Hex08 x = (data[current_address++] & 0xFF);
ups += ((x & 0x7F) * shift);
if(x & 0x80) break;
shift <<= 7;
ups += shift;
}
return ups;
}
void encodeUPS(vector<Hex08>& data, Hex64 ups)
{
while(true)
{
Hex64 x = (ups & 0x000000000000007FLL);
ups >>= 7;
if(ups == 0)
{
data.push_back( (0x80 | x) & 0xFF );
break;
}
data.push_back( x & 0xFF );
ups--;
}
}
If you have any questions about the code, feel free to ask.