michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // Utility that converts file encoded in one charset codepage to michael@0: // another encoding michael@0: michael@0: #include "nscore.h" michael@0: #include "nsString.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsICharsetConverterManager.h" michael@0: #include "nsIUnicodeEncoder.h" michael@0: #include "nsIUnicodeDecoder.h" michael@0: michael@0: static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: void usage() michael@0: { michael@0: printf( michael@0: "nsconv -f fromcode -t tocode infile outfile\n" michael@0: "nsconv -f fromcode -t tocode infile > outfile\n" michael@0: "nsconv -f fromcode -t tocode < infile > outfile\n" michael@0: ); michael@0: } michael@0: michael@0: #define INBUFSIZE (1024*16) michael@0: #define MEDBUFSIZE (1024*16*2) michael@0: #define OUTBUFSIZE (1024*16*8) michael@0: char inbuffer[INBUFSIZE]; michael@0: char outbuffer[OUTBUFSIZE]; michael@0: char16_t medbuffer[MEDBUFSIZE]; michael@0: michael@0: int main(int argc, const char** argv) michael@0: { michael@0: nsIUnicodeEncoder* encoder = nullptr; michael@0: nsIUnicodeDecoder* decoder = nullptr; michael@0: FILE* fin = 0; michael@0: FILE* fout = 0; michael@0: FILE* infile = 0; michael@0: FILE* outfile = 0; michael@0: nsresult res= NS_OK; michael@0: michael@0: NS_InitXPCOM2(nullptr, nullptr, nullptr); michael@0: michael@0: // get ccMain; michael@0: nsCOMPtr ccMain = michael@0: do_GetService(kCharsetConverterManagerCID, &res); michael@0: if(NS_FAILED(res)) michael@0: { michael@0: fprintf(stderr, "Cannot get Character Converter Manager %x\n", res); michael@0: return -1; michael@0: } michael@0: michael@0: int i; michael@0: if(argc > 4) michael@0: { michael@0: for(i =0; i < argc; i++) michael@0: { michael@0: if(strcmp(argv[i], "-f") == 0) michael@0: { michael@0: // User has specified the charset to convert from michael@0: nsAutoCString str; michael@0: michael@0: // First check if a charset alias was given, michael@0: // and convert to the canonical name michael@0: res = ccMain->GetCharsetAlias(argv[i+1], str); michael@0: if (NS_FAILED(res)) michael@0: { michael@0: fprintf(stderr, "Cannot get charset alias for %s %x\n", michael@0: argv[i+1], res); michael@0: goto error_exit; michael@0: } michael@0: michael@0: // Finally create the decoder michael@0: res = ccMain->GetUnicodeDecoder(str.get(), &decoder); michael@0: if(NS_FAILED(res)) { michael@0: fprintf(stderr, "Cannot get Unicode decoder %s %x\n", michael@0: argv[i+1],res); michael@0: goto error_exit; michael@0: } michael@0: michael@0: } michael@0: michael@0: if(strcmp(argv[i], "-t") == 0) michael@0: { michael@0: // User has specified which charset to convert to michael@0: nsAutoCString str; michael@0: michael@0: // First check if a charset alias was given, michael@0: // and convert to the canonical name michael@0: res = ccMain->GetCharsetAlias(argv[i+1], str); michael@0: if (NS_FAILED(res)) michael@0: { michael@0: fprintf(stderr, "Cannot get charset alias for %s %x\n", michael@0: argv[i+1], res); michael@0: goto error_exit; michael@0: } michael@0: michael@0: // Finally create the encoder michael@0: res = ccMain->GetUnicodeEncoderRaw(str.get(), &encoder); michael@0: if(NS_FAILED(res)) { michael@0: fprintf(stderr, "Cannot get Unicode encoder %s %x\n", michael@0: argv[i+1],res); michael@0: goto error_exit; michael@0: } michael@0: } michael@0: } michael@0: michael@0: if (argc > 5) michael@0: { michael@0: // The user has specified an input file michael@0: // if we have more than four arguments michael@0: fin = infile = fopen(argv[5], "rb"); michael@0: if(!infile) michael@0: { michael@0: usage(); michael@0: fprintf(stderr,"cannot open input file %s\n", argv[5]); michael@0: goto error_exit; michael@0: } michael@0: michael@0: if (argc > 6) michael@0: { michael@0: // The user has specified an output file michael@0: // if we have more than four arguments michael@0: fout = outfile = fopen(argv[6], "ab"); michael@0: if(!outfile) michael@0: { michael@0: usage(); michael@0: fprintf(stderr,"cannot open output file %s\n", argv[6]); michael@0: goto error_exit; michael@0: } michael@0: } michael@0: else michael@0: fout = stdout; michael@0: } michael@0: else michael@0: { michael@0: // No inputfiles are given. Read and write michael@0: // to/from standard in and standard out michael@0: fin = stdin; michael@0: fout = stdout; michael@0: } michael@0: michael@0: int32_t insize,medsize,outsize; michael@0: while((insize=fread(inbuffer, 1,INBUFSIZE, fin)) > 0) michael@0: { michael@0: medsize=MEDBUFSIZE; michael@0: michael@0: res = decoder->Convert(inbuffer,&insize, medbuffer, &medsize); michael@0: if(NS_FAILED(res)) { michael@0: fprintf(stderr, "failed in decoder->Convert %x\n",res); michael@0: goto error_exit; michael@0: } michael@0: outsize = OUTBUFSIZE; michael@0: res = encoder->Convert(medbuffer, &medsize, outbuffer,&outsize); michael@0: if(NS_FAILED(res)) { michael@0: fprintf(stderr, "failed in encoder->Convert %x\n",res); michael@0: goto error_exit; michael@0: } michael@0: fwrite(outbuffer, 1, outsize, fout); michael@0: michael@0: } michael@0: michael@0: // Clean up michael@0: if (infile != 0) michael@0: fclose(infile); michael@0: if (outfile != 0) michael@0: fclose(outfile); michael@0: fprintf(stderr, "Done!\n"); michael@0: NS_IF_RELEASE(encoder); michael@0: NS_IF_RELEASE(decoder); michael@0: return 0; michael@0: } michael@0: usage(); michael@0: error_exit: michael@0: // Clean up after michael@0: if (infile != 0) michael@0: fclose(infile); michael@0: if (outfile != 0) michael@0: fclose(outfile); michael@0: NS_IF_RELEASE(encoder); michael@0: NS_IF_RELEASE(decoder); michael@0: return -1; michael@0: }