/* inet_pton.c -- convert IPv4 and IPv6 addresses from text to binary form
Copyright (C) 2006 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/*
* Copyright (c) 1996,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
//port by snoj for speed test for nodejs
//http://www.koders.com/c/fid74A647B73741DDD374D5478366A00584E8740D43.aspx
function inet_pton6 (src)
{
//static const char xdigits[] = "0123456789abcdef";
//unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
//const char *curtok;
//int ch, saw_xdigit;
//unsigned val;
var xdigits, tmp, tp, endp, colonp, curtok, ch, saw_xdigit, val;
xdigits = "0123456789abcdef";
tmp = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
//tp = memset (tmp, '\0', NS_IN6ADDRSZ);
//endp = tp + NS_IN6ADDRSZ; end pointer (basically the length);
colonp = null;
endp = 16;
tp = 0;
/* Leading :: requires sme special handling. */
if (src[0] == ':' && src[1] != ':') {
//console.log("address starts with one :");
return 0;
}
//if (*src != ':')
//return (0);
//curtok = src;
saw_xdigit = 0;
val = 0;
//while ((ch = tolower (*src++)) != '\0')
src = src.toLowerCase();
for(var i = 0; i<src.length; i++)
{
ch = parseInt(src[i],16) //src.charCodeAt(i)
//const char *pch;
var pch;
//pch = strchr (xdigits, ch);
//pch = xdigits.indexOf(String.fromCharCode(ch));
pch = xdigits.indexOf(src[i]);
if (pch != -1)
{
val <<= 4;
//val |= (pch - xdigits);
val |= (ch);
if (val > 0xffff) {
//console.log("val > %s", 0xffff);
return (0);
}
saw_xdigit = 1;
continue;
}
if (src[i] == ':')
{
curtok = i;
if (!saw_xdigit)
{
if (colonp) {
//console.log("colonp not null?");
return (0);
}
colonp = tp;
continue;
}
else if (src[i] == '\0') //probably can delete this?
{
//console.log("wtf?")
return (0);
}
//if (tp + NS_INT16SZ > endp)
if ((tp + 2) > 16) {
//console.log("tp + 2 > 16");
return (0);
}
//*tp++ = (u_char) (val >> 8) & 0xff;
//*tp++ = (u_char) val & 0xff;
//tmp[tp++] = String.fromCharCode((val >> 8) &0xff)
//tmp[tp++] = String.fromCharCode((val) &0xff)
//console.log("tp = %s", tp);
//console.log(((val >> 8) & 0xff).toString(16));
//console.log(((val) &0xff).toString(16));
tmp[tp++] = ((val >> 8) & 0xff)//.toString(16) //.replace(/(0.)([a-f].)/i, '$2');
tmp[tp++] = ((val) & 0xff)//.toString(16) //.replace(/(0.)([a-f].)/i, '$2');
//tmp[tp++] = (val >> 8)
saw_xdigit = 0;
val = 0;
continue;
}
/*if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
inet_pton4 (curtok, tp) > 0)
{
tp += NS_INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). * /
}*/
//console.log("end of for loop");
return (0);
}
if (saw_xdigit)
{
//if (tp + NS_INT16SZ > endp)
if ((tp + 2) > 16) {
//console.log("tp + 2 > 16");
return (0);
}
//*tp++ = (u_char) (val >> 8) & 0xff;
//*tp++ = (u_char) val & 0xff;
//console.log(val);
//tmp[tp++] = String.fromCharCode((val >> 8) &0xff)
//tmp[tp++] = String.fromCharCode((val) &0xff)
tmp[tp++] = ((val >> 8) &0xff)//.toString(16) //.replace(/(0.)([a-f].)/i, '$2');
tmp[tp++] = ((val) &0xff)//.toString(16) //.replace(/(0.)([a-f].)/i, '$2');
}
//console.log(tmp);
if (colonp != null)
{
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
//const int n = tp - colonp;
//int i;
n = tp - colonp;
if (tp == endp) {
//console.log("tp == endp");
return (0);
}
//console.log("tp = %s, n = %s", tp , n);
for (var i = 0; i <= n; i++)
{
//endp[-i] = colonp[n - i];
//colonp[n - i] = 0;
//console.log("tmp[16-i] = %s, n = %s, colonp = %s, tmp[n+i] = %s", tmp[15-i], n, colonp, tmp[n+i]);
tmp[15-i] = tmp[n+i];
tmp[n+i] = 0;
}
tp = endp;
}
if (tp != endp) {
//console.log("now tp != endp");
return (0);
}
//memcpy (dst, tmp, NS_IN6ADDRSZ);
//return (1);
//console.log("eol");
return tmp.slice(0,15);
}
console.log(inet_pton6("::"));
console.log(inet_pton6("::a"));
console.log(inet_pton6("a::"));
console.log(inet_pton6("ffaa:FFFF::1a:a"));
console.log(inet_pton6("0000:0000:0000:0000:0000:0000:0000:0000::0000"));
console.time("inet_pton");
for(var i = 0; i< 10000; i++) {
inet_pton6("0000:0000:0000:0000:0000:0000:0000:0000::0000");
}
console.timeEnd("inet_pton");