Add comment.
[libdcp.git] / src / util.cc
1 /*
2     Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program 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
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 /** @file  src/util.cc
21  *  @brief Utility methods.
22  */
23
24 #include <stdexcept>
25 #include <sstream>
26 #include <iostream>
27 #include <iomanip>
28 #include <boost/filesystem.hpp>
29 #include <openssl/sha.h>
30 #include "KM_util.h"
31 #include "KM_fileio.h"
32 #include "AS_DCP.h"
33 #include "util.h"
34 #include "exceptions.h"
35 #include "types.h"
36
37 using namespace std;
38 using namespace boost;
39
40 string
41 libdcp::make_uuid ()
42 {
43         char buffer[64];
44         Kumu::UUID id;
45         Kumu::GenRandomValue (id);
46         id.EncodeHex (buffer, 64);
47         return string (buffer);
48 }
49
50 string
51 libdcp::make_digest (string filename, sigc::signal1<void, float>* progress)
52 {
53         int const file_size = filesystem::file_size (filename);
54         
55         Kumu::FileReader reader;
56         if (ASDCP_FAILURE (reader.OpenRead (filename.c_str ()))) {
57                 throw FileError ("could not open file to compute digest", filename);
58         }
59         
60         SHA_CTX sha;
61         SHA1_Init (&sha);
62         
63         Kumu::ByteString read_buffer (65536);
64         int done = 0;
65         while (1) {
66                 ui32_t read = 0;
67                 Kumu::Result_t r = reader.Read (read_buffer.Data(), read_buffer.Capacity(), &read);
68                 
69                 if (r == Kumu::RESULT_ENDOFFILE) {
70                         break;
71                 } else if (ASDCP_FAILURE (r)) {
72                         throw FileError ("could not read file to compute digest", filename);
73                 }
74                 
75                 SHA1_Update (&sha, read_buffer.Data(), read);
76                 done += read;
77
78                 if (progress) {
79                         (*progress) (0.5 + (0.5 * done / file_size));
80                 }
81         }
82
83         byte_t byte_buffer[20];
84         SHA1_Final (byte_buffer, &sha);
85
86         stringstream s;
87         char digest[64];
88         return Kumu::base64encode (byte_buffer, 20, digest, 64);
89 }
90
91 string
92 libdcp::content_kind_to_string (ContentKind kind)
93 {
94         switch (kind) {
95         case FEATURE:
96                 return "feature";
97         case SHORT:
98                 return "short";
99         case TRAILER:
100                 return "trailer";
101         case TEST:
102                 return "test";
103         case TRANSITIONAL:
104                 return "transitional";
105         case RATING:
106                 return "rating";
107         case TEASER:
108                 return "teaser";
109         case POLICY:
110                 return "policy";
111         case PUBLIC_SERVICE_ANNOUNCEMENT:
112                 return "psa";
113         case ADVERTISEMENT:
114                 return "advertisement";
115         }
116
117         assert (false);
118 }
119
120 libdcp::ContentKind
121 libdcp::content_kind_from_string (string type)
122 {
123         if (type == "feature") {
124                 return FEATURE;
125         } else if (type == "short") {
126                 return SHORT;
127         } else if (type == "trailer") {
128                 return TRAILER;
129         } else if (type == "test") {
130                 return TEST;
131         } else if (type == "transitional") {
132                 return TRANSITIONAL;
133         } else if (type == "rating") {
134                 return RATING;
135         } else if (type == "teaser") {
136                 return TEASER;
137         } else if (type == "policy") {
138                 return POLICY;
139         } else if (type == "psa") {
140                 return PUBLIC_SERVICE_ANNOUNCEMENT;
141         } else if (type == "advertisement") {
142                 return ADVERTISEMENT;
143         }
144
145         assert (false);
146 }
147                 
148 bool
149 libdcp::ends_with (string big, string little)
150 {
151         if (little.size() > big.size()) {
152                 return false;
153         }
154
155         return big.compare (big.length() - little.length(), little.length(), little) == 0;
156 }