780
787
* CONV_UNESCAPEHEX: ':XX' will be converted to an UCS2 character
781
788
* CONV_IGNORE: return the first convertable characters.
789
* CONV_FORCE: force convertion
783
791
* This will *not* work if the destination charset is not multibyte, i.e. UCS2->UCS2 will fail
784
792
* The (un)escape scheme is not compatible to the old cap style escape. This is bad, we need it
785
793
* for e.g. HFS cdroms.
788
static size_t pull_charset_flags (charset_t from_set, charset_t cap_charset, char* src, size_t srclen, char* dest, size_t destlen, u_int16_t *flags)
796
static size_t pull_charset_flags (charset_t from_set, charset_t cap_set, char* src, size_t srclen, char* dest, size_t destlen, u_int16_t *flags)
790
size_t i_len, o_len, hlen;
791
size_t retval, j = 0;
792
const char* inbuf = (const char*)src;
793
char* outbuf = (char*)dest;
794
atalk_iconv_t descriptor;
795
atalk_iconv_t descriptor_cap;
800
if (srclen == (size_t)-1)
801
srclen = strlen(src)+1;
803
lazy_initialize_conv();
805
descriptor = conv_handles[from_set][CH_UCS2];
806
descriptor_cap = conv_handles[cap_charset][CH_UCS2];
808
if (descriptor == (atalk_iconv_t)-1 || descriptor == (atalk_iconv_t)0) {
816
if ( flags && (*flags & CONV_UNESCAPEHEX)) {
817
if ( NULL != (s = strchr ( inbuf, ':'))) {
818
j = i_len - (s - inbuf);
819
if ( 0 == (i_len = (s - inbuf)))
824
retval = atalk_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len);
825
if(retval==(size_t)-1) {
826
if (errno == EILSEQ && flags && (*flags & CONV_IGNORE)) {
827
*flags |= CONV_REQMANGLE;
828
return destlen-o_len;
835
if (j && flags && (*flags & CONV_UNESCAPEHEX )) {
836
/* we're at the start on an hex encoded ucs2 char */
842
isxdigit( *(inbuf+1)) && isxdigit( *(inbuf+2)) ) {
844
while ( *inbuf == ':' && j >=3 &&
845
isxdigit( *(inbuf+1)) && isxdigit( *(inbuf+2)) ) {
847
h[hlen] = hextoint( *inbuf ) << 4;
849
h[hlen++] |= hextoint( *inbuf );
853
h_buf = (const char*) h;
854
if ((size_t) -1 == (retval = atalk_iconv(descriptor_cap, &h_buf, &hlen, &outbuf, &o_len)) ) {
855
if (errno == EILSEQ && CHECK_FLAGS(flags, CONV_IGNORE)) {
856
*flags |= CONV_REQMANGLE;
857
return destlen-o_len;
865
/* We have an invalid :xx sequence */
866
if (CHECK_FLAGS(flags, CONV_IGNORE)) {
867
*flags |= CONV_REQMANGLE;
868
return destlen-o_len;
878
goto conversion_loop;
883
return destlen-o_len;
798
const u_int16_t option = (flags ? *flags : 0);
801
const char* inbuf = (const char*)src;
803
atalk_iconv_t descriptor;
804
atalk_iconv_t descriptor_cap;
806
if (srclen == (size_t)-1)
807
srclen = strlen(src) + 1;
809
lazy_initialize_conv();
811
descriptor = conv_handles[from_set][CH_UCS2];
812
descriptor_cap = conv_handles[cap_set][CH_UCS2];
814
if (descriptor == (atalk_iconv_t)-1 || descriptor == (atalk_iconv_t)0) {
823
if ((option & CONV_UNESCAPEHEX)) {
824
for (j = 0; j < i_len; ++j) {
825
if (inbuf[j] == ':') break;
832
atalk_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len) == (size_t)-1) {
833
if (errno == EILSEQ || errno == EINVAL) {
835
if ((option & CONV_IGNORE)) {
836
*flags |= CONV_REQMANGLE;
837
return destlen - o_len;
839
if ((option & CONV__EILSEQ)) {
844
*((ucs2_t *)outbuf) = (ucs2_t) IGNORE_CHAR; /**inbuf */
849
/* FIXME reset stat ? */
857
/* we're at the start on an hex encoded ucs2 char */
862
while (i_len >= 3 && inbuf[0] == ':' &&
863
isxdigit(inbuf[1]) && isxdigit(inbuf[2])) {
864
h[hlen++] = (hextoint(inbuf[1]) << 4) | hextoint(inbuf[2]);
869
const char *h_buf = h;
870
if (atalk_iconv(descriptor_cap, &h_buf, &hlen, &outbuf, &o_len) == (size_t)-1) {
873
if (errno == EILSEQ && (option & CONV_IGNORE)) {
874
*flags |= CONV_REQMANGLE;
875
return destlen - o_len;
880
/* We have an invalid :xx sequence */
882
if ((option & CONV_IGNORE)) {
883
*flags |= CONV_REQMANGLE;
884
return destlen - o_len;
891
return (i_len + j == 0 || (option & CONV_FORCE)) ? destlen - o_len : (size_t)-1;
900
910
static size_t push_charset_flags (charset_t to_set, charset_t cap_set, char* src, size_t srclen, char* dest, size_t destlen, u_int16_t *flags)
902
size_t i_len, o_len, i;
903
size_t retval, j = 0;
904
const char* inbuf = (const char*)src;
905
char* outbuf = (char*)dest;
906
atalk_iconv_t descriptor;
908
char *buf, *buf_save;
911
lazy_initialize_conv();
913
descriptor = conv_handles[CH_UCS2][to_set];
915
if (descriptor == (atalk_iconv_t)-1 || descriptor == (atalk_iconv_t)0) {
923
if ( SVAL(inbuf,0) == 0x002e && flags && (*flags & CONV_ESCAPEDOTS)) { /* 0x002e = . */
935
if (flags) *flags |= CONV_REQESCAPE;
939
if ( flags && (*flags & CONV_ESCAPEHEX)) {
940
for ( i = 0; i < i_len; i+=2) {
941
if ( SVAL((inbuf+i),0) == 0x002f) { /* 0x002f = / */
943
if ( 0 == ( i_len = i))
946
} else if ( SVAL(inbuf+i,0) == 0x003a) { /* 0x003a = : */
953
retval = atalk_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len);
954
if (retval==(size_t)-1) {
955
if (errno == EILSEQ && CHECK_FLAGS(flags, CONV_IGNORE)) {
956
*flags |= CONV_REQMANGLE;
957
return destlen -o_len;
959
else if ( errno == EILSEQ && flags && (*flags & CONV_ESCAPEHEX)) {
912
const u_int16_t option = (flags ? *flags : 0);
913
size_t i_len, o_len, i;
915
const char* inbuf = (const char*)src;
916
char* outbuf = (char*)dest;
917
atalk_iconv_t descriptor;
918
atalk_iconv_t descriptor_cap;
920
lazy_initialize_conv();
922
descriptor = conv_handles[CH_UCS2][to_set];
923
descriptor_cap = conv_handles[CH_UCS2][cap_set];
925
if (descriptor == (atalk_iconv_t)-1 || descriptor == (atalk_iconv_t)0) {
933
if ((option & CONV_ESCAPEDOTS) &&
934
i_len >= 2 && SVAL(inbuf, 0) == 0x002e) { /* 0x002e = . */
945
*flags |= CONV_REQESCAPE;
949
if ((option & CONV_ESCAPEHEX)) {
950
for (i = 0; i < i_len; i += 2) {
951
ucs2_t c = SVAL(inbuf, i);
952
if (c == 0x002f) { /* 0x002f = / */
956
} else if (c == 0x003a) { /* 0x003a = : */
963
atalk_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len) == (size_t)-1) {
964
if (errno == EILSEQ) {
965
if ((option & CONV_IGNORE)) {
966
*flags |= CONV_REQMANGLE;
967
return destlen - o_len;
969
if ((option & CONV_ESCAPEHEX)) {
970
const size_t bufsiz = o_len / 3 + 1;
971
char *buf = malloc(bufsiz);
977
for (buflen = 1; buflen <= bufsiz; ++buflen) {
980
if (atalk_iconv(descriptor_cap, &inbuf, &i, &b, &o) != (size_t)-1) {
983
} else if (errno != E2BIG) {
986
} else if (o < buflen) {
964
if ((size_t) -1 == (buflen = convert_string_allocate_internal(CH_UCS2, cap_set, inbuf, 2, &buf)) )
973
*outbuf++ = hexdig[ ( *buf & 0xf0 ) >> 4 ];
974
*outbuf++ = hexdig[ *buf & 0x0f ];
983
if (flags) *flags |= CONV_REQESCAPE;
985
goto conversion_loop;
991
if (o_len < buflen * 3) {
998
for (i = 0; i < buflen; ++i) {
1000
*outbuf++ = hexdig[(buf[i] >> 4) & 0x0f];
1001
*outbuf++ = hexdig[buf[i] & 0x0f];
1004
*flags |= CONV_REQESCAPE;
992
if (j && flags && (*flags & CONV_ESCAPEHEX)) {
997
o_save[destlen -o_len] = ':';
998
o_save[destlen -o_len+1] = '2';
999
o_save[destlen -o_len+2] = 'f';
1006
goto conversion_loop;
1008
return destlen -o_len;
1025
if (i_len > 0) errno = EINVAL;
1027
return (i_len + j == 0 || (option & CONV_FORCE)) ? destlen - o_len : (size_t)-1;