1 /*******************************************************************************
2 ********************************************************************************
4 Copyright (c) 2008 Ahmed S. Badran
6 Licensed under the FreeBSD License (see LICENSE)
8 Filename: tree_builder.cc
9 Description: Implementation
10 Created: 08/23/2008 09:24:28 PM PDT
11 Author: Ahmed S. Badran (Ahmed B.), ahmed.badran@gmail.com
13 ********************************************************************************
14 *******************************************************************************/
16 #include <sys/types.h>
20 #include "tree_builder.h"
21 #include "fs_item_dir.h"
22 #include "fs_item_file.h"
25 tree_builder
* tree_builder::instance
= 0;
27 tree_builder::tree_builder ()
32 tree_builder::get_instance ()
35 instance
= new tree_builder
;
40 tree_builder::build (const string
& path
, const vector
<string
>& patterns
,
41 vector
<string
>* file_list
) const
43 fs_item_dir
* dir
= new fs_item_dir(path
);
44 build_dir_tree(path
, dir
, patterns
, file_list
);
49 tree_builder::build_dir_tree (const string
& path
, fs_item
* dir
, const
50 vector
<string
>& patterns
, vector
<string
>*
54 if ((dir_handle
= opendir(path
.c_str())) == 0) {
58 long path_max
= pathconf(path
.c_str(), _PC_NAME_MAX
);
59 char* buf
= new char[sizeof(struct dirent
) + path_max
+ 1];
60 memset(buf
, 0, sizeof(struct dirent
) + path_max
+ 1);
61 struct dirent
* entry
= 0;
64 while ((readdir_r(dir_handle
, reinterpret_cast<struct dirent
*>(buf
),
65 &entry
) == 0) && entry
) {
66 tmp
= path
+ "/" + entry
->d_name
;
67 memset(&stat_buf
, 0, sizeof(stat_buf
));
68 if (stat(tmp
.c_str(), &stat_buf
) == -1) {
72 if (S_ISDIR(stat_buf
.st_mode
) &&
73 (strcmp(entry
->d_name
, ".") != 0) &&
74 (strcmp(entry
->d_name
, "..") != 0)) {
75 fs_item_dir
* item
= new fs_item_dir(entry
->d_name
);
76 build_dir_tree(tmp
, item
, patterns
, file_list
);
78 } else if (matches(entry
->d_name
, patterns
)){
79 file_list
->push_back(tmp
);
80 fs_item_file
* item
= new fs_item_file(entry
->d_name
);
89 tree_builder::matches (const char* entry
, const vector
<string
>& patterns
)
92 const unsigned entry_len
= strlen(entry
);
93 unsigned pattern_len
= 0;
94 vector
<string
>::const_iterator pos
;
95 vector
<string
>::const_iterator end
= patterns
.end();
96 for (pos
= patterns
.begin(); pos
!= end
; ++pos
) {
97 pattern_len
= (*pos
).length();
98 if (pattern_len
> entry_len
) {
101 if (strcmp(&entry
[entry_len
- pattern_len
], (*pos
).c_str()) ==
109 tree_builder::~tree_builder ()