Newer
Older
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include "Transcoder.hpp"
XERCES_CPP_NAMESPACE_USE
static bool DEBUG_IN = false;
static bool DEBUG_OUT = false;
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
Transcoder* Transcoder::_instance = NULL;
Transcoder*
Transcoder::getInstance() {
// fprintf(stderr, "getInstance: finding instance\n");
if (_instance == NULL) {
// fprintf(stderr, "getInstance: making new transcoder\n");
_instance = new Transcoder();
}
return _instance;
}
Transcoder::~Transcoder() {
// fprintf(stderr, "Deleting transcoder\n");
}
Transcoder::Transcoder() {
XMLTransService::Codes failReason;
// we assume that the Xerces-C transcoding service is already initialized
// via XMLPlatformUtils::Initialize()
UTF8_TRANSCODER = XMLPlatformUtils::fgTransService->makeNewTranscoderFor(
XMLUni::fgUTF8EncodingString,
failReason,
1024);
if (UTF8_TRANSCODER == NULL) {
croak("ERROR: Transcoder Could not create UTF-8 transcoder");
} else if (failReason == XMLTransService::UnsupportedEncoding) {
croak("ERROR: Transcoder: unsupported encoding");
} else if (failReason == XMLTransService::InternalFailure) {
croak("ERROR: Transcoder: internal failure");
} else if (failReason == XMLTransService::SupportFilesNotFound) {
croak("ERROR: Transcoder: support files not found");
} else if (failReason == XMLTransService::Ok) {
// fprintf(stderr, "Created transcoder ok\n");
}
}
SV*
Transcoder::XMLString2Local(const XMLCh* input) {
if (input == NULL) {
return &PL_sv_undef;
}
XMLSize_t charsEaten = 0;
int length = XMLString::stringLen(input); // string length
// use +1 to make room for the '\0' at the end of the string
// in the pathological case when each character of the string
// is UTF8_MAXLEN bytes long
XMLByte* res = new XMLByte[(length * UTF8_MAXLEN) + 1]; // output string
XMLSize_t total_chars =
UTF8_TRANSCODER->transcodeTo((const XMLCh*) input,
(XMLSize_t) length,
(XMLByte*) res,
(XMLSize_t) (length*UTF8_MAXLEN),
charsEaten,
XMLTranscoder::UnRep_Throw
);
res[total_chars] = '\0';
#if (0)
printf("Xerces out length = %d: ",total_chars);
for (int i=0;i<length;i++){
printf("<0x%.4X>",res[i]);
}
printf("\n");
}
#endif
output = sv_newmortal();
sv_setpv((SV*)output, (char *)res );
SvUTF8_on((SV*)output);
delete[] res;
return output;
}
XMLCh*
Transcoder::Local2XMLString(SV* input){
if (input == &PL_sv_undef) {
return NULL;
}
XMLCh* output;
STRLEN length;
char *ptr = (char *)SvPVutf8(input,length);
#if (0)
printf("Perl in length = %d: ",length);
for (unsigned int i=0;i<length;i++){
printf("<0x%.4X>",ptr[i]);
}
printf("\n");
}
#endif
if (SvUTF8(input)) {
XMLSize_t charsEaten = 0;
unsigned char* sizes = new unsigned char[length+1];
output = new XMLCh[length+1];
XMLSize_t chars_stored =
UTF8_TRANSCODER->transcodeFrom((const XMLByte*) ptr,
(XMLSize_t) length,
(XMLCh*) output,
(XMLSize_t) length,
charsEaten,
(unsigned char*)sizes
);
delete [] sizes;
#if (0)
printf("Xerces in length = %d: ",chars_stored);
for (unsigned int i=0;i<chars_stored;i++){
printf("<0x%.4X>",output[i]);
}
printf("\n");
}
#endif
// indicate the end of the string
output[chars_stored] = '\0';
} else {
output = XMLString::transcode(ptr);
#if (0)
printf("Xerces: ");
for (int i=0;output[i];i++){
printf("<0x%.4X>",output[i]);
}
printf("\n");
}
#endif
}
return(output);
}