15
15
-- of the license. --
16
16
-- ----------------------------------------------------------------------------
17
17
18
+ with Ada.Exceptions ; use Ada.Exceptions;
19
+ with Ada.Characters.Handling ;
18
20
with GNAT.Strings ; use GNAT.Strings;
19
21
with GNATCOLL.Traces ; use GNATCOLL.Traces;
22
+
23
+ with GNATCOLL.VFS ; use GNATCOLL.VFS;
24
+ with GNATCOLL.Iconv ; use GNATCOLL.Iconv;
20
25
with VSS.Strings ; use VSS.Strings;
21
26
with VSS.Strings.Conversions ;
22
27
with LSP.Ada_Documents ; use LSP.Ada_Documents;
@@ -27,6 +32,104 @@ package body LSP.Ada_Handlers.File_Readers is
27
32
28
33
Me : constant Trace_Handle := Create (" ALS.FILE_READERS" );
29
34
35
+ function Read_And_Convert_To_UTF8
36
+ (Filename : String; Charset : String)
37
+ return GNAT.Strings.String_Access;
38
+ -- Read the file content from Filename and convert it from the original
39
+ -- Charset to UTF-8.
40
+
41
+ -- ----------------------------
42
+ -- Read_And_Convert_To_UTF8 --
43
+ -- ----------------------------
44
+
45
+ function Read_And_Convert_To_UTF8
46
+ (Filename : String; Charset : String)
47
+ return GNAT.Strings.String_Access
48
+ is
49
+ Raw : GNAT.Strings.String_Access;
50
+ Decoded : GNAT.Strings.String_Access;
51
+ begin
52
+ -- Read the file (this call uses MMAP)
53
+ Raw := Create_From_UTF8 (Filename).Read_File;
54
+
55
+ if Raw = null then
56
+ return null ;
57
+ end if ;
58
+
59
+ -- Convert the file if it's not already encoded in utf-8
60
+
61
+ if Ada.Characters.Handling.To_Lower (Charset) = " utf-8" then
62
+ Decoded := Raw;
63
+ else
64
+ declare
65
+ State : constant Iconv_T := Iconv_Open (UTF8, Charset);
66
+ Outbuf : Byte_Sequence (1 .. 4096 );
67
+ Input_Index : Positive := Raw'First;
68
+ Conv_Result : Iconv_Result := Full_Buffer;
69
+ Output_Index : Positive;
70
+ begin
71
+ while Conv_Result = Full_Buffer loop
72
+ Output_Index := 1 ;
73
+ Iconv (State => State,
74
+ Inbuf => Raw.all ,
75
+ Input_Index => Input_Index,
76
+ Outbuf => Outbuf,
77
+ Output_Index => Output_Index,
78
+ Result => Conv_Result);
79
+
80
+ -- Append the converted contents
81
+ if Decoded /= null then
82
+ declare
83
+ Tmp : GNAT.Strings.String_Access := Decoded;
84
+ begin
85
+ Decoded := new String'
86
+ (Tmp.all & Outbuf (1 .. Output_Index - 1 ));
87
+ GNAT.Strings.Free (Tmp);
88
+ end ;
89
+ else
90
+ Decoded := new String'(Outbuf (1 .. Output_Index - 1 ));
91
+ end if ;
92
+ end loop ;
93
+
94
+ GNAT.Strings.Free (Raw);
95
+ Iconv_Close (State);
96
+
97
+ case Conv_Result is
98
+ when Success =>
99
+ -- The conversion was successful
100
+ null ;
101
+ when others =>
102
+ Me.Trace
103
+ (" Failed to convert '" & Filename & " ' to UTF-8: "
104
+ & Conv_Result'Img);
105
+ return null ;
106
+ end case ;
107
+ exception
108
+ when E : others =>
109
+
110
+ Me.Trace
111
+ (" Exception caught when reading '" & Filename & " ':"
112
+ & Exception_Message (E));
113
+ return null ;
114
+ end ;
115
+ end if ;
116
+
117
+ -- Convert the string to a Virtual_String for easier handling
118
+
119
+ return Decoded;
120
+ exception
121
+ when E : others =>
122
+ if Decoded /= null then
123
+ GNAT.Strings.Free (Decoded);
124
+ end if ;
125
+
126
+ Me.Trace
127
+ (" Exception caught when reading '" & Filename & " ':"
128
+ & Exception_Message (E));
129
+
130
+ return null ;
131
+ end Read_And_Convert_To_UTF8 ;
132
+
30
133
-- --------
31
134
-- Read --
32
135
-- --------
@@ -56,7 +159,7 @@ package body LSP.Ada_Handlers.File_Readers is
56
159
Buffer := new String'
57
160
(VSS.Strings.Conversions.To_UTF_8_String (Doc.Text));
58
161
else
59
- Buffer := Create_From_UTF8 (Filename).Read_File ;
162
+ Buffer := Read_And_Convert_To_UTF8 (Filename, Charset) ;
60
163
61
164
-- Return an empty sring when failing to read the file (i.e: when the
62
165
-- file has been deleted).
0 commit comments