1 /*
2  ******************************************************************************
3  * Copyright (C) 1998-2005, International Business Machines Corporation and   *
4  * others. All Rights Reserved.                                               *
5  ******************************************************************************
6  */
7 
8 #include <errno.h>
9 #include <stdio.h>
10 #include <string.h>
11 
12 #include "unicode/utypes.h"
13 #include "unicode/unistr.h"
14 
15 #include "layout/LETypes.h"
16 
17 #include "GUISupport.h"
18 #include "UnicodeReader.h"
19 
20 #define BYTE(b) (((int) b) & 0xFF)
21 
22 /*
23  * Read the text from a file. The text must start with a Unicode Byte
24  * Order Mark (BOM) so that we know what order to read the bytes in.
25  */
readFile(const char * fileName,GUISupport * guiSupport,int32_t & charCount)26 const UChar *UnicodeReader::readFile(const char *fileName, GUISupport *guiSupport, int32_t &charCount)
27 {
28     FILE *f;
29     int32_t fileSize;
30 
31     UChar *charBuffer;
32     char *byteBuffer;
33     char startBytes[4] = {'\xA5', '\xA5', '\xA5', '\xA5'};
34     char errorMessage[128];
35     const char *cp = "";
36     int32_t signatureLength = 0;
37 
38     f = fopen(fileName, "rb");
39 
40     if( f == NULL ) {
41         sprintf(errorMessage,"Couldn't open %s: %s \n", fileName, strerror(errno));
42         guiSupport->postErrorMessage(errorMessage, "Text File Error");
43         return 0;
44     }
45 
46     fseek(f, 0, SEEK_END);
47     fileSize = ftell(f);
48 
49     fseek(f, 0, SEEK_SET);
50     fread(startBytes, sizeof(char), 4, f);
51 
52     if (startBytes[0] == '\xFE' && startBytes[1] == '\xFF') {
53         cp = "UTF-16BE";
54         signatureLength = 2;
55     } else if (startBytes[0] == '\xFF' && startBytes[1] == '\xFE') {
56         if (startBytes[2] == '\x00' && startBytes[3] == '\x00') {
57             cp = "UTF-32LE";
58             signatureLength = 4;
59         } else {
60             cp = "UTF-16LE";
61             signatureLength = 2;
62         }
63     } else if (startBytes[0] == '\xEF' && startBytes[1] == '\xBB' && startBytes[2] == '\xBF') {
64         cp = "UTF-8";
65         signatureLength = 3;
66     } else if (startBytes[0] == '\x0E' && startBytes[1] == '\xFE' && startBytes[2] == '\xFF') {
67         cp = "SCSU";
68         signatureLength = 3;
69     } else if (startBytes[0] == '\x00' && startBytes[1] == '\x00' &&
70         startBytes[2] == '\xFE' && startBytes[3] == '\xFF') {
71         cp = "UTF-32BE";
72         signatureLength = 4;
73     } else {
74         sprintf(errorMessage, "Couldn't detect the encoding of %s: (%2.2X, %2.2X, %2.2X, %2.2X)\n", fileName,
75                     BYTE(startBytes[0]), BYTE(startBytes[1]), BYTE(startBytes[2]), BYTE(startBytes[3]));
76         guiSupport->postErrorMessage(errorMessage, "Text File Error");
77         fclose(f);
78         return 0;
79     }
80 
81     fileSize -= signatureLength;
82     fseek(f, signatureLength, SEEK_SET);
83     byteBuffer = new char[fileSize];
84 
85     if(byteBuffer == 0) {
86         sprintf(errorMessage,"Couldn't get memory for reading %s: %s \n", fileName, strerror(errno));
87         guiSupport->postErrorMessage(errorMessage, "Text File Error");
88         fclose(f);
89         return 0;
90     }
91 
92     fread(byteBuffer, sizeof(char), fileSize, f);
93     if( ferror(f) ) {
94         sprintf(errorMessage,"Couldn't read %s: %s \n", fileName, strerror(errno));
95         guiSupport->postErrorMessage(errorMessage, "Text File Error");
96         fclose(f);
97         delete[] byteBuffer;
98         return 0;
99     }
100     fclose(f);
101 
102     UnicodeString myText(byteBuffer, fileSize, cp);
103 
104     delete[] byteBuffer;
105 
106     charCount = myText.length();
107     charBuffer = LE_NEW_ARRAY(UChar, charCount + 1);
108     if(charBuffer == 0) {
109         sprintf(errorMessage,"Couldn't get memory for reading %s: %s \n", fileName, strerror(errno));
110         guiSupport->postErrorMessage(errorMessage, "Text File Error");
111         return 0;
112     }
113 
114     myText.extract(0, myText.length(), charBuffer);
115     charBuffer[charCount] = 0;    // NULL terminate for easier reading in the debugger
116 
117     return charBuffer;
118 }
119 
120