-
Notifications
You must be signed in to change notification settings - Fork 0
/
numlist.c
84 lines (75 loc) · 2.28 KB
/
numlist.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
tc_client, a simple non-flash client for tinychat(.com)
Copyright (C) 2014-2015, 2017 alicia@ion.nu
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, version 3 of the License.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <iconv.h>
#include "numlist.h"
// Functions for converting to/from the comma-separated decimal character code format that tinychat uses for chat messages, e.g. "97,98,99" = "abc"
#if(__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__)
#define ENDIAN "le"
#else
#define ENDIAN "be"
#endif
char* fromnumlist(char* in, size_t* outlen)
{
size_t len=1;
char* x=in;
while((x=strchr(x, ',')))
{
++len;
x=&x[1];
}
unsigned short string[len+1];
int i;
for(i=0; i<len; ++i)
{
string[i]=strtol(in, &in, 0);
if(!in){break;}
in=&in[1];
}
string[len]=0;
iconv_t cd=iconv_open("//IGNORE", "utf-16"ENDIAN);
char* outbuf=malloc(len*4);
char* i_out=outbuf;
char* i_in=(char*)string;
size_t remaining=len*4;
*outlen=remaining;
len*=2; // 2 bytes per number/character in utf-16
while(outlen>0 && len>0 && iconv(cd, &i_in, &len, &i_out, &remaining)>0);
i_out[0]=0; // null-terminates 'outbuf'
iconv_close(cd);
*outlen-=remaining;
return outbuf;
}
char* tonumlist(char* i_in, size_t len)
{
iconv_t cd=iconv_open("utf-16"ENDIAN, "");
unsigned short in[len+1];
char* i_out=(char*)in;
size_t outlen=len*2; // 2 bytes per character in utf-16
while(outlen>0 && len>0 && iconv(cd, &i_in, &len, &i_out, &outlen)>0);
iconv_close(cd);
len=((void*)i_out-(void*)in)/2;
char* out=malloc(len*strlen("65535,"));
out[0]=0;
char* x=out;
int i;
for(i=0; i<len; ++i)
{
sprintf(x, "%s%u", x==out?"":",", (unsigned int)in[i]&0xffff);
x=&x[strlen(x)];
}
return out;
}