dhun 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +83 -0
- data/TODO.md +19 -0
- data/bin/dhun +7 -0
- data/ext/Makefile +157 -0
- data/ext/dhun.h +37 -0
- data/ext/dhun_ext.c +84 -0
- data/ext/extconf.rb +15 -0
- data/ext/player.c +187 -0
- data/ext/query.c +102 -0
- data/lib/dhun.rb +13 -0
- data/lib/dhun/command.rb +15 -0
- data/lib/dhun/controller.rb +116 -0
- data/lib/dhun/dhun_client.rb +30 -0
- data/lib/dhun/dhun_server.rb +43 -0
- data/lib/dhun/handler.rb +80 -0
- data/lib/dhun/player.rb +66 -0
- data/lib/dhun/query.rb +44 -0
- data/lib/dhun/result.rb +32 -0
- data/lib/dhun/runner.rb +87 -0
- data/lib/dhun/server.rb +39 -0
- metadata +76 -0
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2009 Deepak Jois
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Introduction
|
2
|
+
|
3
|
+
> A dhun (Hindi: धुन; literally "tune") is a light instrumental piece in the
|
4
|
+
> Hindustani classical music of North India.
|
5
|
+
>
|
6
|
+
> Source : [Wikipedia](http://en.wikipedia.org/wiki/Dhun)
|
7
|
+
|
8
|
+
Dhun is a minimalist commandline music player for OS X.
|
9
|
+
|
10
|
+
It uses Spotlight to search for audio files on your computer and play them.
|
11
|
+
|
12
|
+
# Features
|
13
|
+
|
14
|
+
### Sneak Peek
|
15
|
+
|
16
|
+
deepak@vyombook ~/code/personal/dhun (master) $ ./dhun Spirit
|
17
|
+
Querying for kMDItemContentTypeTree == 'public.audio' && kMDItemAlbum == '*Spirit*'wc
|
18
|
+
/Users/deepak/Dropbox/shared/music/Coke Studio/Mai-Ne.mp3
|
19
|
+
/Users/deepak/Dropbox/shared/music/Coke Studio/Saari-Raat.mp3
|
20
|
+
/Users/deepak/Dropbox/shared/music/Coke Studio/Bulleya.mp3
|
21
|
+
/Users/deepak/Dropbox/shared/music/Coke Studio/Mahi-Ve.mp3
|
22
|
+
/Users/deepak/Dropbox/shared/music/Coke Studio/Chup.mp3
|
23
|
+
5 results total
|
24
|
+
Now Playing /Users/deepak/Dropbox/shared/music/Coke Studio/Mai-Ne.mp3
|
25
|
+
|
26
|
+
Here is what is planned.
|
27
|
+
|
28
|
+
* Client server model, where you can issue commands to the server like
|
29
|
+
`dhun play Spirit`, `dhun pause`, `dhun next`, `dhun prev` and `dhun stop`
|
30
|
+
|
31
|
+
* Flexible query syntax (like `artist:Rahman` or `album spirit`)
|
32
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
|
3
|
+
task :default => :package
|
4
|
+
|
5
|
+
# PACKAGING =================================================================
|
6
|
+
|
7
|
+
require 'rubygems/specification'
|
8
|
+
$spec = eval(File.read('dhun.gemspec'))
|
9
|
+
|
10
|
+
def package(ext='')
|
11
|
+
"pkg/dhun-#{$spec.version}" + ext
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Build packages'
|
15
|
+
task :package => %w[.gem .tar.gz].map {|e| package(e)}
|
16
|
+
|
17
|
+
desc 'Build and install as local gem'
|
18
|
+
task :install => package('.gem') do
|
19
|
+
sh "gem install #{package('.gem')}"
|
20
|
+
end
|
21
|
+
|
22
|
+
directory 'pkg/'
|
23
|
+
|
24
|
+
file package('.gem') => %w[pkg/ dhun.gemspec] + $spec.files do |f|
|
25
|
+
sh "gem build dhun.gemspec"
|
26
|
+
mv File.basename(f.name), f.name
|
27
|
+
end
|
28
|
+
|
29
|
+
file package('.tar.gz') => %w[pkg/] + $spec.files do |f|
|
30
|
+
sh "git archive --format=tar HEAD | gzip > #{f.name}"
|
31
|
+
end
|
32
|
+
|
33
|
+
# GEMSPEC HELPERS ==========================================================
|
34
|
+
|
35
|
+
def source_version
|
36
|
+
line = File.read('lib/dhun.rb')[/^\s*VERSION = .*/]
|
37
|
+
line.match(/.*VERSION = '(.*)'/)[1]
|
38
|
+
end
|
39
|
+
|
40
|
+
file 'dhun.gemspec' => FileList['Rakefile','lib/dhun.rb'] do |f|
|
41
|
+
puts "running"
|
42
|
+
# read spec file and split out manifest section
|
43
|
+
spec = File.read(f.name)
|
44
|
+
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
45
|
+
head.sub!(/\.version = '.*'/, ".version = '#{source_version}'")
|
46
|
+
head.sub!(/\.date = '.*'/, ".date = '#{Date.today.to_s}'")
|
47
|
+
# determine file list from git ls-files
|
48
|
+
files = `git ls-files`.
|
49
|
+
split("\n").
|
50
|
+
sort.
|
51
|
+
reject{ |file| file =~ /^\./ || file =~ /^test/ }.
|
52
|
+
map{ |file| " #{file}" }.
|
53
|
+
join("\n")
|
54
|
+
# piece file back together and write...
|
55
|
+
manifest = " s.files = %w[\n#{files}\n ]\n"
|
56
|
+
spec = [head,manifest,tail].join(" # = MANIFEST =\n")
|
57
|
+
File.open(f.name, 'w') { |io| io.write(spec) }
|
58
|
+
puts "updated #{f.name}"
|
59
|
+
end
|
60
|
+
|
61
|
+
# ==========================================================
|
62
|
+
# Ruby Extension
|
63
|
+
# ==========================================================
|
64
|
+
|
65
|
+
DLEXT = Config::CONFIG['DLEXT']
|
66
|
+
|
67
|
+
file 'ext/Makefile' => FileList['ext/{*.c,*.h,*.rb}'] do
|
68
|
+
chdir('ext') { ruby 'extconf.rb' }
|
69
|
+
end
|
70
|
+
CLEAN.include 'ext/Makefile', 'ext/mkmf.log'
|
71
|
+
|
72
|
+
file "ext/dhun_ext.#{DLEXT}" => FileList['ext/Makefile', 'ext/*.{c,h,rb}'] do |f|
|
73
|
+
sh 'cd ext && make'
|
74
|
+
end
|
75
|
+
CLEAN.include 'ext/*.{o,bundle,so,dll}'
|
76
|
+
|
77
|
+
file "lib/dhun_ext.#{DLEXT}" => "ext/dhun_ext.#{DLEXT}" do |f|
|
78
|
+
cp f.prerequisites, "lib/", :preserve => true
|
79
|
+
end
|
80
|
+
|
81
|
+
desc 'Build the dhun extension'
|
82
|
+
task :build => "lib/dhun_ext.#{DLEXT}"
|
83
|
+
|
data/TODO.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
* Gem files
|
2
|
+
|
3
|
+
TODO
|
4
|
+
====
|
5
|
+
|
6
|
+
* Daemonizing/Logging of Server
|
7
|
+
|
8
|
+
* Better querying mechanism using a treetop parser
|
9
|
+
|
10
|
+
* Prev, by keeping a history
|
11
|
+
|
12
|
+
* Display info from idv3 tags
|
13
|
+
|
14
|
+
* Advanced Querying Support
|
15
|
+
|
16
|
+
* iTunes support
|
17
|
+
|
18
|
+
* Pause and Skip functionality
|
19
|
+
|
data/bin/dhun
ADDED
data/ext/Makefile
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
|
2
|
+
SHELL = /bin/sh
|
3
|
+
|
4
|
+
#### Start of system configuration section. ####
|
5
|
+
|
6
|
+
srcdir = .
|
7
|
+
topdir = /usr/local/lib/ruby/1.8/i686-darwin10.0.0
|
8
|
+
hdrdir = $(topdir)
|
9
|
+
VPATH = $(srcdir):$(topdir):$(hdrdir)
|
10
|
+
exec_prefix = $(prefix)
|
11
|
+
prefix = $(DESTDIR)/usr/local
|
12
|
+
sharedstatedir = $(prefix)/com
|
13
|
+
mandir = $(datarootdir)/man
|
14
|
+
psdir = $(docdir)
|
15
|
+
oldincludedir = $(DESTDIR)/usr/include
|
16
|
+
localedir = $(datarootdir)/locale
|
17
|
+
bindir = $(exec_prefix)/bin
|
18
|
+
libexecdir = $(exec_prefix)/libexec
|
19
|
+
sitedir = $(libdir)/ruby/site_ruby
|
20
|
+
htmldir = $(docdir)
|
21
|
+
vendorarchdir = $(vendorlibdir)/$(sitearch)
|
22
|
+
includedir = $(prefix)/include
|
23
|
+
infodir = $(datarootdir)/info
|
24
|
+
vendorlibdir = $(vendordir)/$(ruby_version)
|
25
|
+
sysconfdir = $(prefix)/etc
|
26
|
+
libdir = $(exec_prefix)/lib
|
27
|
+
sbindir = $(exec_prefix)/sbin
|
28
|
+
rubylibdir = $(libdir)/ruby/$(ruby_version)
|
29
|
+
docdir = $(datarootdir)/doc/$(PACKAGE)
|
30
|
+
dvidir = $(docdir)
|
31
|
+
vendordir = $(libdir)/ruby/vendor_ruby
|
32
|
+
datarootdir = $(prefix)/share
|
33
|
+
pdfdir = $(docdir)
|
34
|
+
archdir = $(rubylibdir)/$(arch)
|
35
|
+
sitearchdir = $(sitelibdir)/$(sitearch)
|
36
|
+
datadir = $(datarootdir)
|
37
|
+
localstatedir = $(prefix)/var
|
38
|
+
sitelibdir = $(sitedir)/$(ruby_version)
|
39
|
+
|
40
|
+
CC = gcc
|
41
|
+
LIBRUBY = $(LIBRUBY_SO)
|
42
|
+
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
43
|
+
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
|
44
|
+
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
|
45
|
+
|
46
|
+
RUBY_EXTCONF_H =
|
47
|
+
CFLAGS = -fno-common -D_XOPEN_SOURCE=1 -fno-common -pipe -fno-common $(cflags) -std=c99
|
48
|
+
INCFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir)
|
49
|
+
DEFS =
|
50
|
+
CPPFLAGS = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE $(DEFS) $(cppflags)
|
51
|
+
CXXFLAGS = $(CFLAGS)
|
52
|
+
ldflags = -L. -framework AudioToolbox -framework CoreServices
|
53
|
+
dldflags =
|
54
|
+
archflag =
|
55
|
+
DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
|
56
|
+
LDSHARED = cc -dynamic -bundle -undefined suppress -flat_namespace
|
57
|
+
AR = ar
|
58
|
+
EXEEXT =
|
59
|
+
|
60
|
+
RUBY_INSTALL_NAME = ruby
|
61
|
+
RUBY_SO_NAME = ruby
|
62
|
+
arch = i686-darwin10.0.0
|
63
|
+
sitearch = i686-darwin10.0.0
|
64
|
+
ruby_version = 1.8
|
65
|
+
ruby = /usr/local/bin/ruby
|
66
|
+
RUBY = $(ruby)
|
67
|
+
RM = rm -f
|
68
|
+
MAKEDIRS = mkdir -p
|
69
|
+
INSTALL = /usr/bin/install -c
|
70
|
+
INSTALL_PROG = $(INSTALL) -m 0755
|
71
|
+
INSTALL_DATA = $(INSTALL) -m 644
|
72
|
+
COPY = cp
|
73
|
+
|
74
|
+
#### End of system configuration section. ####
|
75
|
+
|
76
|
+
preload =
|
77
|
+
|
78
|
+
libpath = . $(libdir)
|
79
|
+
LIBPATH = -L. -L$(libdir)
|
80
|
+
DEFFILE =
|
81
|
+
|
82
|
+
CLEANFILES = mkmf.log
|
83
|
+
DISTCLEANFILES =
|
84
|
+
|
85
|
+
extout =
|
86
|
+
extout_prefix =
|
87
|
+
target_prefix =
|
88
|
+
LOCAL_LIBS =
|
89
|
+
LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl -lobjc
|
90
|
+
SRCS = dhun_ext.c player.c query.c
|
91
|
+
OBJS = dhun_ext.o player.o query.o
|
92
|
+
TARGET = dhun_ext
|
93
|
+
DLLIB = $(TARGET).bundle
|
94
|
+
EXTSTATIC =
|
95
|
+
STATIC_LIB =
|
96
|
+
|
97
|
+
BINDIR = $(bindir)
|
98
|
+
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
99
|
+
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
100
|
+
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
101
|
+
|
102
|
+
TARGET_SO = $(DLLIB)
|
103
|
+
CLEANLIBS = $(TARGET).bundle $(TARGET).il? $(TARGET).tds $(TARGET).map
|
104
|
+
CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
|
105
|
+
|
106
|
+
all: $(DLLIB)
|
107
|
+
static: $(STATIC_LIB)
|
108
|
+
|
109
|
+
clean:
|
110
|
+
@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
|
111
|
+
|
112
|
+
distclean: clean
|
113
|
+
@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
114
|
+
@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
|
115
|
+
|
116
|
+
realclean: distclean
|
117
|
+
install: install-so install-rb
|
118
|
+
|
119
|
+
install-so: $(RUBYARCHDIR)
|
120
|
+
install-so: $(RUBYARCHDIR)/$(DLLIB)
|
121
|
+
$(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
|
122
|
+
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
|
123
|
+
install-rb: pre-install-rb install-rb-default
|
124
|
+
install-rb-default: pre-install-rb-default
|
125
|
+
pre-install-rb: Makefile
|
126
|
+
pre-install-rb-default: Makefile
|
127
|
+
$(RUBYARCHDIR):
|
128
|
+
$(MAKEDIRS) $@
|
129
|
+
|
130
|
+
site-install: site-install-so site-install-rb
|
131
|
+
site-install-so: install-so
|
132
|
+
site-install-rb: install-rb
|
133
|
+
|
134
|
+
.SUFFIXES: .c .m .cc .cxx .cpp .C .o
|
135
|
+
|
136
|
+
.cc.o:
|
137
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
138
|
+
|
139
|
+
.cxx.o:
|
140
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
141
|
+
|
142
|
+
.cpp.o:
|
143
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
144
|
+
|
145
|
+
.C.o:
|
146
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
147
|
+
|
148
|
+
.c.o:
|
149
|
+
$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
|
150
|
+
|
151
|
+
$(DLLIB): $(OBJS) Makefile
|
152
|
+
@-$(RM) $@
|
153
|
+
$(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
|
154
|
+
|
155
|
+
|
156
|
+
|
157
|
+
$(OBJS): ruby.h defines.h
|
data/ext/dhun.h
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <string.h>
|
3
|
+
|
4
|
+
#include <CoreServices/CoreServices.h>
|
5
|
+
#include <CoreAudio/CoreAudioTypes.h>
|
6
|
+
#include <AudioToolbox/AudioToolbox.h>
|
7
|
+
#include <CoreServices/CoreServices.h>
|
8
|
+
|
9
|
+
#define LOG(f,s) fprintf(stderr,f,s);fflush(stderr);
|
10
|
+
#define QUERY_TEMPLATE "kMDItemContentTypeTree == 'public.audio' && (kMDItemAlbum == '*%s*'wc || kMDItemTitle == '*%s*'wc || kMDItemDisplayName == '*%s*'wc)"
|
11
|
+
|
12
|
+
#define kNumberBuffers 3
|
13
|
+
typedef struct {
|
14
|
+
AudioStreamBasicDescription mDataFormat;
|
15
|
+
AudioQueueRef mQueue;
|
16
|
+
AudioQueueBufferRef mBuffers[kNumberBuffers];
|
17
|
+
AudioFileID mAudioFile;
|
18
|
+
UInt32 bufferByteSize;
|
19
|
+
SInt64 mCurrentPacket;
|
20
|
+
UInt32 mNumPacketsToRead;
|
21
|
+
AudioStreamPacketDescription *mPacketDescs;
|
22
|
+
bool mIsRunning;
|
23
|
+
} AQPlayerState;
|
24
|
+
|
25
|
+
extern AQPlayerState aqData;
|
26
|
+
|
27
|
+
typedef struct {
|
28
|
+
int size;
|
29
|
+
char** files;
|
30
|
+
} SearchResults;
|
31
|
+
|
32
|
+
extern SearchResults queryResults;
|
33
|
+
|
34
|
+
|
35
|
+
void playFile(const char* filePath);
|
36
|
+
void free_aqData();
|
37
|
+
int getFilesForQuery(const char* queryStr);
|
data/ext/dhun_ext.c
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
#include "dhun.h"
|
2
|
+
#include <assert.h>
|
3
|
+
#include <pthread.h>
|
4
|
+
|
5
|
+
// Include the Ruby headers and goodies
|
6
|
+
#include "ruby.h"
|
7
|
+
#include "rubysig.h"
|
8
|
+
// Defining a space for information and references about the module to be stored internally
|
9
|
+
static VALUE DhunExt = Qnil;
|
10
|
+
|
11
|
+
static VALUE Spotlight = Qnil;
|
12
|
+
|
13
|
+
static VALUE Player = Qnil;
|
14
|
+
|
15
|
+
static pthread_t posixThreadID;
|
16
|
+
|
17
|
+
// Prototype for the initialization method - Ruby calls this, not you
|
18
|
+
void Init_dhunruby();
|
19
|
+
|
20
|
+
static VALUE method_play_file(VALUE self, VALUE fileName);
|
21
|
+
static VALUE method_pause_play(VALUE self);
|
22
|
+
static VALUE method_query_spotlight(VALUE self, VALUE query);
|
23
|
+
static VALUE method_is_playing(VALUE self);
|
24
|
+
|
25
|
+
// The initialization method for this module
|
26
|
+
void Init_dhun_ext() {
|
27
|
+
DhunExt = rb_define_class("DhunExt", rb_cObject);
|
28
|
+
rb_define_singleton_method(DhunExt, "play_file", method_play_file, 1);
|
29
|
+
rb_define_singleton_method(DhunExt, "query_spotlight", method_query_spotlight, 1);
|
30
|
+
rb_define_singleton_method(DhunExt, "pause_play", method_pause_play, 0);
|
31
|
+
rb_define_singleton_method(DhunExt, "is_playing?", method_is_playing, 0);
|
32
|
+
}
|
33
|
+
|
34
|
+
static VALUE method_play_file(VALUE self, VALUE filename) {
|
35
|
+
playFile(StringValuePtr(filename));
|
36
|
+
struct timeval wait;
|
37
|
+
wait.tv_sec=0;
|
38
|
+
wait.tv_usec=100*1000;
|
39
|
+
do {
|
40
|
+
CHECK_INTS;
|
41
|
+
CFRunLoopRunInMode (kCFRunLoopDefaultMode,
|
42
|
+
0.25,
|
43
|
+
false);
|
44
|
+
} while (aqData.mIsRunning);
|
45
|
+
|
46
|
+
CFRunLoopRunInMode(kCFRunLoopDefaultMode,
|
47
|
+
1,
|
48
|
+
false);
|
49
|
+
free_aqData();
|
50
|
+
return Qnil;
|
51
|
+
}
|
52
|
+
|
53
|
+
static VALUE method_pause_play(VALUE self) {
|
54
|
+
aqData.mIsRunning = false;
|
55
|
+
return Qnil;
|
56
|
+
}
|
57
|
+
|
58
|
+
static VALUE method_is_playing(VALUE self) {
|
59
|
+
if (aqData.mIsRunning == true)
|
60
|
+
return Qtrue;
|
61
|
+
else
|
62
|
+
return Qfalse;
|
63
|
+
}
|
64
|
+
|
65
|
+
static VALUE method_query_spotlight(VALUE self, VALUE query) {
|
66
|
+
getFilesForQuery(StringValuePtr(query));
|
67
|
+
VALUE files = rb_ary_new();
|
68
|
+
|
69
|
+
if (queryResults.size > 0) { // there were some results
|
70
|
+
|
71
|
+
for(int i=0; i<queryResults.size;i++) {
|
72
|
+
rb_ary_push(files,rb_str_new2(queryResults.files[i]));
|
73
|
+
free(queryResults.files[i]);
|
74
|
+
}
|
75
|
+
|
76
|
+
if (queryResults.size > 0) {
|
77
|
+
queryResults.size = 0;
|
78
|
+
free(queryResults.files);
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
return files;
|
83
|
+
}
|
84
|
+
|