stlab.adobe.com Adobe Systems Incorporated

file_slurp.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2007 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://stlab.adobe.com/licenses.html)
00005 */
00006 
00007 /*************************************************************************************************/
00008 
00009 #ifndef ADOBE_FILE_SLURP_HPP
00010 #define ADOBE_FILE_SLURP_HPP
00011 
00012 /*************************************************************************************************/
00013 
00014 #include <adobe/config.hpp>
00015 
00016 #include <boost/filesystem/operations.hpp>
00017 #include <boost/filesystem/fstream.hpp>
00018 
00019 #include <boost/noncopyable.hpp>
00020 
00021 #include <stdexcept>
00022 
00023 /****************************************************************************************************/
00024 
00025 // REVISIT (fbrereto) : Eventually I'd like to get this file slurper to the point where
00026 //                      it reads 64k blocks out of the file as it needs to, instead of
00027 //                      slurping the file all at once.
00028 
00029 /****************************************************************************************************/
00030 
00031 namespace adobe {
00032 
00033 /****************************************************************************************************/
00034 
00035 template <typename T>
00036 struct file_slurp : boost::noncopyable
00037 {
00038     typedef T*          store_type;
00039     typedef std::size_t size_type;
00040     typedef T           value_type;
00041     typedef T*          iterator;
00042     typedef const T*    const_iterator;
00043 
00044     explicit file_slurp(const boost::filesystem::path& path) :
00045         contents_m(0), size_m(0), path_m(path)
00046     { reslurp(); }
00047 
00048     ~file_slurp()
00049     { if (contents_m) delete [] contents_m; }
00050 
00051     iterator begin() { return &contents_m[0]; }
00052     iterator end()   { return begin() + size(); }
00053 
00054     const_iterator begin() const { return &contents_m[0]; }
00055     const_iterator end() const   { return begin() + size(); }
00056 
00057     bool        empty() const { return size() == 0; }
00058     size_type   size() const  { return size_m; }
00059 
00060     T*          c_str() { return contents_m; }
00061 
00062     T*          release()
00063     {
00064         T* result(contents_m);
00065 
00066         contents_m = 0;
00067 
00068         return result;
00069     }
00070 
00071     void reslurp();
00072 
00073 private:
00074     T*                      contents_m;
00075     size_type               size_m;
00076     boost::filesystem::path path_m;
00077 };
00078 
00079 /****************************************************************************************************/
00080 
00081 template <typename T>
00082 void file_slurp<T>::reslurp()
00083 {
00084     if (contents_m)
00085         return;
00086 
00087     size_m = 0;
00088 
00089     boost::intmax_t size(boost::filesystem::file_size(path_m));
00090 
00091     contents_m = new T[static_cast<std::size_t>(size) + 1];
00092 
00093     if (size == 0)
00094         return;
00095 
00096     boost::filesystem::ifstream in(path_m, std::ios_base::in | std::ios_base::binary);
00097 
00098     if (!in.is_open())
00099 #if 1
00100         throw std::runtime_error("file slurp: failed to open file");
00101 #else
00102         return;
00103 #endif
00104 
00105     in.unsetf(std::ios_base::skipws);
00106 
00107     // read in max 64K at a time
00108     std::size_t buffer_size(64*1024);
00109 
00110     if (static_cast<std::size_t>(size) < buffer_size)
00111         buffer_size = static_cast<std::size_t>(size);
00112 
00113     while (true)
00114     {
00115         in.read(&contents_m[size_m], static_cast<std::streamsize>(buffer_size));
00116 
00117         std::size_t count(static_cast<std::size_t>(in.gcount()));
00118 
00119         size_m += count;
00120 
00121         if (count != buffer_size)
00122             break;
00123     }
00124 
00125     contents_m[size_m] = 0;
00126 }
00127 
00128 /****************************************************************************************************/
00129 
00130 } // namespace adobe
00131 
00132 /****************************************************************************************************/
00133 
00134 #endif
00135 
00136 /****************************************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google