-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathwc.ts
158 lines (148 loc) · 4.13 KB
/
wc.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import fs from 'fs';
/**
* This function Reads the given stream and returns a Buffer.
*
* @async
* @param {NodeJS.ReadStream} stream
* @returns {Promise<Buffer>}
*/
async function readStream(
stream: NodeJS.ReadStream | fs.ReadStream
): Promise<Buffer> {
const chunks = [];
for await (const chunk of stream) {
chunks.push(Buffer.from(chunk));
}
return Buffer.concat(chunks);
}
/**
* This function returns the number of bytes consisting the given file.
*
* @param {string} filename
* @returns {number}
*/
function byteCount(filename: string): number {
return fs.statSync(filename).size;
}
/**
* This function returns the number of lines in a given text.
*
* @param {string} text
* @returns {number}
*/
function lineCount(text: string): number {
return text.split(/\r\n|\r|\n/).length - 1;
}
/**
* This function returns the number of words stored in a text.
*
* @param {string} text
* @returns {number}
*/
function wordCount(text: string): number {
if (text.length <= 0) {
return 0;
}
return text.trim().split(/\s+/).length;
}
/**
* This function returns the number of characters in a given text.
*
* @param {string} text
* @returns {number}
*/
function charCount(text: string): number {
return text.length;
}
/**
* This function is the unix wc command implementation
*
* @async
* @param {string[]} argv - The first two are reserved arguments considering the
* node call to the file
* @param {?NodeJS.ReadStream | fs.ReadStream } [stream] - This can be a file read stream or the
* stdin stream
* @returns {Promise<string>}
*/
async function myWC(
argv: string[],
stream?: NodeJS.ReadStream | fs.ReadStream
): Promise<string> {
// Option is given, file is given
if (argv.length === 4) {
// console.log('file + option');
const option = argv[2];
const filename = argv[3];
if (fs.existsSync(filename)) {
const fileContents = fs.readFileSync(filename, 'utf8').toString();
switch (option) {
case '-c':
return byteCount(filename).toString() + ' ' + filename;
case '-l':
return lineCount(fileContents).toString() + ' ' + filename;
case '-w':
return wordCount(fileContents).toString() + ' ' + filename;
case '-m':
return charCount(fileContents) + ' ' + filename;
default:
throw new Error('Invalid option');
}
}
if (typeof stream === 'undefined') {
throw new Error('Invalid file');
}
}
// Only filename is given
if (argv.length === 3) {
// console.log('only option');
const filename = argv[2];
if (fs.existsSync(filename)) {
const fileContents = fs.readFileSync(filename, 'utf8');
const line = lineCount(fileContents).toString();
const word = wordCount(fileContents).toString();
const bytes = byteCount(filename).toString();
return line + ' ' + word + ' ' + bytes + ' ' + filename;
}
if (typeof stream === 'undefined') {
throw new Error('Invalid file');
}
}
// Checking for stream
if (typeof stream !== 'undefined') {
// console.log('stream');
try {
// If option is given
const buffer = await readStream(stream);
const fileContents = buffer.toString();
if (argv.length === 3) {
const option = argv[2];
switch (option) {
case '-c':
return buffer.length.toString();
case '-l':
return lineCount(fileContents).toString();
case '-w':
return wordCount(fileContents).toString();
case '-m':
return charCount(fileContents).toString();
default:
throw new Error('Invalid option');
}
}
// If no option is given
if (argv.length == 2) {
const line = lineCount(fileContents).toString();
const word = wordCount(fileContents).toString();
const bytes = buffer.length.toString();
return line + ' ' + word + ' ' + bytes;
}
} catch (err) {
// If the error is not an expected TypeError
if (!(err instanceof TypeError)) {
throw err;
}
}
}
throw new Error('Invalid input or file');
}
export { myWC };