Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 4 commits
  • 18 files changed
  • 0 comments
  • 1 contributor
3  .gitmodules
... ...
@@ -1,6 +1,3 @@
1  
-[submodule "external/bp-service-tools"]
2  
-	path = external/bp-service-tools
3  
-	url = git://github.com/browserplus/bp-service-tools.git
4 1
 [submodule "external/bakery"]
5 2
 	path = external/bakery
6 3
 	url = git://github.com/browserplus/bakery.git
2  external/bp-service-framework
... ...
@@ -1 +1 @@
1  
-Subproject commit 0eaff8dda4c95e6f369d02da3ee71a0844170e89
  1
+Subproject commit 1f027b6d5c1b1d0d8a3ae1587ef3654a11aae08b
1  external/bp-service-tools
... ...
@@ -1 +0,0 @@
1  
-Subproject commit fa4113518ffa16f022890f9470c09aab16dd497c
19  src/CMakeLists.txt
@@ -44,8 +44,7 @@ INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/../external/bp-build-templates/cmake/BuildCo
44 44
 
45 45
 INCLUDE_DIRECTORIES(
46 46
   "${CMAKE_CURRENT_SOURCE_DIR}/../external/dist/include"
47  
-  "${CMAKE_CURRENT_SOURCE_DIR}/../external/bp-service-tools/CppTools/external/bpsdk/include"
48  
-  "${CMAKE_CURRENT_SOURCE_DIR}/../external/bp-service-tools/CppTools/src"
  47
+  "${CMAKE_CURRENT_SOURCE_DIR}/../external/bp-service-framework/include"
49 48
 )
50 49
 
51 50
 IF ("${CMAKE_BUILD_TYPE}" STREQUAL "CodeCoverage")
@@ -60,33 +59,25 @@ ELSE ()
60 59
   )
61 60
 ENDIF ()
62 61
 
63  
-SET(EXT_SRCS
64  
-  ${CMAKE_CURRENT_SOURCE_DIR}/../external/bp-service-tools/CppTools/src/bptypeutil.cpp
65  
-  ${CMAKE_CURRENT_SOURCE_DIR}/../external/bp-service-tools/CppTools/src/bpurlutil.cpp
66  
-  ${CMAKE_CURRENT_SOURCE_DIR}/../external/bp-service-tools/CppTools/src/bpservicedescription.cpp
67  
-  ${CMAKE_CURRENT_SOURCE_DIR}/../external/bp-service-tools/CppTools/src/bpserviceversion.cpp
68  
-)
69  
-
70 62
 # add required OS libs here
71 63
 SET(OS_LIBS)
72 64
 IF (WIN32)
73 65
    # Visual Studio does some autolink magic with boost, no need
74 66
    # to specify library
75  
-   SET (OS_SRCS util/bpsync_Windows.cpp)
76 67
    SET (OS_LIBS Winmm Ws2_32 mswsock rpcrt4 psapi)
  68
+   SET (OS_SRCS littleuuid_Windows.cpp)
77 69
 ELSE()
78 70
    SET(BOOST_LIBS "boost_filesystem" "boost_system")
79  
-   SET (OS_SRCS util/bpsync_UNIX.cpp)
80  
-
81 71
    IF (APPLE)
82 72
        # need carbon headers and library
83 73
        FIND_LIBRARY(CARBON_LIBRARY Carbon)
84 74
        MARK_AS_ADVANCED(CARBON_LIBRARY)
85 75
        SET(OS_LIBS ${CARBON_LIBRARY})
  76
+       SET (OS_SRCS littleuuid_Darwin.cpp)
86 77
    ENDIF()
87 78
 ENDIF ()
88  
-SET(SRCS service.cpp littleuuid.cpp FileServer.cpp util/fileutil.cpp ${EXT_SRCS} ${OS_SRCS})
89  
-SET(HDRS service.h littleuuid.h ResourceLimit.h FileServer.h util/bpsync.hh util/fileutil.hh)
  79
+SET(SRCS service.cpp FileServer.cpp ${OS_SRCS})
  80
+SET(HDRS littleuuid.h ResourceLimit.h FileServer.h)
90 81
 SET(LIBS mongoose_s bpfile_s ${BOOST_LIBS} ${OS_LIBS})
91 82
 
92 83
 BPAddCppService()
172  src/FileServer.cpp
@@ -5,128 +5,104 @@
5 5
  *  (c) 2008 Yahoo! inc.
6 6
  */
7 7
 
8  
-#include <fstream>
9  
-
10 8
 #include "FileServer.h"
11  
-#include "service.h"
  9
+#include "bpservice/bpservice.h"
12 10
 #include "littleuuid.h"
13  
-#include "util/fileutil.hh"
14  
-#include "util/bpsync.hh"
15  
-
16 11
 #include <mongoose/mongoose.h>
  12
+#include <sstream>
17 13
 
18 14
 #define FS_MAX_TEMP_FILES 1024
19 15
 #define FS_MAX_TEMP_BYTES 1024 * 1024 * 512
  16
+#define BUFSIZE 1024 * 8
20 17
 
