diff --git a/HISTORY b/HISTORY index fbc3bc8..8b0a6db 100644 --- a/HISTORY +++ b/HISTORY @@ -1,5 +1,5 @@ -Version 1.44 2020-03-30 +Version 1.44 2020-03-31 * add test file src/tests/test_pthread_lock.c * add uniq_skiplist.[hc] * add function split_string_ex @@ -24,6 +24,7 @@ Version 1.44 2020-03-30 * add function common_blocked_queue_return_nodes * add functions getIpAndPort and getPeerIpAndPort * bugfixed: call fast_mblock_destroy in common_blocked_queue_destroy + * add function fc_get_file_line_count_ex Version 1.43 2019-12-25 * replace function call system to getExecResult, diff --git a/src/shared_func.c b/src/shared_func.c index 0bc36f1..5a011f3 100644 --- a/src/shared_func.c +++ b/src/shared_func.c @@ -693,6 +693,64 @@ int getOccurCount(const char *src, const char seperator) return count; } +int fc_get_file_line_count_ex(const char *filename, + const int64_t until_offset, int64_t *line_count) +{ +#define READ_BUFFER_SIZE (256 * 1024) + int fd; + int result; + int read_bytes; + int64_t remain_bytes; + char *buff; + + *line_count = 0; + buff = (char *)malloc(READ_BUFFER_SIZE); + if (buff == NULL) { + logError("file: "__FILE__", line: %d, " + "malloc %d bytes fail", + __LINE__, READ_BUFFER_SIZE); + return ENOMEM; + } + + fd = open(filename, O_RDONLY); + if (fd < 0) { + result = errno != 0 ? errno : EACCES; + logError("file: "__FILE__", line: %d, " + "open file \"%s\" fail, errno: %d, error info: %s", + __LINE__, filename, result, STRERROR(result)); + free(buff); + return result; + } + + if (until_offset >= 0) { + remain_bytes = until_offset; + } else { + remain_bytes = lseek(fd, 0, SEEK_END); + } + while (remain_bytes > 0) { + read_bytes = remain_bytes >= READ_BUFFER_SIZE ? + (READ_BUFFER_SIZE - 1) : remain_bytes; + read_bytes = read(fd, buff, read_bytes); + if (read_bytes == 0) { + break; + } else if (read_bytes < 0) { + result = errno != 0 ? errno : EIO; + logError("file: "__FILE__", line: %d, " + "read file \"%s\" fail, errno: %d, error info: %s", + __LINE__, filename, result, STRERROR(result)); + return result; + } + + *(buff + read_bytes) = '\0'; + *line_count += getOccurCount(buff, '\n'); + remain_bytes -= read_bytes; + } + + close(fd); + free(buff); + return 0; +} + char **split(char *src, const char seperator, const int nMaxCols, int *nColCount) { char **pCols; diff --git a/src/shared_func.h b/src/shared_func.h index 7342499..06a823c 100644 --- a/src/shared_func.h +++ b/src/shared_func.h @@ -362,6 +362,24 @@ char *urldecode_ex(const char *src, const int src_len, char *dest, int *dest_len */ int getOccurCount(const char *src, const char seperator); + +/** get the file line count + * parameters: + * filename: the filename + * until_offset: util the file offset, -1 for file end + * line_count: store the line count + * return: error no, 0 success, != 0 fail +*/ +int fc_get_file_line_count_ex(const char *filename, + const int64_t until_offset, int64_t *line_count); + +static inline int fc_get_file_line_count(const char *filename, + int64_t *line_count) +{ + const int64_t until_offset = -1; + return fc_get_file_line_count_ex(filename, until_offset, line_count); +} + /** split string * parameters: * src: the source string, will be modified by this function