libdigidocpp
Document.cpp
Go to the documentation of this file.
1 /*
2  * libdigidocpp
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  */
19 
20 #include "log.h"
21 #include "Document.h"
22 #include "crypto/Digest.h"
23 #include "util/File.h"
24 
25 #include <fstream>
26 
33 digidoc::Document::Document(const std::string &filepath, const std::string &mediaType)
34  : filename(digidoc::util::File::fileName(filepath))
35  , filepath(filepath)
36  , mediaType(mediaType)
37 {
38 }
39 
47 digidoc::Document::Document(const std::string &filename, const std::string &filepath, const std::string &mediaType, const std::string &id)
48  : id( id.empty() ? "/" + filename : id )
49  , filename(filename)
50  , filepath(filepath)
51  , mediaType(mediaType)
52 {
53 }
54 
58 std::string digidoc::Document::getId() const
59 {
60  return id;
61 }
62 
66 std::string digidoc::Document::getFileName() const
67 {
68  return filename;
69 }
70 
74 std::string digidoc::Document::getFilePath() const
75 {
76  return filepath;
77 }
78 
84 {
85  return mediaType;
86 }
87 
91 unsigned long digidoc::Document::getSize() const throw(IOException)
92 {
93  return util::File::fileSize(filepath);
94 }
95 
104 std::vector<unsigned char> digidoc::Document::calcDigest(Digest* calc) throw(IOException)
105 {
106  if(!calc)
107  THROW_IOEXCEPTION("Null pointer in Documnent::calcDigest");
108 
109  // If digest is already calculated return it.
110  if(!digest.empty())
111  {
112  DEBUG("Digest already calculated");
113  return digest;
114  }
115 
116  // Calculate digest.
117  std::ifstream ifs(digidoc::util::File::encodeName(filepath).c_str(), std::ios::in | std::ios::binary);
118  if(!ifs.is_open() || ifs.fail())
119  THROW_IOEXCEPTION("Failed to open document file '%s'.", filepath.c_str());
120 
121  unsigned int const BUF_SIZE = 10240;
122  while( ifs )
123  {
124  char buf[BUF_SIZE];
125  ifs.read( buf, BUF_SIZE );
126  unsigned long bytesRead = (unsigned long)ifs.gcount();
127  if ( bytesRead > 0 )
128  {
129  DEBUG("Added %d bytes from %s", bytesRead, filepath.c_str());
130  calc->update(reinterpret_cast<unsigned char*>(buf), bytesRead);
131  }
132  }
133 
134  digest = calc->getDigest();
135  DEBUGMEM("digest", &digest[0], digest.size());
136  return digest;
137 }
138 
144 void digidoc::Document::saveAs(const std::string& path) throw(IOException)
145 {
146  util::File::copyFile(filepath, path);
147 }