21  
-
22  
-FileServer::FileServer(const boost::filesystem::path& tempDir) 
23  
-    : m_tempDir(tempDir),
24  
-      m_limit(FS_MAX_TEMP_FILES, FS_MAX_TEMP_BYTES),
25  
-      m_ctx(NULL)
26  
-{
27  
-    BPCLOG_INFO_STRM( "ctor, tempDir = " << m_tempDir );
  18
+FileServer::FileServer(const boost::filesystem::path& tempDir) :
  19
+    m_tempDir(tempDir),
  20
+    m_limit(FS_MAX_TEMP_FILES, FS_MAX_TEMP_BYTES),
  21
+    m_ctx(NULL) {
  22
+    bplus::service::Service::log(BP_INFO, "ctor, tempDir = " + m_tempDir.string());
28 23
 }
29 24
 
30  
-FileServer::~FileServer()
31  
-{
  25
+FileServer::~FileServer() {
32 26
     if (m_ctx) {
33  
-        mg_stop((struct mg_context *) m_ctx);
34  
-        mg_destroy((struct mg_context *) m_ctx);        
  27
+        mg_stop((struct mg_context*)m_ctx);
  28
+        mg_destroy((struct mg_context*)m_ctx);        
35 29
         m_ctx = NULL;
36 30
     }
37  
-    BPCLOG_INFO( "Stopping m_httpServer." );
  31
+    bplus::service::Service::log(BP_INFO, "Stopping m_httpServer.");
38 32
     bp::file::safeRemove(m_tempDir);
39 33
 }
40 34
 
41 35
 std::string
42  
-FileServer::start()
43  
-{
  36
+FileServer::start() {
44 37
     std::stringstream boundTo;
45 38
     m_port = 0;
46  
-    struct mg_context * ctx = mg_create();
47  
-    int nRet = mg_set_option( ctx, "ports", "0" );
  39
+    struct mg_context* ctx = mg_create();
  40
+    int nRet = mg_set_option(ctx, "ports", "0");
48 41
     if (nRet <= 0 || !mg_start(ctx)) {
49 42
         mg_destroy(ctx);
50 43
         return std::string();
51 44
     }
52  
-    m_port = (unsigned short) nRet;
  45
+    m_port = (unsigned short)nRet;
53 46
     boundTo << "127.0.0.1:" << m_port;
54  
-    BPCLOG_INFO_STRM( "Bound to: " << boundTo.str() );
  47
+    bplus::service::Service::log(BP_INFO, "Bound to: " + boundTo.str());
55 48
     m_ctx = ctx;
56  
-
57 49
     // now set up the callback function
58  
-    mg_set_uri_callback(ctx, "*", (mg_callback_t) mongooseCallback, (void *) this);
59  
-    
  50
+    mg_set_uri_callback(ctx, "*", (mg_callback_t)mongooseCallback, (void*)this);
60 51
     return boundTo.str();
61 52
 }
62 53
 
63  
-
64 54
 std::string
65  
-FileServer::addFile(const boost::filesystem::path& path)
66  
-{
  55
+FileServer::addFile(const boost::filesystem::path& path) {
67 56
     // generate a nice random url path
68 57
     std::stringstream url;    
69 58
     std::string uuid;
70  
-
71 59
     uuid_generate(uuid);
72 60
     url << "http://127.0.0.1:" << m_port << "/" << uuid;
73 61
     {
74  
-        bp::sync::Lock lck(m_lock);
  62
+        bplus::sync::Lock lck(m_lock);
75 63
         m_paths[uuid] = path;
76 64
     }
77  
-
78  
-    BPCLOG_DEBUG_STRM( "m_urls[" << uuid << "] = " << path.string() );
  65
+    bplus::service::Service::log(BP_DEBUG, "m_urls[" + uuid + "] = " + path.string());
79 66
     return url.str();
80 67
 }
81 68
 
82 69
 std::vector<ChunkInfo>
83  
-FileServer::getFileChunks(const boost::filesystem::path& path,
84  
-                          size_t chunkSize)
85  
-{
  70
+FileServer::getFileChunks(const boost::filesystem::path& path, size_t chunkSize) {
86 71
     if (m_tempDir.empty()) {
87 72
         throw std::string("no temp dir set, internal error");        
88 73
     }
89  
-
90 74
     try {
91 75
         boost::filesystem::create_directories(m_tempDir);
92 76
     } catch (const boost::filesystem::filesystem_error&) {
93 77
         throw std::string("unable to create temp dir");
94 78
     }
95  
-
96 79
     std::vector<ChunkInfo> rval;
97  
-
98 80
     std::ifstream fstream;
99  
-    if (!bp::file::openReadableStream(fstream, path, 
100  
-                                      std::ios_base::in | std::ios_base::binary)) {
  81
+    if (!bp::file::openReadableStream(fstream, path, std::ios_base::in | std::ios_base::binary)) {
101 82
         throw std::string("cannot open file for reading");
102 83
     }
103  
-
104 84
     // get filesize
105 85
     fstream.seekg(0, std::ios::end);
106 86
     size_t size = (size_t) fstream.tellg();
107 87
     fstream.seekg(0, std::ios::beg);
108  
-    BPCLOG_DEBUG_STRM("file size = " << size);
109  
-
110  
-    if (size <= 0) throw std::string("chunk size is invalid");
111  
-
  88
+    bplus::service::Service::log(BP_DEBUG, "file size = " + size);
  89
+    if (size <= 0) {
  90
+        throw std::string("chunk size is invalid");
  91
+    }
112 92
     // check resource usage
113 93
     if (m_limit.wouldExceed(size / chunkSize, size)) {
114 94
         throw std::string("allowed resources exceeded");
115 95
     }
116  
-
117  
-
118 96
     // if file fits in a single chunk, just return the file
119 97
     if (size <= chunkSize) {
120  
-        ChunkInfo i = {path, 1, 1};
  98
+        ChunkInfo i = { path, 1, 1 };
121 99
         rval.push_back(i);
122 100
         return rval;
123 101
     }
124  
-
125 102
     char* buf = new char[chunkSize];
126 103
     if (!buf) {
127 104
         throw std::string("unable to allocate memory");
128 105
     }
129  
-
130 106
     try {
131 107
         size_t chunkNumber = 0;
132 108
         size_t totalRead = 0;
@@ -136,18 +112,18 @@ FileServer::getFileChunks(const boost::filesystem::path& path,
136 112
             if (fstream.bad()) {
137 113
                 throw std::string("error reading file");
138 114
             }
139  
-            size_t numRead = (size_t) fstream.gcount();
  115
+            size_t numRead = (size_t)fstream.gcount();
140 116
             totalRead += numRead;
141  
-            BPCLOG_DEBUG_STRM("read " << numRead << ", totalRead = " << totalRead);
142  
-
  117
+            std::stringstream ss1;
  118
+            ss1 << "read " << numRead << ", totalRead = " << totalRead;
  119
+            bplus::service::Service::log(BP_DEBUG, ss1.str());
143 120
             // write chunk to a file
144  
-            std::stringstream ss;
145  
-            ss << path.filename().string() << "_chunk-" << chunkNumber << "_";
146  
-            boost::filesystem::path p = bp::file::getTempPath(m_tempDir, ss.str());
147  
-            BPCLOG_DEBUG_STRM("chunk file: " << p);
  121
+            std::stringstream ss2;
  122
+            ss2 << path.filename().string() << "_chunk-" << chunkNumber << "_";
  123
+            boost::filesystem::path p = bp::file::getTempPath(m_tempDir, ss2.str());
  124
+            bplus::service::Service::log(BP_DEBUG, "chunk file: " + p.string());
148 125
             std::ofstream ofs;
149  
-            if (!bp::file::openWritableStream(ofs, p, std::ios_base::out
150  
-                                              | std::ios_base::binary)) {
  126
+            if (!bp::file::openWritableStream(ofs, p, std::ios_base::out | std::ios_base::binary)) {
151 127
                 throw std::string("unable to open temp chunk file");
152 128
             }
153 129
             ofs.write(buf, numRead);
@@ -160,7 +136,6 @@ FileServer::getFileChunks(const boost::filesystem::path& path,
160 136
             info.m_chunkNumber = chunkNumber++;
161 137
             rval.push_back(info);
162 138
         }
163  
-
164 139
         for (size_t i = 0; i < rval.size(); i++) {
165 140
             rval[i].m_numberOfChunks = chunkNumber;
166 141
         }
@@ -169,14 +144,11 @@ FileServer::getFileChunks(const boost::filesystem::path& path,
169 144
         throw(e);
170 145
     }
171 146
     delete [] buf;
172  
-    
173 147
     // update usage:
174 148
     m_limit.noteUsage(size / chunkSize, size);
175  
-
176 149
     return rval;
177 150
 }
178 151
 
179  
-#define BUFSIZE (1024 * 8)
180 152
 boost::filesystem::path
181 153
 FileServer::getSlice(const boost::filesystem::path& path,
182 154
                      size_t offset, size_t size)
@@ -254,64 +226,56 @@ FileServer::getSlice(const boost::filesystem::path& path,
254 226
 }
255 227
 
256 228
 void
257  
-FileServer::mongooseCallback(void * connPtr, void * requestPtr,
258  
-                             void * user_data)
259  
-{
260  
-    struct mg_connection * conn = (struct mg_connection *) connPtr;
261  
-    const struct mg_request_info * request = (const struct mg_request_info * ) requestPtr;
262  
-    FileServer * self = (FileServer *) user_data;
263  
-    
  229
+FileServer::mongooseCallback(void* connPtr, void* requestPtr, void* user_data) {
  230
+    struct mg_connection* conn = (struct mg_connection*)connPtr;
  231
+    const struct mg_request_info* request = (const struct mg_request_info*)requestPtr;
  232
+    FileServer* self = (FileServer*)user_data;
264 233
     std::string id(request->uri);
265  
-    BPCLOG_INFO_STRM( "request.url.path = " << id );
  234
+    bplus::service::Service::log(BP_INFO, "request.url.path = " + id);
266 235
     // drop the leading /
267  
-    id = id.substr(1, id.length()-1);
268  
-
269  
-    // if we can find a slash '/', in the url, we'll drop everything
270  
-    // after it.
  236
+    id = id.substr(1, id.length() - 1);
  237
+    // if we can find a slash '/', in the url, we'll drop everything after it.
271 238
     size_t slashLoc = id.find('/');
272 239
     if (slashLoc != std::string::npos) {
273 240
         id = id.substr(0, slashLoc);
274 241
     }
275  
-
276  
-    BPCLOG_INFO_STRM( "token '" << id << "' extracted from request path: "
277  
-                      << request->uri );
278  
-
  242
+    bplus::service::Service::log(BP_INFO, "token '" + id + "' extracted from request path: " + request->uri);
279 243
     boost::filesystem::path path;
280 244
     {
281  
-        bp::sync::Lock lck(self->m_lock);
  245
+        bplus::sync::Lock lck(self->m_lock);
282 246
         std::map<std::string,boost::filesystem::path>::const_iterator it;
283 247
         it = self->m_paths.find(id);
284 248
         if (it == self->m_paths.end()) {
285  
-            BPCLOG_WARN( "Requested id not found." );
  249
+            bplus::service::Service::log(BP_WARN, "Requested id not found.");
286 250
             mg_printf(conn, "HTTP/1.0 404 Not Found\r\n\r\n");
287 251
             return;
288 252
         }
289 253
         path = it->second;
290 254
     }
291  
-    
292  
-
293 255
     // read file and output to connection
294  
-    FILE * f = ft::fopen_binary_read(path.string());
295  
-    if (f == NULL) {
296  
-        BPCLOG_WARN_STRM( "Couldn't open file for reading " << path );
  256
+    std::ifstream ifs;
  257
+    if (!bp::file::openReadableStream(ifs, path.string(), std::ios::binary)) {
  258
+        bplus::service::Service::log(BP_WARN, "Couldn't open file for reading " + path.string());
297 259
         mg_printf(conn, "HTTP/1.0 500 Internal Error\r\n\r\n");
298 260
         return;
299 261
     }
300  
-
301  
-    long len;
302  
-    if (0 != fseek(f, 0, SEEK_END) ||
303  
-        (len = ftell(f)) < 0 ||
304  
-        0 != fseek(f, 0, SEEK_SET))
305  
-    {
306  
-        BPCLOG_WARN_STRM( "Couldn't determine file length: " << path );
  262
+    // get length of file:
  263
+    long len = 0;
  264
+    try {
  265
+        ifs.seekg(0, std::ios::end);
  266
+        len = ifs.tellg();
  267
+        ifs.seekg(0, std::ios::beg);
  268
+    } catch (...) {
  269
+        len = -1;
  270
+    }
  271
+    if (len < 0) {
  272
+        bplus::service::Service::log(BP_WARN, "Couldn't determine file length: " + path.string());
307 273
         mg_printf(conn, "HTTP/1.0 500 Internal Error\r\n\r\n");
308 274
         return;
309 275
     }
310  
-
311 276
     mg_printf(conn, "HTTP/1.0 200 OK\r\n");
312 277
     mg_printf(conn, "Content-Length: %ld\r\n", len);
313 278
     mg_printf(conn, "Server: FileAccess BrowserPlus service\r\n");
314  
-
315 279
     // set mime type header
316 280
     {
317 281
         std::vector<std::string> mts;
@@ -321,17 +285,17 @@ FileServer::mongooseCallback(void * connPtr, void * requestPtr,
321 285
         }
322 286
     }
323 287
     mg_printf(conn, "\r\n");    
324  
-
325 288
     char buf[1024 * 32];
326  
-    size_t rd;
327  
-    while ((rd = fread(buf, sizeof(char), sizeof(buf), f)) > 0) {
  289
+    while (!ifs.eof()) {
  290
+        size_t rd = 0;
  291
+        ifs.read(buf, sizeof(buf));
  292
+        rd = ifs.gcount();
328 293
         if (rd != (size_t) mg_write(conn, buf, rd)) {
329  
-            BPCLOG_WARN( "partial write detected!  client left?" );
330  
-            fclose(f);
  294
+            bplus::service::Service::log(BP_WARN, "partial write detected!  client left?");
  295
+            ifs.close();
331 296
             return;
332 297
         }
333 298
     }
334  
-
335  
-    BPCLOG_DEBUG( "Request processed." );
  299
+    bplus::service::Service::log(BP_DEBUG, "Request processed.");
336 300
     return;
337 301
 }
41  src/FileServer.h
@@ -5,60 +5,47 @@
5 5
  *  (c) 2008 Yahoo! inc.
6 6
  */
7 7
 
8  
-#ifndef __FILE_SERVER_H__
9  
-#define __FILE_SERVER_H__
  8
+#ifndef __FILESERVER_H__
  9
+#define __FILESERVER_H__
10 10
 
11 11
 #include "bp-file/bpfile.h"
12  
-#include "util/bpsync.hh"
13  
-
  12
+#include "bputil/bpsync.h"
14 13
 #include "ResourceLimit.h"
15  
-
16 14
 #include <string>
17 15
 #include <vector>
18 16
 #include <map>
19 17
 
20  
-class ChunkInfo
21  
-{
22  
- public:
  18
+class ChunkInfo {
  19
+public:
23 20
     boost::filesystem::path m_path;
24 21
     size_t m_chunkNumber;
25 22
     size_t m_numberOfChunks;
26 23
 };
27 24
 
28  
-class FileServer
29  
-{
30  
-  public:
  25
+class FileServer {
  26
+public:
31 27
     FileServer(const boost::filesystem::path& tempDir);
32 28
     ~FileServer();
33  
-
34 29
     /* start the server, returns host/port when bound, otherwise returns
35 30
      * .empty() on error */     
36 31
     std::string start();
37  
-
38 32
     /* add a file to the server, returning a url, .empty() on error */ 
39 33
     std::string addFile(const boost::filesystem::path& path);
40  
-
41 34
     /* add a chunked file to the server, returning a vector of 
42 35
      * ChunkInfo (empty on error)
43 36
      */
44  
-    std::vector<ChunkInfo> getFileChunks(const boost::filesystem::path& path,
45  
-                                         size_t chunkSize);
46  
-
  37
+    std::vector<ChunkInfo> getFileChunks(const boost::filesystem::path& path, size_t chunkSize);
47 38
     /* get a slice of a file */
48  
-    boost::filesystem::path getSlice(const boost::filesystem::path& path,
49  
-                                     size_t offset, size_t size);
50  
-
51  
-  private:
52  
-
53  
-    static void mongooseCallback(void * connPtr, void * requestPtr,
54  
-                                 void * user_data);
55  
-
  39
+    boost::filesystem::path getSlice(const boost::filesystem::path& path, size_t offset, size_t size);
  40
+private:
  41
+    static void mongooseCallback(void* connPtr, void* requestPtr, void* user_data);
  42
+private:
56 43
     unsigned short int m_port;
57 44
     std::map<std::string, boost::filesystem::path> m_paths;
58 45
     boost::filesystem::path m_tempDir;
59 46
     ResourceLimit m_limit;
60  
-    void * m_ctx;
61  
-    bp::sync::Mutex m_lock;
  47
+    void* m_ctx;
  48
+    bplus::sync::Mutex m_lock;
62 49
 };
63 50
 
64 51
 #endif
28  src/ResourceLimit.h
@@ -7,27 +7,27 @@
7 7
 #ifndef __RESOURCE_LIMIT_H__
8 8
 #define __RESOURCE_LIMIT_H__
9 9
 
10  
-class ResourceLimit 
11  
-{
  10
+class ResourceLimit {
12 11
 public:
13 12
     ResourceLimit(size_t fileLimit, size_t byteLimit) :
14  
-        m_fileLimit(fileLimit), m_byteLimit(byteLimit),
15  
-        m_filesUsed(0), m_bytesUsed(0) { };    
16  
-    
17  
-    bool wouldExceed(size_t files, size_t bytes)
18  
-    {
19  
-        if (m_filesUsed + files > m_fileLimit) return true;
20  
-        if (m_bytesUsed + bytes > m_byteLimit) return true;
  13
+        m_fileLimit(fileLimit),
  14
+        m_byteLimit(byteLimit),
  15
+        m_filesUsed(0),
  16
+        m_bytesUsed(0) {
  17
+    }
  18
+    bool wouldExceed(size_t files, size_t bytes) {
  19
+        if (m_filesUsed + files > m_fileLimit) {
  20
+            return true;
  21
+        }
  22
+        if (m_bytesUsed + bytes > m_byteLimit) {
  23
+            return true;
  24
+        }
21 25
         return false;
22 26
     }
23  
-    
24  
-
25  
-    void noteUsage(size_t files, size_t bytes)
26  
-    {
  27
+    void noteUsage(size_t files, size_t bytes) {
27 28
         m_filesUsed += files;
28 29
         m_bytesUsed += bytes;
29 30
     }
30  
-    
31 31
 private:
32 32
     size_t m_fileLimit, m_byteLimit;
33 33
     size_t m_filesUsed, m_bytesUsed;
30  src/littleuuid.cpp
... ...
@@ -1,30 +0,0 @@
1  
-#include "littleuuid.h"
2  
-
3  
-#ifdef WIN32
4  
-#include <Rpc.h>
5  
-#else 
6  
-#include <uuid/uuid.h>
7  
-#endif
8  
-
9  
-bool uuid_generate( std::string & sUuid )
10  
-{
11  
-#ifdef WIN32
12  
-    UUID uuid;
13  
-    if (UuidCreate( &uuid ) != RPC_S_OK)
14  
-        return false;
15  
-    unsigned char* pch = NULL;
16  
-    if (UuidToStringA( &uuid, &pch ) != RPC_S_OK)
17  
-        return false;
18  
-    if (pch)
19  
-        sUuid = reinterpret_cast<char*>(pch);
20  
-    RpcStringFreeA( &pch );
21  
-    return true;
22  
-#else
23  
-    uuid_t uuid;
24  
-    uuid_generate( uuid );
25  
-    char szUuid[37];
26  
-    uuid_unparse( uuid, szUuid );
27  
-    sUuid = szUuid;
28  
-    return true;
29  
-#endif
30  
-}
8  src/littleuuid.h
... ...
@@ -1,6 +1,8 @@
1  
-#include <string>
2  
-
3 1
 #ifndef __LITTLE_UUID_H__
4 2
 #define __LITTLE_UUID_H__
5  
-bool uuid_generate( std::string & sUuid );
  3
+
  4
+#include <string>
  5
+
  6
+bool uuid_generate(std::string& sUuid);
  7
+
6 8
 #endif
13  src/littleuuid_Darwin.cpp
... ...
@@ -0,0 +1,13 @@
  1
+#include "littleuuid.h"
  2
+
  3
+#include <uuid/uuid.h>
  4
+
  5
+bool
  6
+uuid_generate(std::string& sUuid) {
  7
+    uuid_t uuid;
  8
+    char szUuid[37];
  9
+    uuid_generate(uuid);
  10
+    uuid_unparse(uuid, szUuid);
  11
+    sUuid = szUuid;
  12
+    return true;
  13
+}
20  src/littleuuid_Windows.cpp
... ...
@@ -0,0 +1,20 @@
  1
+#include "littleuuid.h"
  2
+
  3
+#include <Rpc.h>
  4
+
  5
+bool
  6
+uuid_generate(std::string& sUuid) {
  7
+    UUID uuid;
  8
+    unsigned char* pch = NULL;
  9
+    if (UuidCreate(&uuid) != RPC_S_OK) {
  10
+        return false;
  11
+    }
  12
+    if (UuidToStringA(&uuid, &pch) != RPC_S_OK) {
  13
+        return false;
  14
+    }
  15
+    if (pch) {
  16
+        sUuid = reinterpret_cast<char*>(pch);
  17
+    }
  18
+    RpcStringFreeA(&pch);
  19
+    return true;
  20
+}
554  src/service.cpp
... ...
@@ -1,15 +1,7 @@
1  
-#include <ServiceAPI/bperror.h>
2  
-#include <ServiceAPI/bptypes.h>
3  
-#include <ServiceAPI/bpdefinition.h>
4  
-#include <ServiceAPI/bpcfunctions.h>
5  
-#include <ServiceAPI/bppfunctions.h>
6  
-
  1
+#include "bpservice/bpservice.h"
  2
+#include "bpservice/bpcallback.h"
7 3
 #include "FileServer.h"
8  
-#include "service.h"
9  
-#include "bptypeutil.hh"
10  
-#include "bpurlutil.hh"
11 4
 #include "base64.h"
12  
-
13 5
 #include <stdio.h>
14 6
 #include <stdlib.h>
15 7
 #include <assert.h>
@@ -20,370 +12,288 @@
20 12
 
21 13
 // 2mb is default chunk size
22 14
 #define FA_CHUNK_SIZE (1<<21)
  15
+class FileAccess : public bplus::service::Service {
  16
+public:
  17
+BP_SERVICE(FileAccess)
  18
+    FileAccess();
  19
+    ~FileAccess();
  20
+    virtual void finalConstruct();
  21
+    void read(const bplus::service::Transaction& tran, const bplus::Map& args);
  22
+    void readBase64(const bplus::service::Transaction& tran, const bplus::Map& args);
  23
+    void slice(const bplus::service::Transaction& tran, const bplus::Map& args);
  24
+    void getURL(const bplus::service::Transaction& tran, const bplus::Map& args);
  25
+    void chunk(const bplus::service::Transaction& tran, const bplus::Map& args);
  26
+private:
  27
+    void readImpl(const bplus::service::Transaction& tran, const bplus::Map& args, bool base64);
  28
+    bool hasEmbeddedNulls(unsigned char* bytes, unsigned int len);
  29
+    bplus::String* readFileContents(const boost::filesystem::path& path, unsigned int offset, int size, bool base64, std::string& err);
  30
+private:
  31
+    FileServer* m_fs;
  32
+};
  33
+
  34
+BP_SERVICE_DESC(FileAccess, "FileAccess", "2.1.0",
  35
+                "Access the contents of files that the user has selected.")
  36
+ADD_BP_METHOD(FileAccess, read,
  37
+              "Read the contents of a file on disk returning a string.  "
  38
+              "If the file contains binary data an error will be returned.")
  39
+ADD_BP_METHOD_ARG(read, "file", Path, true,
  40
+                  "The input file to operate on.")
  41
+ADD_BP_METHOD_ARG(read, "offset", Integer, false,
  42
+                  "The beginning byte offset.")
  43
+ADD_BP_METHOD_ARG(read, "size", Integer, false,
  44
+                  "The amount of data.")
  45
+ADD_BP_METHOD(FileAccess, readBase64,
  46
+              "Read the contents of a file on disk returning a base64 encoded string.  "
  47
+              "Since the return is base64 encoded, it will be 4/3 times the size of the request.")
  48
+ADD_BP_METHOD_ARG(readBase64, "file", Path, true,
  49
+                  "The input file to operate on.")
  50
+ADD_BP_METHOD_ARG(readBase64, "offset", Integer, false,
  51
+                  "The beginning byte offset.")
  52
+ADD_BP_METHOD_ARG(readBase64, "size", Integer, false,
  53
+                  "The amount of data.")
  54
+ADD_BP_METHOD(FileAccess, slice,
  55
+              "Given a file and an optional offset and size, return a new "
  56
+              "file whose contents are a subset of the first.")
  57
+ADD_BP_METHOD_ARG(slice, "file", Path, true,
  58
+                  "The input file to operate on.")
  59
+ADD_BP_METHOD_ARG(slice, "offset", Integer, false,
  60
+                  "The beginning byte offset.")
  61
+ADD_BP_METHOD_ARG(slice, "size", Integer, false,
  62
+                  "The amount of data.")
  63
+ADD_BP_METHOD(FileAccess, getURL,
  64
+              "Get a localhost url that can be used to attain the full contents"
  65
+              " of a file on disk.  The URL will be of the form "
  66
+              "http://127.0.0.1:<port>/<uuid> -- The port will be an ephemerally "
  67
+              "bound port, the uuid will be a traditional GUID.  When a local "
  68
+              "client accesses the URL, the FileAccess service will ignore any "
  69
+              "appended pathing (i.e. for http://127.0.0.1:<port>/<uuid>/foo.tar.gz,"
  70
+              " '/foo.tar.gz' will be ignored).  This allows client code to supply "
  71
+              "a filename when triggering a browser supplied 'save as' dialog.")
  72
+ADD_BP_METHOD_ARG(getURL, "file", Path, true,
  73
+                  "The file that you would like to read via a localhost url.")
  74
+ADD_BP_METHOD(FileAccess, chunk,
  75
+              "Get a vector of objects that result from chunking a file. "
  76
+              "The return value will be an ordered list of file handles with each "
  77
+              "successive file representing a different chunk")
  78
+ADD_BP_METHOD_ARG(chunk, "file", Path, true,
  79
+                  "The file that you would like to chunk.")
  80
+ADD_BP_METHOD_ARG(chunk, "chunkSize", Integer, false,
  81
+                  "The desired chunk size, not to exceed 2MB.  Default is 2MB.")
  82
+END_BP_SERVICE_DESC
  83
+
  84
+FileAccess::FileAccess() : bplus::service::Service(),
  85
+    m_fs(NULL) {
  86
+}
23 87
 
24  
-const BPCFunctionTable * g_bpCoreFunctions = NULL;
  88
+FileAccess::~FileAccess() {
  89
+    assert(m_fs != NULL);
  90
+    if (m_fs != NULL) {
  91
+        delete m_fs;
  92
+        m_fs = NULL;
  93
+    }
  94
+}
25 95
 
26  
-static int
27  
-BPPAllocate(void ** instance, unsigned int, const BPElement * elem)
28  
-{
29  
-    boost::filesystem::path tempDir;
30  
-    bp::Object * args = bp::Object::build(elem);
31  
-    if (args->has("temp_dir", BPTString)) {
32  
-        tempDir = (std::string)(*(args->get("temp_dir")));
33  
-    } else {
34  
-        g_bpCoreFunctions->log(BP_ERROR,
35  
-                               "(FileAccess) allocated (NO 'temp_dir' key)");
  96
+void
  97
+FileAccess::finalConstruct() {
  98
+    bplus::service::Service::finalConstruct();
  99
+    bplus::tPathString tmpDir = tempDir();
  100
+    if (tmpDir.empty()) {
  101
+        log(BP_ERROR, "(FileAccess) allocated (NO 'temp_dir' key)");
  102
+    }
  103
+    boost::filesystem::path tempDir = boost::filesystem::path(tmpDir);
  104
+    m_fs = new FileServer(tempDir);
  105
+    assert(m_fs != NULL);
  106
+    m_fs->start();
  107
+}
  108
+
  109
+void
  110
+FileAccess::read(const bplus::service::Transaction& tran, const bplus::Map& args) {
  111
+    readImpl(tran, args, false);
  112
+}
  113
+
  114
+void
  115
+FileAccess::readBase64(const bplus::service::Transaction& tran, const bplus::Map& args) {
  116
+    readImpl(tran, args, true);
  117
+}
  118
+
  119
+void
  120
+FileAccess::slice(const bplus::service::Transaction& tran, const bplus::Map& args) {
  121
+    // dig out args
  122
+    const bplus::Path* bpPath = dynamic_cast<const bplus::Path*>(args.value("file"));
  123
+    if (!bpPath) {
  124
+        tran.error("bp.fileAccessError", "invalid file path");
36 125
     }
  126
+    boost::filesystem::path path((bplus::tPathString)*bpPath);
  127
+    log(BP_INFO, "slice");
  128
+    size_t offset = 0, size = (size_t) -1;
  129
+    if (args.has("offset", BPTInteger)) {
  130
+        offset = (int)(long long)*(args.get("offset"));            
  131
+    }
  132
+    if (args.has("size", BPTInteger)) {
  133
+        size = (int)(long long)*(args.get("size"));            
  134
+    }
  135
+    std::string err;
  136
+    try {
  137
+        boost::filesystem::path s = m_fs->getSlice(path, offset, size);
  138
+        tran.complete(bplus::Path(bp::file::nativeString(s)));
  139
+    } catch (const std::string& e) {
  140
+        tran.error("bp.fileAccessError", e.c_str());
  141
+    }
  142
+}
37 143
 
38  
-    FileServer * fs = new FileServer(tempDir);
39  
-    fs->start();
40  
-    *instance = (void *) fs;
41  
-    assert(*instance != NULL);
42  
-    return 0;
  144
+void
  145
+FileAccess::getURL(const bplus::service::Transaction& tran, const bplus::Map& args) {
  146
+    // dig out args
  147
+    const bplus::Path* bpPath = dynamic_cast<const bplus::Path*>(args.value("file"));
  148
+    if (!bpPath) {
  149
+        tran.error("bp.fileAccessError", "invalid file path");
  150
+    }
  151
+    boost::filesystem::path path((bplus::tPathString)*bpPath);
  152
+    log(BP_INFO, "getURL");
  153
+    std::string url = m_fs->addFile(path);
  154
+    if (url.empty()) {
  155
+        tran.error("bp.fileAccessError", NULL);
  156
+    } else {
  157
+        tran.complete(bplus::String(url));
  158
+    }
43 159
 }
44 160
 
45  
-static void
46  
-BPPDestroy(void * instance)
47  
-{
48  
-    assert(instance != NULL);
49  
-    delete (FileServer *) instance;
  161
+void
  162
+FileAccess::chunk(const bplus::service::Transaction& tran, const bplus::Map& args) {
  163
+    // dig out args
  164
+    const bplus::Path* bpPath = dynamic_cast<const bplus::Path*>(args.value("file"));
  165
+    if (!bpPath) {
  166
+        tran.error("bp.fileAccessError", "invalid file path");
  167
+    }
  168
+    boost::filesystem::path path((bplus::tPathString)*bpPath);
  169
+    log(BP_INFO, "chunk");
  170
+    size_t chunkSize = FA_CHUNK_SIZE;
  171
+    if (args.has("chunkSize", BPTInteger)) {
  172
+        chunkSize = (size_t)(long long)*(args.get("chunkSize"));            
  173
+    }
  174
+    std::vector<ChunkInfo> v;
  175
+    std::string err;
  176
+    try {
  177
+        v = m_fs->getFileChunks(path, chunkSize);
  178
+    } catch (const std::string& e) {
  179
+        err = e;
  180
+        v.clear();
  181
+    }
  182
+    if (v.empty()) {
  183
+        tran.error("bp.fileAccessError", err.c_str());
  184
+    } else {
  185
+        bplus::List* l = new bplus::List;
  186
+        for (size_t i = 0; i < v.size(); i++) {
  187
+            l->append(new bplus::Path(bp::file::nativeString(v[i].m_path)));
  188
+        }
  189
+        tran.complete(*l);
  190
+    }
50 191
 }
51 192
 
52  
-static void
53  
-BPPShutdown(void)
54  
-{
  193
+void
  194
+FileAccess::readImpl(const bplus::service::Transaction& tran, const bplus::Map& args, bool base64) {
  195
+    // dig out args
  196
+    const bplus::Path* bpPath = dynamic_cast<const bplus::Path*>(args.value("file"));
  197
+    if (!bpPath) {
  198
+        tran.error("bp.fileAccessError", "invalid file path");
  199
+    }
  200
+    boost::filesystem::path path((bplus::tPathString)*bpPath);
  201
+    log(BP_INFO, base64 ? "readBase64" : "read");
  202
+    unsigned int offset = 0;
  203
+    int size = -1;
  204
+    if (args.has("offset", BPTInteger)) {
  205
+        offset = (int) (long long) *(args.get("offset"));            
  206
+    }
  207
+    if (args.has("size", BPTInteger)) {
  208
+        size = (int) (long long) *(args.get("size"));            
  209
+    }
  210
+    bplus::String* contents = NULL;
  211
+    std::string err;
  212
+    contents = readFileContents(path, offset, size, base64, err);
  213
+    if (!err.empty() || contents == NULL) {
  214
+        tran.error("bp.fileAccessError", err.c_str());
  215
+    } else {
  216
+        tran.complete(*contents);
  217
+    }
  218
+    if (contents) {
  219
+        delete contents;
  220
+    }
55 221
 }
56 222
 
57  
-static bool
58  
-hasEmbeddedNulls(unsigned char * bytes, unsigned int len)
59  
-{
60  
-    for (unsigned int i = 0; i < len; i++) if (bytes[i] == 0) return true;
  223
+bool
  224
+FileAccess::hasEmbeddedNulls(unsigned char * bytes, unsigned int len) {
  225
+    for (unsigned int i = 0; i < len; i++) {
  226
+        if (bytes[i] == 0) {
  227
+            return true;
  228
+        }
  229
+    }
61 230
     return false;
62 231
 }
63 232
 
64  
-static bp::String *
65  
-readFileContents(const boost::filesystem::path & path,
66  
-                 unsigned int offset, int size,
67  
-                 bool base64,
68  
-                 std::string & err)
69  
-{
  233
+bplus::String*
  234
+FileAccess::readFileContents(const boost::filesystem::path& path, unsigned int offset, int size, bool base64, std::string& err) {
70 235
     std::ifstream fstream;
71  
-
72 236
     // verify size is reasonable
73 237
     if (size > FA_MAX_READ) {
74 238
         err = "size too large, greater than 2mb limit";
75 239
         return NULL;
76 240
     }
77  
-
78 241
     // set to 2mb if 
79  
-    if (size < 0) size = FA_MAX_READ;
80  
-
  242
+    if (size < 0) {
  243
+        size = FA_MAX_READ;
  244
+    }
81 245
     // verify file exists and open
82  
-    if (!bp::file::openReadableStream(
83  
-            fstream, path, std::ios_base::in | std::ios_base::binary))
84  
-    {
  246
+    if (!bp::file::openReadableStream(fstream, path, std::ios_base::in | std::ios_base::binary)) {
85 247
         err = "cannot open file for reading";
86 248
         return NULL;
87 249
     }
88  
-
89 250
     // now validate offset and size
90  
-    fstream.seekg (0, std::ios::end);
91  
-    if ((size_t) offset > fstream.tellg()) {
  251
+    fstream.seekg(0, std::ios::end);
  252
+    if ((size_t)offset > fstream.tellg()) {
92 253
         err = "offset out of range";        
93 254
         return NULL;
94 255
     }
95 256
     // now set size to exact amount required
96 257
     {
97 258
         int avail = ((int)fstream.tellg() - (int)offset);
98  
-        if (avail < size) size = avail;
  259
+        if (avail < size) {
  260
+            size = avail;
  261
+        }
99 262
     }
100  
-    
101  
-    fstream.seekg (offset, std::ios::beg);
102  
-
  263
+    fstream.seekg(offset, std::ios::beg);
103 264
     // allocate memory:1
104  
-    unsigned char * buffer = new unsigned char [size];
105  
-    bp::String * s = NULL;
106  
-
  265
+    unsigned char* buffer = new unsigned char[size];
  266
+    bplus::String* s = NULL;
107 267
     if (base64) {
108 268
         std::stringstream ss;
109 269
         Base64 b64;
110 270
         b64.encode(fstream, size, ss);
111 271
         // encode into a js literal
112  
-        s = new bp::String(ss.str().c_str(), (unsigned int) ss.str().length());
  272
+        s = new bplus::String(ss.str().c_str(), (unsigned int) ss.str().length());
113 273
     } else {
114 274
         // read data
115  
-        fstream.read ((char *) buffer, size);
  275
+        fstream.read((char*)buffer, size);
116 276
         if (fstream.gcount() > 0) {
117 277
             // no support for "binary data" --> embedded nulls
118  
-            if (hasEmbeddedNulls(buffer, (unsigned int) fstream.gcount())) {
119  
-                delete [] buffer;            
  278
+            if (hasEmbeddedNulls(buffer, (unsigned int)fstream.gcount())) {
  279
+                delete [] buffer;
120 280
                 err = "binary data not supported";
121  
-                return NULL; 
  281
+                return NULL;
122 282
             }
123 283
             // encode into a js literal
124  
-            s = new bp::String((char *) buffer, (unsigned int) fstream.gcount());
  284
+            s = new bplus::String((char*) buffer, (unsigned int)fstream.gcount());
125 285
         } else {
126  
-            s = new bp::String("", 0);
  286
+            s = new bplus::String("", 0);
127 287
         }
128 288
     }
129  
-
130 289
     fstream.close();
131  
-    
132  
-    delete [] buffer;
133  
-
  290
+    delete []buffer;
134 291
     if (fstream.fail()) {
135 292
         err = "read error";
136  
-        if (s) delete s;
  293
+        if (s) {
  294
+            delete s;
  295
+        }
137 296
         s = NULL;
138 297
     }
139  
-    
140 298
     return s;
141 299
 }
142  
-
143  
-static void
144  
-BPPInvoke(void * instance, const char * funcName,
145  
-          unsigned int tid, const BPElement * elem)
146  
-{
147  
-    bp::Object * args = NULL;
148  
-    if (elem) args = bp::Object::build(elem);
149  
-
150  
-    // all functions have a "file" argument, validate we can parse it
151  
-    std::string url = (*(args->get("file")));
152  
-    std::string pathString = bp::urlutil::pathFromURL(url);
153  
-
154  
-    if (pathString.empty())
155  
-    {
156  
-        g_bpCoreFunctions->postError(tid, "bp.fileAccessError",
157  
-                                     "invalid file URI");
158  
-        if (args) delete args;
159  
-        return;
160  
-    }
161  
-
162  
-    boost::filesystem::path path(pathString);
163  
-    
164  
-    if (!strcmp(funcName, "read") || !strcmp(funcName, "readBase64"))
165  
-    {
166  
-        bool base64 = !strcmp(funcName, "readBase64");
167  
-        BPCLOG_INFO( base64 ? "readBas64" : "read" );
168  
-        
169  
-        unsigned int offset = 0;
170  
-        int size = -1;
171  
-        if (args->has("offset", BPTInteger)) {
172  
-            offset = (int) (long long) *(args->get("offset"));            
173  
-        }
174  
-        if (args->has("size", BPTInteger)) {
175  
-            size = (int) (long long) *(args->get("size"));            
176  
-        }
177  
-
178  
-        bp::String * contents = NULL;
179  
-        std::string err;
180  
-        contents = readFileContents(path, offset, size, base64, err);
181  
-
182  
-        if (!err.empty()) {
183  
-            g_bpCoreFunctions->postError(tid, "bp.fileAccessError",
184  
-                                         err.c_str());
185  
-        } else {
186  
-            g_bpCoreFunctions->postResults(tid, contents->elemPtr());
187  
-        }
188  
-        if (contents) delete contents;
189  
-    }
190  
-    else if (!strcmp(funcName, "getURL"))
191  
-    {
192  
-        BPCLOG_INFO( "getURL" );
193  
-        
194  
-        FileServer * fs = (FileServer *) instance;
195  
-
196  
-        std::string url = fs->addFile(path);
197  
-
198  
-        if (url.empty()) {
199  
-            g_bpCoreFunctions->postError(tid, "bp.fileAccessError", NULL);
200  
-        } else {
201  
-            g_bpCoreFunctions->postResults(tid, bp::String(url).elemPtr());
202  
-        }
203  
-    }
204  
-    else if (!strcmp(funcName, "chunk"))
205  
-    {
206  
-        BPCLOG_INFO( "chunk" );
207  
-        
208  
-        size_t chunkSize = FA_CHUNK_SIZE;
209  
-        if (args->has("chunkSize", BPTInteger)) {
210  
-            chunkSize = (size_t) (long long) *(args->get("chunkSize"));            
211  
-        }
212  
-
213  
-        FileServer * fs = (FileServer *) instance;
214  
-
215  
-        std::vector<ChunkInfo> v;
216  
-        std::string err;
217  
-        try {
218  
-            v = fs->getFileChunks(path, chunkSize);
219  
-        } catch (const std::string& e) {
220  
-            err = e;
221  
-            v.clear();
222  
-        }
223  
-
224  
-        if (v.empty()) {
225  
-            g_bpCoreFunctions->postError(tid, "bp.fileAccessError", err.c_str());
226  
-        } else {
227  
-            bp::List* l = new bp::List;
228  
-            for (size_t i = 0; i < v.size(); i++) {
229  
-                l->append(new bp::Path(bp::file::nativeUtf8String(v[i].m_path)));
230  
-            }
231  
-            g_bpCoreFunctions->postResults(tid, l->elemPtr());
232  
-        }
233  
-    }
234  
-    else if (!strcmp(funcName, "slice"))
235  
-    {
236  
-        BPCLOG_INFO( "slice" );
237  
-        size_t offset = 0, size = (size_t) -1;
238  
-
239  
-        if (args->has("offset", BPTInteger)) {
240  
-            offset = (int) (long long) *(args->get("offset"));            
241  
-        }
242  
-        if (args->has("size", BPTInteger)) {
243  
-            size = (int) (long long) *(args->get("size"));            
244  
-        }
245  
-
246  
-        FileServer * fs = (FileServer *) instance;
247  
-
248  
-        std::string err;
249  
-        try {
250  
-            boost::filesystem::path s = fs->getSlice(path, offset, size);
251  
-            g_bpCoreFunctions->postResults(tid, bp::Path(bp::file::nativeUtf8String(s)).elemPtr());
252  
-        } catch (const std::string& e) {
253  
-            g_bpCoreFunctions->postError(tid, "bp.fileAccessError", e.c_str());
254  
-        }
255  
-    }
256  
-
257  
-    // platform ensures that one of the above functions is invoked
258  
-    if (args) delete args;
259  
-
260  
-    return;
261  
-}
262  
-
263  
-/* here is the definition of the corelet interface */
264  
-BPArgumentDefinition s_readFileArgs[] = {
265  
-    {
266  
-        (BPString) "file",
267  
-        (BPString) "The input file to operate on.",
268  
-        BPTPath,
269  
-        BP_TRUE
270  
-    },
271  
-    {
272  
-        (BPString) "offset",
273  
-        (BPString) "The beginning byte offset.",
274  
-        BPTInteger,
275  
-        BP_FALSE
276  
-    },
277  
-    {
278  
-        (BPString) "size",
279  
-        (BPString) "The amount of data.",
280  
-        BPTInteger,
281  
-        BP_FALSE
282  
-    }
283  
-};
284  
-
285  
-/* here is the definition of the corelet interface */
286  
-BPArgumentDefinition s_getURLArgs[] = {
287  
-    {
288  
-        (BPString) "file",
289  
-        (BPString) "The file that you would like to read via a localhost url.",
290  
-        BPTPath,
291  
-        BP_TRUE
292  
-    }
293  
-};
294  
-
295  
-BPArgumentDefinition s_getFileChunksArgs[] = {
296  
-    {
297  
-        (BPString) "file",
298  
-        (BPString) "The file that you would like to chunk.",
299  
-        BPTPath,
300  
-        BP_TRUE
301  
-    },
302  
-    {  
303  
-        (BPString) "chunkSize",
304  
-        (BPString) "The desired chunk size, not to exceed 2MB.  Default is 2MB.",
305  
-        BPTInteger,
306  
-        BP_FALSE
307  
-    }
308  
-};
309  
-
310  
-BPFunctionDefinition s_functions[] = {
311  
-    {
312  
-        (BPString) "read",
313  
-        (BPString) "Read the contents of a file on disk returning a string.  "
314  
-        "If the file contains binary data an error will be returned.",
315  
-        sizeof(s_readFileArgs)/sizeof(s_readFileArgs[0]),
316  
-        s_readFileArgs
317  
-    },
318  
-    {
319  
-        // Note that readBase64 has same args as read
320  
-        (BPString) "readBase64",
321  
-        (BPString) "Read the contents of a file on disk returning a base64 encoded string.  "
322  
-        "Since the return is base64 encoded, it will be 4/3 times the size of the request.",
323  
-        sizeof(s_readFileArgs)/sizeof(s_readFileArgs[0]),
324  
-        s_readFileArgs
325  
-    },
326  
-    {
327  
-        (BPString) "slice",
328  
-        (BPString) "Given a file and an optional offset and size, return a new "
329  
-        "file whose contents are a subset of the first.",
330  
-        sizeof(s_readFileArgs)/sizeof(s_readFileArgs[0]),
331  
-        s_readFileArgs
332  
-    },
333  
-    {
334  
-        (BPString) "getURL",
335  
-        (BPString) "Get a localhost url that can be used to attain the full contents"
336  
-        " of a file on disk.  The URL will be of the form "
337  
-        "http://127.0.0.1:<port>/<uuid> -- The port will be an ephemerally "
338  
-        "bound port, the uuid will be a traditional GUID.  When a local "
339  
-        "client accesses the URL, the FileAccess service will ignore any "
340  
-        "appended pathing (i.e. for http://127.0.0.1:<port>/<uuid>/foo.tar.gz,"
341  
-        " '/foo.tar.gz' will be ignored).  This allows client code to supply "
342  
-        "a filename when triggering a browser supplied 'save as' dialog.",
343  
-        sizeof(s_getURLArgs)/sizeof(s_getURLArgs[0]),
344  
-        s_getURLArgs
345  
-    },
346  
-    {
347  
-        (BPString) "chunk",
348  
-        (BPString) "Get a vector of objects that result from chunking a file. "
349  
-        "The return value will be an ordered list of file handles with each "
350  
-        "successive file representing a different chunk",
351  
-        sizeof(s_getFileChunksArgs)/sizeof(s_getFileChunksArgs[0]),
352  
-        s_getFileChunksArgs
353  
-    }
354  
-};
355  
-
356  
-// a description of this corelet.
357  
-BPCoreletDefinition s_coreletDef = {
358  
-    (BPString) "FileAccess",
359  
-    2, 0, 4,
360  
-    (BPString) "Access the contents of files that the user has selected.",
361  
-    sizeof(s_functions)/sizeof(s_functions[0]),
362  
-    s_functions
363  
-};
364  
-
365  
-const BPCoreletDefinition *
366  
-BPPInitialize(const BPCFunctionTable * bpCoreFunctions,
367  
-              const BPElement * parameterMap)
368  
-{
369  
-    g_bpCoreFunctions = bpCoreFunctions;
370  
-    return &s_coreletDef;
371  
-}
372  
-
373  
-/** and finally, declare the entry point to the corelet */
374  
-BPPFunctionTable funcTable = {
375  
-    BPP_CORELET_API_VERSION,
376  
-    BPPInitialize,
377  
-    BPPShutdown,
378  
-    BPPAllocate,
379  
-    BPPDestroy,
380  
-    BPPInvoke,
381  
-    NULL,
382  
-    NULL
383  
-};
384  
-
385  
-const BPPFunctionTable *
386  
-BPPGetEntryPoints(void)
387  
-{
388  
-    return &funcTable;
389  
-}
32  src/service.h
... ...
@@ -1,32 +0,0 @@
1  
-#ifndef __CORELET_H__
2  
-#define __CORELET_H__
3  
-
4  
-#include <ServiceAPI/bpcfunctions.h>
5  
-
6  
-#include <sstream>
7  
-
8  
-extern const BPCFunctionTable * g_bpCoreFunctions;
9  
-
10  
-#define BPCLOG_LEVEL( level, message ) \
11  
-    g_bpCoreFunctions->log( level, (message) );
12  
-
13  
-#define BPCLOG_FATAL( message ) BPCLOG_LEVEL( BP_FATAL, message )
14  
-#define BPCLOG_ERROR( message ) BPCLOG_LEVEL( BP_ERROR, message )
15  
-#define BPCLOG_WARN( message ) BPCLOG_LEVEL( BP_WARN, message )
16  
-#define BPCLOG_INFO( message ) BPCLOG_LEVEL( BP_INFO, message )
17  
-#define BPCLOG_DEBUG( message ) BPCLOG_LEVEL( BP_DEBUG, message )
18  
-
19  
-#define BPCLOG_LEVEL_STRM( level, x ) \
20  
-{ \
21  
-    std::stringstream ss; \
22  
-    ss << x; \
23  
-    BPCLOG_LEVEL( level, ss.str().c_str() ); \
24  
-}
25  
-
26  
-#define BPCLOG_FATAL_STRM( x ) BPCLOG_LEVEL_STRM( BP_FATAL, x )
27  
-#define BPCLOG_ERROR_STRM( x ) BPCLOG_LEVEL_STRM( BP_ERROR, x )
28  
-#define BPCLOG_WARN_STRM( x ) BPCLOG_LEVEL_STRM( BP_WARN, x )
29  
-#define BPCLOG_INFO_STRM( x ) BPCLOG_LEVEL_STRM( BP_INFO, x )
30  
-#define BPCLOG_DEBUG_STRM( x ) BPCLOG_LEVEL_STRM( BP_DEBUG, x )
31  
-
32  
-#endif
86  src/util/bpsync.hh
... ...
@@ -1,86 +0,0 @@
1  
-/**
2  
- * ***** BEGIN LICENSE BLOCK *****
3  
- * The contents of this file are subject to the Mozilla Public License
4  
- * Version 1.1 (the "License"); you may not use this file except in
5  
- * compliance with the License. You may obtain a copy of the License at
6  
- * http://www.mozilla.org/MPL/
7  
- * 
8  
- * Software distributed under the License is distributed on an "AS IS"
9  
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
10  
- * License for the specific language governing rights and limitations
11  
- * under the License.
12  
- * 
13  
- * The Original Code is BrowserPlus (tm).
14  
- * 
15  
- * The Initial Developer of the Original Code is Yahoo!.
16  
- * Portions created by Yahoo! are Copyright (C) 2006-2009 Yahoo!.
17  
- * All Rights Reserved.
18  
- * 
19  
- * Contributor(s): 
20  
- * ***** END LICENSE BLOCK *****
21  
- */
22  
-
23  
-/*
24  
- *  bpsync.h
25  
- *
26  
- *  Lightweight cross-platform abstractions of synchronization primitives,
27  
- *  in the POSIX style.
28  
- *
29  
- *  Created by Lloyd Hilaiel on 8/1/07.
30  
- */
31  
-
32  
-#ifndef __BPSYNC_H__
33  
-#define __BPSYNC_H__
34  
-
35  
-namespace bp { 
36  
-namespace sync {
37  
-    /** a posix style non-recursive mutual exclusion device */
38  
-    class Mutex {
39  
-      public:
40  
-        Mutex();
41  
-        ~Mutex();
42  
-        void lock();
43  
-        void unlock();
44  
-      private:
45  
-        void * m_osDep;
46  
-        friend class Condition;
47  
-    };
48  
-
49  
-    /** standard lock for exception-safe Mutex usage */
50  
-    class Lock {
51  
-      public:
52  
-        Lock(Mutex& mutex) : m_mutex( mutex ) { m_mutex.lock(); }
53  
-        ~Lock() { m_mutex.unlock(); }
54  
-      private:
55  
-        Mutex & m_mutex;
56  
-        Lock(const Lock &);             // prevent copy construct
57  
-        Lock& operator=(const Lock &);  // prevent copy assign
58  
-    };
59  
-    
60  
-    /** a posix style condition */
61  
-    class Condition {
62  
-      public:
63  
-        Condition();
64  
-        ~Condition();
65  
-        /** awake all threads waiting on the condition */
66  
-        void broadcast();
67  
-        /** awake a single thread waiting on the condition */
68  
-        void signal();
69  
-        /** atomically release a mutex and sleep on a condition.
70  
-         *  Warning: under certain conditions a thread may be awoken
71  
-         *           spuriously.  Just as in POSIX.  The client must
72  
-         *           check state upon waking up to catch this case.
73  
-         */
74  
-        void wait(Mutex * m);
75  
-        /** wait until a signal is recieved or a timeout is hit.
76  
-         *  Warning: under certain conditions a thread may be awoken
77  
-         *           spuriously.  Just as in POSIX.  The client must
78  
-         *           check state upon waking up to catch this case.
79  
-         *  \returns true if a signal was recieved, false otherwise */
80  
-        bool timeWait(Mutex * m, unsigned int msec);
81  
-      private:
82  
-        void * m_osDep;
83  
-    };
84  
-}}
85  
-
86  
-#endif
115  src/util/bpsync_UNIX.cpp
... ...
@@ -1,115 +0,0 @@
1  
-/**
2  
- * ***** BEGIN LICENSE BLOCK *****
3  
- * The contents of this file are subject to the Mozilla Public License
4  
- * Version 1.1 (the "License"); you may not use this file except in
5  
- * compliance with the License. You may obtain a copy of the License at
6  
- * http://www.mozilla.org/MPL/
7  
- * 
8  
- * Software distributed under the License is distributed on an "AS IS"
9  
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
10  
- * License for the specific language governing rights and limitations
11  
- * under the License.
12  
- * 
13  
- * The Original Code is BrowserPlus (tm).
14  
- * 
15  
- * The Initial Developer of the Original Code is Yahoo!.
16  
- * Portions created by Yahoo! are Copyright (C) 2006-2009 Yahoo!.
17  
- * All Rights Reserved.
18  
- * 
19  
- * Contributor(s): 
20  
- * ***** END LICENSE BLOCK *****
21  
- */
22  
-#include "bpsync.hh"
23  
-
24  
-#include <pthread.h>
25  
-#include <sys/time.h>
26  
-#include <stdlib.h>
27  
-
28  
-bp::sync::Mutex::Mutex()
29  
-{
30  
-    pthread_mutex_t * mtx =
31  
-        (pthread_mutex_t *) calloc(sizeof(pthread_mutex_t), 1);
32  
-    pthread_mutex_init(mtx, NULL);
33  
-    m_osDep = (void *) mtx;
34  
-}
35  
-
36  
-bp::sync::Mutex::~Mutex()
37  
-{
38  
-    pthread_mutex_destroy((pthread_mutex_t *) m_osDep);
39  
-    free(m_osDep); 
40  
-}
41  
-
42  
-void
43  
-bp::sync::Mutex::lock()
44  
-{
45  
-    pthread_mutex_lock((pthread_mutex_t *) m_osDep);  
46  
-}
47  
-
48  
-void
49  
-bp::sync::Mutex::unlock()
50  
-{
51  
-    pthread_mutex_unlock((pthread_mutex_t *) m_osDep);  
52  
-}
53  
-
54  
-bp::sync::Condition::Condition()
55  
-{
56  
-    pthread_cond_t * c =
57  
-        (pthread_cond_t *) calloc(sizeof(pthread_cond_t), 1);
58  
-    pthread_cond_init(c, NULL);
59  
-    m_osDep = (void *) c;
60  
-}
61  
-
62  
-bp::sync::Condition::~Condition()
63  
-{
64  
-    pthread_cond_destroy((pthread_cond_t *) m_osDep);
65  
-    free(m_osDep);
66  
-}
67  
-
68  
-void
69  
-bp::sync::Condition::broadcast()
70  
-{
71  
-  pthread_cond_broadcast((pthread_cond_t *) m_osDep);
72  
-}
73  
-
74  
-void
75  
-bp::sync::Condition::signal()
76  
-{
77  
-    pthread_cond_signal((pthread_cond_t *) m_osDep);
78  
-}
79  
-
80  
-void
81  
-bp::sync::Condition::wait(bp::sync::Mutex * m)
82  
-{
83  
-    pthread_cond_wait((pthread_cond_t *) m_osDep,
84  
-                      (pthread_mutex_t *) m->m_osDep);
85  
-}
86  
-
87  
-bool
88  
-bp::sync::Condition::timeWait(Mutex * m, unsigned int msec)
89  
-{
90  
-    int ret;
91  
-
92  
-/* POSIX.1b structure for a time value.  This is like a `struct timeval' but
93  
-   has nanoseconds instead of microseconds.  
94  
-      struct timespec 
95  
-      {
96  
-        __time_t tv_sec;             Seconds.  
97  
-        long int tv_nsec;            Nanoseconds.  
98  
-      };
99  
-  */ 
100  
-    {
101  
-        struct timespec ts;
102  
-        struct timeval  tv;
103  
-
104  
-        gettimeofday(&tv,NULL);
105  
-        msec += (tv.tv_usec/1000);
106  
-        ts.tv_sec = tv.tv_sec + msec/1000;
107  
-        ts.tv_nsec = (msec % 1000) * 1000000;
108  
-        ret = pthread_cond_timedwait((pthread_cond_t *) m_osDep,
109  
-                                     (pthread_mutex_t *) m->m_osDep, &ts);
110  
-    }
111  
-
112  
-    // return of zero means success, a signal was recieved, nonzero means
113  
-    // error, we assume timeout. 
114  
-    return (ret == 0);
115  
-}
135  src/util/bpsync_Windows.cpp
... ...
@@ -1,135 +0,0 @@
1  
-/**
2  
- * ***** BEGIN LICENSE BLOCK *****
3  
- * The contents of this file are subject to the Mozilla Public License
4  
- * Version 1.1 (the "License"); you may not use this file except in
5  
- * compliance with the License. You may obtain a copy of the License at
6  
- * http://www.mozilla.org/MPL/
7  
- * 
8  
- * Software distributed under the License is distributed on an "AS IS"
9  
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
10  
- * License for the specific language governing rights and limitations
11  
- * under the License.
12  
- * 
13  
- * The Original Code is BrowserPlus (tm).
14  
- * 
15  
- * The Initial Developer of the Original Code is Yahoo!.
16  
- * Portions created by Yahoo! are Copyright (C) 2006-2009 Yahoo!.
17  
- * All Rights Reserved.
18  
- * 
19  
- * Contributor(s): 
20  
- * ***** END LICENSE BLOCK *****
21  
- */
22  
-#include "bpsync.hh"
23  
-#include <windows.h>
24  
-
25  
-#include <stdlib.h>
26  
-
27  
-bp::sync::Mutex::Mutex()
28  
-{
29  
-    CRITICAL_SECTION * cs =
30  
-        (CRITICAL_SECTION *) calloc(1, sizeof(CRITICAL_SECTION));
31  
-    InitializeCriticalSection(cs);
32  
-    m_osDep = (void *) cs;
33  
-}
34  
-
35  
-bp::sync::Mutex::~Mutex()
36  
-{
37  
-    DeleteCriticalSection((CRITICAL_SECTION *) m_osDep);
38  
-}
39  
-
40  
-void
41  
-bp::sync::Mutex::lock()
42  
-{
43  
-    EnterCriticalSection((CRITICAL_SECTION *) m_osDep);
44  
-}
45  
-
46  
-void
47  
-bp::sync::Mutex::unlock()
48  
-{
49  
-    LeaveCriticalSection((CRITICAL_SECTION *) m_osDep);
50  
-}
51  
-
52  
-struct Win32Condition {
53  
-    /* This Win32 condition solution is detailed on:
54  
-     *   http://www.cs.wustl.edu/~schmidt/win32-cv-1.html */
55  
-    HANDLE e[2]; /* 0 is signal, 1 is broadcast */
56  
-    unsigned int i;
57  
-    CRITICAL_SECTION lock;
58  
-};
59  
-
60  
-bp::sync::Condition::Condition()
61  
-{
62  
-    Win32Condition * c =
63  
-        (Win32Condition *) malloc(sizeof(struct Win32Condition));
64  
-    InitializeCriticalSection(&(c->lock));
65  
-    c->i = 0;
66  
-    c->e[0] = CreateEvent(NULL, false, false, NULL);
67  
-    c->e[1] = CreateEvent(NULL, true, false, NULL);
68  
-    m_osDep = (void *) c;
69  
-}
70  
-
71  
-bp::sync::Condition::~Condition()
72  
-{
73  
-    Win32Condition * c = (Win32Condition *) m_osDep;
74  
-    CloseHandle(c->e[0]);
75  
-    CloseHandle(c->e[1]);
76  
-    DeleteCriticalSection(&c->lock);
77  
-    free(c);
78  
-}
79  
-
80  
-void
81  
-bp::sync::Condition::broadcast()
82  
-{
83  
-    Win32Condition * c = (Win32Condition *) m_osDep;
84  
-
85  
-    int haveWait;
86  
-    EnterCriticalSection(&(c->lock));
87  
-    haveWait = (c->i > 0);
88  
-    LeaveCriticalSection(&(c->lock));
89  
-    if (haveWait) SetEvent(c->e[1]);
90  
-}
91  
-
92  
-void
93  
-bp::sync::Condition::signal()
94  
-{
95  
-    Win32Condition * c = (Win32Condition *) m_osDep;
96  
-
97  
-    int haveWait;
98  
-    EnterCriticalSection(&(c->lock));
99  
-    haveWait = (c->i > 0);
100  
-    LeaveCriticalSection(&(c->lock));
101  
-    if (haveWait) SetEvent(c->e[0]);
102  
-}
103  
-
104  
-void
105  
-bp::sync::Condition::wait(bp::sync::Mutex * m)
106  
-{
107  
-    timeWait(m, 0);
108  
-}
109  
-
110  
-bool
111  
-bp::sync::Condition::timeWait(Mutex * m, unsigned int msecs)
112  
-{
113  
-    Win32Condition * c = (Win32Condition *) m_osDep;
114  
-
115  
-    int result, lastWaiter;
116  
-
117  
-    /* increment the number of waiters */
118  
-    EnterCriticalSection(&(c->lock));
119  
-    c->i++;
120  
-    LeaveCriticalSection(&(c->lock));
121  
-    m->unlock();
122  
-    result = WaitForMultipleObjects(2, c->e, false, msecs ? msecs : INFINITE);
123  
-
124  
-    EnterCriticalSection(&(c->lock));
125  
-    (c->i)--;
126  
-    lastWaiter = ((result == (WAIT_OBJECT_0 + 1)) && ((c->i) == 0)); 
127  
-    LeaveCriticalSection(&(c->lock));
128  
-
129  
-    if (lastWaiter) ResetEvent(c->e[1]);
130  
-
131  
-    m->lock();
132  
-
133  
-    return false;
134  
-}
135  
-
174  src/util/fileutil.cpp
... ...
@@ -1,174 +0,0 @@
1  
-/**
2  
- * ***** BEGIN LICENSE BLOCK *****
3  
- * The contents of this file are subject to the Mozilla Public License
4  
- * Version 1.1 (the "License"); you may not use this file except in
5  
- * compliance with the License. You may obtain a copy of the License at
6  
- * http://www.mozilla.org/MPL/
7  
- * 
8  
- * Software distributed under the License is distributed on an "AS IS"
9  
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
10  
- * License for the specific language governing rights and limitations
11  
- * under the License.
12  
- * 
13  
- * The Original Code is BrowserPlus (tm).
14  
- * 
15  
- * The Initial Developer of the Original Code is Yahoo!.
16  
- * Portions created by Yahoo! are Copyright (C) 2006-2009 Yahoo!.
17  
- * All Rights Reserved.
18  
- * 
19  
- * Contributor(s): 
20  
- * ***** END LICENSE BLOCK *****
21  
- */
22  
-
23  
-#include "fileutil.hh"
24  
-#include "bpsync.hh"
25  
-
26  
-#ifdef WIN32
27  
-#define PATH_SEP '\\'
28  
-#else
29  
-#include <sys/stat.h>
30  
-#include <errno.h>
31  
-#define PATH_SEP '/'
32  
-#endif
33  
-
34  
-#include <sstream>
35  
-#include <string.h>
36  
-#include <stdio.h>
37  </