1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010 - DIGITEO - Allan CORNET
4 * Copyright (C) 2010 - DIGITEO - Antoine ELIAS
5 * Copyright (C) 2019 - ESI - Antoine ELIAS
6 *
7 * Copyright (C) 2012 - 2016 - Scilab Enterprises
8 *
9 * This file is hereby licensed under the terms of the GNU GPL v2.0,
10 * pursuant to article 5.3.4 of the CeCILL v.2.1.
11 * This file was originally licensed under the terms of the CeCILL v2.1,
12 * and continues to be available under such terms.
13 * For more information, see the COPYING file which you should have received
14 * along with this program.
15 *
16 */
17
18 #include <fstream>
19 #include <iostream>
20
21 extern "C"
22 {
23 #include "charEncoding.h"
24 #include "freeArrayOfString.h"
25 #include "mgetl.h"
26 #include "sci_malloc.h"
27 #include "sciprint.h"
28 }
29 #include "filemanager.hxx"
30
31 #include <stdio.h>
32 #include <string.h>
33
34 #ifdef _MSC_VER
35 #include <Windows.h>
36 #endif
37
38 static const unsigned char UTF8_BOM[] = {0xEF, 0xBB, 0xBF, 0x00};
39
40 //remove \r
rtrim(wchar_t * s)41 inline void rtrim(wchar_t* s)
42 {
43 size_t n = wcslen(s);
44 if (n && s[n - 1] == L'\r')
45 {
46 s[n - 1] = 0;
47 }
48 }
49
mgetl(int iFileID,int iLineCount,wchar_t *** pwstLines)50 int mgetl(int iFileID, int iLineCount, wchar_t*** pwstLines)
51 {
52 *pwstLines = NULL;
53
54 // get file descriptor
55 types::File* pFile = FileManager::getFile(iFileID);
56 FILE* fd;
57 if (pFile != NULL)
58 {
59 fd = pFile->getFiledesc();
60 }
61 else
62 {
63 return -1;
64 }
65
66 if (iLineCount == 0)
67 {
68 return 0;
69 }
70
71 // check file is not empty
72 if (ftell(fd) == 0)
73 {
74 char cValues[4] = {0x00, 0x00, 0x00, 0x00};
75 if (fgets(cValues, 4 * sizeof(char), fd) != NULL)
76 {
77 // skip BOM
78 if (strcmp(cValues, (const char*)UTF8_BOM) != 0)
79 {
80 rewind(fd);
81 }
82 }
83 }
84
85 int orig = ftell(fd);
86
87 std::string str;
88 std::vector<std::string> lst;
89
90 if (iFileID == 5)
91 {
92 // read from stdin
93 while ((iLineCount == -1 || lst.size() < iLineCount) && std::getline(std::cin, str))
94 {
95 lst.push_back(str);
96 }
97 }
98 else
99 {
100 #ifndef _MSC_VER
101 //must reopen the file
102 std::wstring wname = pFile->getFilename();
103 char* name = wide_string_to_UTF8(wname.data());
104 std::ifstream ifs(name);
105 FREE(name);
106 //seek to same position
107 ifs.seekg(orig);
108 #else
109 std::ifstream ifs(fd);
110 #endif
111 while ((iLineCount == -1 || lst.size() < iLineCount) && std::getline(ifs, str))
112 {
113 lst.push_back(str);
114 }
115 #ifndef _MSC_VER
116 auto pos = ifs.tellg();
117 if (pos == -1)
118 {
119 fseek(fd, 0, SEEK_END);
120 }
121 else
122 {
123 fseek(fd, pos, SEEK_SET);
124 }
125
126 ifs.close();
127 #endif
128 }
129
130 int nbLinesOut = (int)lst.size();
131 if (nbLinesOut == 0)
132 {
133 return 0;
134 }
135
136 *pwstLines = (wchar_t**)MALLOC(nbLinesOut * sizeof(wchar_t*));
137 if (*pwstLines == NULL)
138 {
139 return -1;
140 }
141
142 for (int i = 0; i < nbLinesOut; ++i)
143 {
144 wchar_t* str = to_wide_string(lst[i].data());
145 rtrim(str);
146 (*pwstLines)[i] = str;
147 }
148
149 return nbLinesOut;
150 }
151