@@ -194,15 +194,7 @@ func (r *Resource) GetTable(opts ...csv.CreationOpts) (table.Table, error) {
194194 return nil , fmt .Errorf ("only csv and string is supported for inlining data" )
195195 }
196196 }
197- buf , err := loadContents (r .basePath , r .path , csvLoadFunc )
198- if err != nil {
199- return nil , err
200- }
201- t , err := csv .NewTable (func () (io.ReadCloser , error ) { return ioutil .NopCloser (bytes .NewReader (buf )), nil }, fullOpts ... )
202- if err != nil {
203- return nil , err
204- }
205- return t , nil
197+ return csv .NewTable (func () (io.ReadCloser , error ) { return loadContents (r .basePath , r .path , csvLoadFunc ) }, fullOpts ... )
206198}
207199
208200func csvLoadFunc (p string ) func () (io.ReadCloser , error ) {
@@ -233,23 +225,39 @@ func binaryLoadFunc(p string) func() (io.ReadCloser, error) {
233225 if err != nil {
234226 return nil , err
235227 }
236- defer resp .Body .Close ()
237- b , err := ioutil .ReadAll (resp .Body )
238- if err != nil {
239- return nil , err
240- }
241- return ioutil .NopCloser (bytes .NewReader (b )), nil
228+ return resp .Body , nil
242229 }
243230 }
244231 return func () (io.ReadCloser , error ) {
245232 return os .Open (p )
246233 }
247234}
248235
249- type loadFunc func (string ) func () (io.ReadCloser , error )
236+ type multiReadCloser struct {
237+ io.Reader
238+ rcs []io.ReadCloser
239+ }
240+
241+ func (m * multiReadCloser ) Close () error {
242+ var err error
243+ for _ , rc := range m .rcs {
244+ if e := rc .Close (); e != nil {
245+ err = e
246+ }
247+ }
248+ return err
249+ }
250+
251+ func newMultiReadCloser (rcs []io.ReadCloser ) io.ReadCloser {
252+ readers := make ([]io.Reader , len (rcs ))
253+ for i := range rcs {
254+ readers [i ] = io .Reader (rcs [i ])
255+ }
256+ return & multiReadCloser {io .MultiReader (readers ... ), rcs }
257+ }
250258
251- func loadContents (basePath string , path []string , f loadFunc ) ([] byte , error ) {
252- var buf bytes. Buffer
259+ func loadContents (basePath string , path []string , f func ( string ) func () (io. ReadCloser , error )) (io. ReadCloser , error ) {
260+ var rcs []io. ReadCloser
253261 for _ , p := range path {
254262 if basePath != "" {
255263 p = joinPaths (basePath , p )
@@ -258,17 +266,12 @@ func loadContents(basePath string, path []string, f loadFunc) ([]byte, error) {
258266 if err != nil {
259267 return nil , err
260268 }
261- defer rc .Close ()
262- b , err := ioutil .ReadAll (rc )
263- if err != nil {
264- return nil , err
265- }
266- buf .Write (b )
269+ rcs = append (rcs , rc )
267270 if len (path ) > 1 {
268- buf . WriteRune ( '\n' )
271+ rcs = append ( rcs , ioutil . NopCloser ( bytes . NewReader ([] byte { '\n' })) )
269272 }
270273 }
271- return buf . Bytes ( ), nil
274+ return newMultiReadCloser ( rcs ), nil
272275}
273276
274277func joinPaths (basePath , path string ) string {
@@ -289,11 +292,11 @@ func (r *Resource) ReadAll(opts ...csv.CreationOpts) ([][]string, error) {
289292 return t .ReadAll ()
290293}
291294
292- // RawRead reads all resource contents and return it as byte slice .
295+ // RawRead returns an io.ReaderCloser associated to the resource contents .
293296// It can be used to access the content of non-tabular resources.
294- func (r * Resource ) RawRead () ([] byte , error ) {
297+ func (r * Resource ) RawRead () (io. ReadCloser , error ) {
295298 if r .data != nil {
296- return []byte (r .data .(string )), nil
299+ return ioutil . NopCloser ( bytes . NewReader ( []byte (r .data .(string )) )), nil
297300 }
298301 return loadContents (r .basePath , r .path , binaryLoadFunc )
299302}
0 commit comments