2 進から 16 進への変換関数
以下のサンプル・プログラムでは、bintohex および hextobin という 2 つの UDF を定義しています。これらは、一般的な 2 進と 16 進のデータ変換を行います。
/*
Copyright (c) 2007-2009 Netezza Corporation, an IBM Company
All rights reserved.
Functions bintohex and hextobin allow packing and unpacking of binary
data into varchar fields.
This file must be placed in the /home/nz/osf/ directory.
create or replace function bintohex(varchar(16000)) returns
varchar(32000)
language cpp parameter style npsgeneric
EXTERNAL CLASS NAME 'CBinToHex'
EXTERNAL HOST OBJECT '/home/nz/osf/hexbin.o_x86'
EXTERNAL SPU OBJECT '/home/nz/osf/hexbin.o_spu10';
create or replace function hextobin(varchar(32000)) returns
varchar(16000)
language cpp parameter style npsgeneric
EXTERNAL CLASS NAME 'CHexToBin'
EXTERNAL HOST OBJECT '/home/nz/osf/hexbin.o_x86'
EXTERNAL SPU OBJECT '/home/nz/osf/hexbin.o_spu10';
(SIMPLE USAGE)
select bintohex(field) from a;
select bintohex('abcd') from a;
select hextobin(field) from b;
select hextobin('3A3B0F1141') from b;
(COMPLEX USAGE)
create table bintest (a varchar(100), b varchar(50));
insert into bintest values ('000102030405060708090A0B0C0D0E0F','');
update bintest set B = hextobin(A);
select bintohex(B) from bintest;
Note: select * from bintest will not properly display column B.
*/
#include "udxinc.h"
#include <string.h>
using namespace nz::udx;
class CHexToBin : public Udf
{
char convert(char inp)
{
if (inp >= '0' && inp <= '9')
return inp - '0';
if (inp >= 'a' && inp <= 'f')
return inp - 'a' + 10;
if (inp >= 'A' && inp <= 'F')
return inp - 'A' + 10;
throwUdxException("Bad Hex");
return 0;
}
public:
char *m_pBuf;
CHexToBin()
{
m_pBuf = new char[16000];
}
~CHexToBin()
{
delete m_pBuf;
}
static Udf* instantiate();
virtual ReturnValue evaluate()
{
StringReturn* ret = stringReturnInfo();
StringArg *input = stringArg(0);
int numbytes = input->length / 2;
if ((input->length%2) != 0)
throwUdxException("Bad Hex (Dangling)");
for (int i = 0; i < numbytes; i++)
{
char b1 = input->data[i*2];
char b2 = input->data[i*2+1];
m_pBuf[i] = convert(b1) * 16 + convert(b2);
}
ret->size = numbytes;
memcpy(ret->data, m_pBuf, numbytes);
NZ_UDX_RETURN_STRING(ret);
}
};
Udf* CHexToBin::instantiate()
{
return new CHexToBin;
}
class CBinToHex : public Udf
{
char unconvert(char inp)
{
if (inp <= 9)
return inp + '0';
return inp + 'A' - 10;
}
public:
char *m_pBuf;
CBinToHex()
{
m_pBuf = new char[32000];
}
~CBinToHex()
{
delete m_pBuf;
}
static Udf* instantiate();
virtual ReturnValue evaluate()
{
StringReturn* ret = stringReturnInfo();
StringArg *input = stringArg(0);
int numbytes = input->length * 2;
for (int i=0; i < input->length; i++)
{
m_pBuf[i*2] = unconvert(((unsigned char)(input->data[i]) &
0xF0) >> 4);
m_pBuf[i*2+1] = unconvert((unsigned char)(input->data[i]) &
0x0F);
}
ret->size = numbytes;
memcpy(ret->data, m_pBuf, numbytes);
NZ_UDX_RETURN_STRING(ret);
}
};
Udf* CBinToHex::instantiate()
{
return new CBinToHex;
}