rhodes 2.0.0.beta7 → 2.0.0.beta8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/CHANGELOG +20 -1
  2. data/bin/rhodes-setup +6 -2
  3. data/lib/extensions/digest/ext/Rakefile +2 -2
  4. data/lib/framework/rho/render.rb +2 -0
  5. data/lib/framework/rho/rho.rb +159 -95
  6. data/lib/framework/rho/rhoapplication.rb +24 -5
  7. data/lib/framework/rhodes.rb +1 -1
  8. data/lib/framework/rhom/rhom_model.rb +32 -23
  9. data/lib/framework/rhom/rhom_object_factory.rb +2 -2
  10. data/lib/rhodes.rb +1 -1
  11. data/platform/android/Rhodes/jni/src/callbacks.cpp +8 -1
  12. data/platform/android/Rhodes/jni/src/mapview.cpp +4 -1
  13. data/platform/android/Rhodes/jni/src/sslimpl.cpp +5 -1
  14. data/platform/android/Rhodes/jni/src/webview.cpp +3 -1
  15. data/platform/android/Rhodes/src/com/rhomobile/rhodes/NativeBar.java +3 -2
  16. data/platform/android/Rhodes/src/com/rhomobile/rhodes/NativeLibraries.java +2 -2
  17. data/platform/android/Rhodes/src/com/rhomobile/rhodes/NavBar.java +1 -2
  18. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +1 -1
  19. data/platform/android/Rhodes/src/com/rhomobile/rhodes/geolocation/GeoLocation.java +3 -1
  20. data/platform/android/Rhodes/src/com/rhomobile/rhodes/geolocation/GeoLocationImpl.java +0 -1
  21. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/MainView.java +4 -1
  22. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/SimpleMainView.java +24 -6
  23. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/TabbedMainView.java +7 -2
  24. data/platform/android/build/android.rake +11 -38
  25. data/platform/android/build/androidcommon.rb +50 -2
  26. data/platform/android/build/librhocommon_build.files +1 -0
  27. data/platform/android/build/libsqlite_build.files +1 -0
  28. data/platform/bb/rhodes/platform/5.0/com/rho/BrowserAdapter5.java +2 -1
  29. data/platform/bb/rhodes/src/com/rho/BrowserAdapter.java +1 -5
  30. data/platform/bb/rhodes/src/com/rho/net/NetworkAccess.java +3 -6
  31. data/platform/bb/rhodes/src/com/rho/rubyext/System.java +4 -2
  32. data/platform/bb/rhodes/src/rhomobile/RhodesApplication.java +12 -35
  33. data/platform/bb/rhodes/src/rhomobile/Utilities.java +2 -1
  34. data/platform/iphone/Classes/DateTimePickerDelegate.m +4 -4
  35. data/platform/iphone/Classes/NativeBar.m +12 -6
  36. data/platform/iphone/Classes/NavBar.m +1 -1
  37. data/platform/iphone/Classes/RhoMainView.h +4 -1
  38. data/platform/iphone/Classes/Rhodes.h +6 -2
  39. data/platform/iphone/Classes/Rhodes.m +23 -3
  40. data/platform/iphone/Classes/SimpleMainView.h +3 -7
  41. data/platform/iphone/Classes/SimpleMainView.m +108 -54
  42. data/platform/iphone/Classes/TabbedMainView.h +3 -2
  43. data/platform/iphone/Classes/TabbedMainView.m +21 -10
  44. data/platform/iphone/RhoLib/RhoLib.xcodeproj/project.pbxproj +8 -0
  45. data/platform/shared/common/IRhoClassFactory.h +1 -0
  46. data/platform/shared/common/RhodesApp.cpp +7 -2
  47. data/platform/shared/common/ThreadQueue.cpp +110 -0
  48. data/platform/shared/common/ThreadQueue.h +75 -0
  49. data/platform/shared/logging/RhoLogCat.h +4 -0
  50. data/platform/shared/net/AsyncHttp.cpp +134 -135
  51. data/platform/shared/net/AsyncHttp.h +74 -33
  52. data/platform/shared/net/HttpServer.cpp +7 -1
  53. data/platform/shared/ruby/thread.c +4 -0
  54. data/platform/shared/ruby/thread_win32.c +9 -8
  55. data/platform/shared/rubyJVM/src/com/rho/RhodesApp.java +26 -5
  56. data/platform/shared/rubyJVM/src/com/rho/net/INetworkAccess.java +0 -2
  57. data/platform/shared/rubyJVM/src/com/rho/net/NetRequest.java +4 -13
  58. data/platform/shared/rubyJVM/src/com/rho/net/URI.java +2 -2
  59. data/platform/shared/rubyJVM/src/com/rho/sync/SyncEngine.java +3 -3
  60. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/ObjectFactory.java +12 -2
  61. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyString.java +6 -3
  62. data/platform/shared/rubyJVM/src/javolution/util/FastTable.java +12 -2
  63. data/platform/shared/sync/SyncEngine.cpp +15 -3
  64. data/platform/shared/sync/SyncEngine.h +1 -1
  65. data/platform/shared/sync/SyncThread.cpp +18 -101
  66. data/platform/shared/sync/SyncThread.h +30 -22
  67. data/platform/wm/RhoLib/RhoLib.vcproj +8 -0
  68. data/platform/wm/rhodes/Rhodes.cpp +143 -1
  69. data/platform/wm/rhodes/memory_helper.cpp +273 -0
  70. data/platform/wm/rhodes/rho/common/RhoThreadImpl.cpp +1 -0
  71. data/platform/wm/rhodes/rho/net/NetRequestImpl.cpp +46 -3
  72. data/platform/wm/rhodes/rho/rubyext/WebView.cpp +29 -1
  73. data/res/build-tools/db/syncdb.schema +1 -0
  74. data/res/generators/rhogen.rb +1 -1
  75. data/rhodes.gemspec +2 -2
  76. metadata +23 -6
  77. data/Manifest.txt +0 -5289
  78. data/rhobuild.yml +0 -37
@@ -48,6 +48,8 @@
48
48
  5C98174C0FBC4FCE002597A5 /* AutoPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C9817490FBC4FCE002597A5 /* AutoPointer.h */; };
49
49
  5C98174D0FBC4FCE002597A5 /* InputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C98174A0FBC4FCE002597A5 /* InputStream.h */; };
50
50
  5C98174E0FBC4FCE002597A5 /* irhoclassfactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C98174B0FBC4FCE002597A5 /* irhoclassfactory.h */; };
51
+ 5CA2DE9011B01EF000B868D5 /* ThreadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CA2DE8E11B01EF000B868D5 /* ThreadQueue.cpp */; };
52
+ 5CA2DE9111B01EF000B868D5 /* ThreadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CA2DE8F11B01EF000B868D5 /* ThreadQueue.h */; };
51
53
  5CBD462A1087399700107D0D /* URI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CBD46271087399700107D0D /* URI.cpp */; };
52
54
  5CBD462B1087399700107D0D /* URI.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CBD46281087399700107D0D /* URI.h */; };
53
55
  5CCD7EBC116CE2D5005E6CA3 /* AppMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD7EBA116CE2D5005E6CA3 /* AppMenu.cpp */; };
@@ -111,6 +113,8 @@
111
113
  5C9817490FBC4FCE002597A5 /* AutoPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AutoPointer.h; path = ../../shared/common/AutoPointer.h; sourceTree = SOURCE_ROOT; };
112
114
  5C98174A0FBC4FCE002597A5 /* InputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InputStream.h; path = ../../shared/common/InputStream.h; sourceTree = SOURCE_ROOT; };
113
115
  5C98174B0FBC4FCE002597A5 /* irhoclassfactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = irhoclassfactory.h; path = ../../shared/common/irhoclassfactory.h; sourceTree = SOURCE_ROOT; };
116
+ 5CA2DE8E11B01EF000B868D5 /* ThreadQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadQueue.cpp; path = ../../shared/common/ThreadQueue.cpp; sourceTree = SOURCE_ROOT; };
117
+ 5CA2DE8F11B01EF000B868D5 /* ThreadQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadQueue.h; path = ../../shared/common/ThreadQueue.h; sourceTree = SOURCE_ROOT; };
114
118
  5CBD46271087399700107D0D /* URI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = URI.cpp; path = ../../shared/net/URI.cpp; sourceTree = SOURCE_ROOT; };
115
119
  5CBD46281087399700107D0D /* URI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = URI.h; path = ../../shared/net/URI.h; sourceTree = SOURCE_ROOT; };
116
120
  5CCD7EBA116CE2D5005E6CA3 /* AppMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AppMenu.cpp; path = ../../shared/common/AppMenu.cpp; sourceTree = SOURCE_ROOT; };
@@ -196,6 +200,8 @@
196
200
  5C7162600F8B7DEE0096B6AA /* common */ = {
197
201
  isa = PBXGroup;
198
202
  children = (
203
+ 5CA2DE8E11B01EF000B868D5 /* ThreadQueue.cpp */,
204
+ 5CA2DE8F11B01EF000B868D5 /* ThreadQueue.h */,
199
205
  5CCD7EBA116CE2D5005E6CA3 /* AppMenu.cpp */,
200
206
  5CCD7EBB116CE2D5005E6CA3 /* AppMenu.h */,
201
207
  BDD11ECB113664E700349BE3 /* rhoparams.c */,
@@ -328,6 +334,7 @@
328
334
  5C59BF4E115B4BC300E96ADE /* unzip.h in Headers */,
329
335
  5C2F10BC116146930054AC80 /* RhoRuby.h in Headers */,
330
336
  5CCD7EBD116CE2D5005E6CA3 /* AppMenu.h in Headers */,
337
+ 5CA2DE9111B01EF000B868D5 /* ThreadQueue.h in Headers */,
331
338
  );
332
339
  runOnlyForDeploymentPostprocessing = 0;
333
340
  };
@@ -396,6 +403,7 @@
396
403
  5C59BF4D115B4BC300E96ADE /* unzip.cpp in Sources */,
397
404
  5C2F10BB116146930054AC80 /* RhoRuby.cpp in Sources */,
398
405
  5CCD7EBC116CE2D5005E6CA3 /* AppMenu.cpp in Sources */,
406
+ 5CA2DE9011B01EF000B868D5 /* ThreadQueue.cpp in Sources */,
399
407
  );
400
408
  runOnlyForDeploymentPostprocessing = 0;
401
409
  };
@@ -8,6 +8,7 @@ namespace net{
8
8
 
9
9
  struct ICallbackObject
10
10
  {
11
+ virtual ~ICallbackObject(){};
11
12
  virtual unsigned long getObjectValue() = 0;
12
13
  };
13
14
 
@@ -92,6 +92,7 @@ void CRhodesApp::run()
92
92
 
93
93
  LOG(INFO) + "Starting sync engine...";
94
94
  rho_sync_create();
95
+
95
96
  LOG(INFO) + "RhoRubyInitApp...";
96
97
  RhoRubyInitApp();
97
98
 
@@ -130,7 +131,7 @@ void CRhodesApp::stopApp()
130
131
  stop(2000);
131
132
  }
132
133
 
133
- rho_asynchttp_destroy();
134
+ net::CAsyncHttp::Destroy();
134
135
  }
135
136
 
136
137
  class CRhoCallbackCall : public common::CRhoThread
@@ -577,7 +578,11 @@ unsigned long CRhodesApp::getCallbackObject(int nIndex)
577
578
  if ( !pCallbackObject )
578
579
  return rho_ruby_get_NIL();
579
580
 
580
- return pCallbackObject->getObjectValue();
581
+ unsigned long valRes = pCallbackObject->getObjectValue();
582
+
583
+ delete pCallbackObject;
584
+
585
+ return valRes;
581
586
  }
582
587
 
583
588
  void CRhodesApp::setPushNotification(String strUrl, String strParams )
@@ -0,0 +1,110 @@
1
+ #include "ThreadQueue.h"
2
+
3
+ namespace rho {
4
+ namespace common {
5
+
6
+ CThreadQueue::CThreadQueue(common::IRhoClassFactory* factory) : CRhoThread(factory)
7
+ {
8
+ m_nPollInterval = QUEUE_POLL_INTERVAL_SECONDS;
9
+ m_bNoThreaded = false;
10
+
11
+ m_ptrFactory = factory;
12
+ }
13
+
14
+ CThreadQueue::~CThreadQueue(void)
15
+ {
16
+ }
17
+
18
+ void CThreadQueue::addQueueCommand(CQueueCommand* pCmd)
19
+ {
20
+ LOG(INFO) + "addCommand: " + pCmd->toString();
21
+ {
22
+ synchronized(m_mxStackCommands);
23
+
24
+ boolean bExist = false;
25
+ if ( isSkipDuplicateCmd() )
26
+ {
27
+ for ( int i = 0; i < (int)m_stackCommands.size(); i++ )
28
+ {
29
+ if ( m_stackCommands.get(i)->equals(*pCmd) )
30
+ {
31
+ bExist = true;
32
+ break;
33
+ }
34
+ }
35
+ }
36
+
37
+ if ( !bExist )
38
+ m_stackCommands.add(pCmd);
39
+ }
40
+
41
+ if ( isNoThreadedMode() )
42
+ processCommands();
43
+ else
44
+ stopWait();
45
+ }
46
+
47
+ void CThreadQueue::run()
48
+ {
49
+ LOG(INFO) + "Starting main routine...";
50
+
51
+ int nLastPollInterval = getLastPollInterval();
52
+ while( !isStopped() )
53
+ {
54
+ unsigned int nWait = m_nPollInterval > 0 ? m_nPollInterval : QUEUE_POLL_INTERVAL_INFINITE;
55
+
56
+ if ( m_nPollInterval > 0 && nLastPollInterval > 0 )
57
+ {
58
+ int nWait2 = m_nPollInterval - nLastPollInterval;
59
+ if ( nWait2 <= 0 )
60
+ nWait = QUEUE_STARTUP_INTERVAL_SECONDS;
61
+ else
62
+ nWait = nWait2;
63
+ }
64
+
65
+ if ( nWait >= 0 && !isStopped() && isNoCommands() )
66
+ {
67
+ LOG(INFO) + "ThreadQueue blocked for " + nWait + " seconds...";
68
+ wait(nWait);
69
+ }
70
+ nLastPollInterval = 0;
71
+
72
+ if ( !isStopped() )
73
+ processCommands();
74
+ }
75
+ }
76
+
77
+ boolean CThreadQueue::isNoCommands()
78
+ {
79
+ boolean bEmpty = false;
80
+ synchronized(m_mxStackCommands)
81
+ {
82
+ bEmpty = m_stackCommands.isEmpty();
83
+ }
84
+
85
+ return bEmpty;
86
+ }
87
+
88
+ void CThreadQueue::processCommands()//throws Exception
89
+ {
90
+ while(!isStopped() && !isNoCommands())
91
+ {
92
+ common::CAutoPtr<CQueueCommand> pCmd = null;
93
+ {
94
+ synchronized(m_mxStackCommands);
95
+ pCmd = (CQueueCommand*)m_stackCommands.removeFirst();
96
+ }
97
+
98
+ processCommand(pCmd);
99
+ }
100
+ }
101
+
102
+ void CThreadQueue::setPollInterval(int nInterval)
103
+ {
104
+ m_nPollInterval = nInterval;
105
+ stopWait();
106
+ }
107
+
108
+ };
109
+ };
110
+
@@ -0,0 +1,75 @@
1
+ #pragma once
2
+
3
+ #ifdef __cplusplus
4
+
5
+ #include "logging/RhoLog.h"
6
+ #include "common/RhoThread.h"
7
+ #include "common/RhoMutexLock.h"
8
+ #include "common/IRhoClassFactory.h"
9
+
10
+ namespace rho {
11
+ namespace common {
12
+
13
+ class CThreadQueue : public common::CRhoThread
14
+ {
15
+ protected:
16
+ static const unsigned int QUEUE_POLL_INTERVAL_SECONDS = 300;
17
+ static const unsigned int QUEUE_POLL_INTERVAL_INFINITE = (unsigned int)(-1);
18
+ static const unsigned int QUEUE_STARTUP_INTERVAL_SECONDS = 10;
19
+
20
+ public:
21
+ DEFINE_BASELOGCLASS
22
+
23
+ struct CQueueCommand
24
+ {
25
+ virtual ~CQueueCommand(){};
26
+ virtual boolean equals(const CQueueCommand& cmd) = 0;
27
+ virtual String toString() = 0;
28
+ };
29
+
30
+ private:
31
+
32
+ common::CAutoPtr<common::IRhoClassFactory> m_ptrFactory;
33
+ int m_nPollInterval;
34
+ common::CMutex m_mxStackCommands;
35
+ LinkedListPtr<CQueueCommand*> m_stackCommands;
36
+
37
+ boolean m_bNoThreaded;
38
+ public:
39
+ CThreadQueue(common::IRhoClassFactory* factory);
40
+
41
+ ~CThreadQueue(void);
42
+
43
+ virtual void addQueueCommand(CQueueCommand* pCmd);
44
+ virtual void run();
45
+
46
+ void setPollInterval(int nInterval);
47
+ int getPollInterval()const{ return m_nPollInterval;}
48
+
49
+ boolean isNoThreadedMode(){ return m_bNoThreaded; }
50
+ void setNonThreadedMode(bool b){m_bNoThreaded = b;}
51
+
52
+ common::IRhoClassFactory* getFactory(){ return m_ptrFactory; }
53
+ protected:
54
+ virtual int getLastPollInterval(){ return 0;}
55
+ virtual void processCommand(CQueueCommand* pCmd) = 0;
56
+ virtual boolean isSkipDuplicateCmd() { return false; }
57
+
58
+ virtual void processCommands();
59
+
60
+ boolean isNoCommands();
61
+ };
62
+
63
+ }
64
+ }
65
+ #endif //__cplusplus
66
+
67
+ #ifdef __cplusplus
68
+ extern "C" {
69
+ #endif //__cplusplus
70
+
71
+ #ifdef __cplusplus
72
+ };
73
+ #endif //__cplusplus
74
+
75
+
@@ -25,4 +25,8 @@ extern rho::LogCategory __rhoCurrentCategory;
25
25
  #define IMPLEMENT_LOGCLASS(classname, name) \
26
26
  rho::LogCategory classname::__rhoCurrentCategory = name
27
27
 
28
+ #define DEFINE_BASELOGCLASS rho::LogCategory __rhoCurrentCategory;\
29
+ rho::LogCategory getLogCategory(){return __rhoCurrentCategory;}\
30
+ void setLogCategory(const rho::LogCategory& cat){__rhoCurrentCategory = cat;}
31
+
28
32
  #endif //_RHOLOGCAT_H_
@@ -11,79 +11,52 @@ namespace net
11
11
  {
12
12
 
13
13
  IMPLEMENT_LOGCLASS(CAsyncHttp, "AsyncHttp");
14
- common::CMutex CAsyncHttp::m_mxInstances;
15
- VectorPtr<CAsyncHttp*> CAsyncHttp::m_arInstances;
14
+ CAsyncHttp* CAsyncHttp::m_pInstance = 0;
16
15
 
17
- extern "C" void header_iter(const char* szName, const char* szValue, void* pHash)
16
+ /*static*/ CAsyncHttp* CAsyncHttp::Create()
18
17
  {
19
- ((Hashtable<String,String>*)pHash)->put(szName, szValue);
18
+ if ( m_pInstance )
19
+ return m_pInstance;
20
+
21
+ m_pInstance = new CAsyncHttp( rho::common::createClassFactory());
22
+ return m_pInstance;
20
23
  }
21
24
 
22
- CAsyncHttp::CAsyncHttp(common::IRhoClassFactory* factory, EHttpCommands eCmd,
23
- const char* url, unsigned long headers, const char* body,
24
- const char* file_path,
25
- const char* callback, const char* callback_params, boolean ssl_verify_peer) : CRhoThread(factory)
25
+ /*static*/void CAsyncHttp::Destroy()
26
26
  {
27
- m_bFinished = false;
28
- m_ptrFactory = factory;
29
- m_strUrl = url != null ? url : "";
30
- m_strBody = body != null ? body : "";
31
- m_strFilePath = file_path != null ? file_path : "";
32
- m_strCallback = callback != null ? callback : "";
33
- m_strCallbackParams = callback_params != null ? callback_params : "";
34
- m_eCmd = eCmd;
35
- m_sslVerifyPeer = ssl_verify_peer;
36
-
37
- rho_ruby_enum_strhash(headers, &header_iter, &m_mapHeaders);
38
-
39
- addNewObject(this);
27
+ if ( m_pInstance )
28
+ delete m_pInstance;
40
29
 
41
- if (m_strCallback.length()==0)
42
- run();
43
- else
44
- start(epLow);
30
+ m_pInstance = 0;
45
31
  }
46
32
 
47
- void CAsyncHttp::cancel(boolean bWait)
33
+ CAsyncHttp::CAsyncHttp(common::IRhoClassFactory* factory) : CThreadQueue(factory)
48
34
  {
49
- {
50
- synchronized(m_mxRequest)
35
+ CThreadQueue::setLogCategory(getLogCategory());
51
36
 
52
- if (m_pNetRequest!=null && !m_pNetRequest->isCancelled() )
53
- m_pNetRequest->cancel();
54
- }
37
+ setPollInterval(QUEUE_POLL_INTERVAL_INFINITE);
55
38
 
56
- if ( bWait )
57
- stop(-1);
39
+ m_pCurCmd = null;
58
40
  }
59
41
 
60
- /*static*/ void CAsyncHttp::addNewObject(CAsyncHttp* pObj)
42
+ CAsyncHttp::~CAsyncHttp(void)
61
43
  {
62
- synchronized(m_mxInstances)
63
- {
64
- while(1)
65
- {
66
- int nToDelete = -1;
67
- for (int i = 0; i < (int)m_arInstances.size(); i++ )
68
- {
69
- if ( m_arInstances.elementAt(i)->m_bFinished )
70
- {
71
- nToDelete = i;
72
- break;
73
- }
74
- }
75
-
76
- if (nToDelete==-1)
77
- break;
78
-
79
- m_arInstances.removeElementAt(nToDelete);
80
- }
44
+ cancelRequest("*", true);
45
+ LOG(INFO) + "Thread shutdown";
46
+ }
81
47
 
82
- m_arInstances.addElement(pObj);
48
+ void CAsyncHttp::addQueueCommand(CQueueCommand* pCmd)
49
+ {
50
+ if ( ((CHttpCommand*)pCmd)->m_strCallback.length()==0)
51
+ processCommand(pCmd);
52
+ else
53
+ {
54
+ CThreadQueue::addQueueCommand(pCmd);
55
+ start(epLow);
83
56
  }
84
57
  }
85
58
 
86
- /*static*/ void CAsyncHttp::cancelRequest(const char* szCallback, boolean bWait)
59
+ void CAsyncHttp::cancelRequest(const char* szCallback, boolean bWait)
87
60
  {
88
61
  if (!szCallback || !*szCallback )
89
62
  {
@@ -91,44 +64,68 @@ void CAsyncHttp::cancel(boolean bWait)
91
64
  return;
92
65
  }
93
66
 
94
- synchronized(m_mxInstances)
95
- {
96
- if ( *szCallback == '*')
97
- {
98
- for (int i = 0; i < (int)m_arInstances.size(); i++ )
99
- m_arInstances.elementAt(i)->cancel(bWait);
100
- }else
101
- {
102
- for (int i = 0; i < (int)m_arInstances.size(); i++ )
103
- {
104
- if ( m_arInstances.elementAt(i)->m_strCallback.compare(szCallback) == 0 )
105
- m_arInstances.elementAt(i)->cancel(bWait);
106
- }
107
- }
108
- }
67
+ if ( m_pCurCmd != null )
68
+ m_pCurCmd->cancel();
69
+
70
+ if ( bWait )
71
+ stop(-1);
72
+
73
+ //TODO: find command by callback and cancel it if current, remove if it is still in queue
109
74
  }
110
75
 
111
- void CAsyncHttp::run()
76
+ void CAsyncHttp::processCommand(CQueueCommand* pCmd)
112
77
  {
113
- LOG(INFO) + "RhoHttp thread start.";
78
+ m_pCurCmd = (CHttpCommand*)pCmd;
79
+ m_pCurCmd->execute();
80
+ m_pCurCmd = null;
81
+ }
114
82
 
115
- {
116
- synchronized(m_mxRequest)
117
- m_pNetRequest = m_ptrFactory->createNetRequest();
118
- m_pNetRequest->sslVerifyPeer(m_sslVerifyPeer);
119
- }
83
+ extern "C" void header_iter(const char* szName, const char* szValue, void* pHash)
84
+ {
85
+ ((Hashtable<String,String>*)pHash)->put(szName, szValue);
86
+ }
87
+
88
+ CAsyncHttp::CHttpCommand::CHttpCommand(
89
+ EHttpCommands eCmd,
90
+ const char* url, unsigned long headers, const char* body,
91
+ const char* file_path,
92
+ const char* callback, const char* callback_params, boolean ssl_verify_peer)
93
+ {
94
+ m_strUrl = url != null ? url : "";
95
+ m_strBody = body != null ? body : "";
96
+ m_strFilePath = file_path != null ? file_path : "";
97
+ m_strCallback = callback != null ? callback : "";
98
+ m_strCallbackParams = callback_params != null ? callback_params : "";
99
+ m_eCmd = eCmd;
100
+ m_sslVerifyPeer = ssl_verify_peer;
101
+
102
+ rho_ruby_enum_strhash(headers, &header_iter, &m_mapHeaders);
120
103
 
104
+ m_pNetRequest = CAsyncHttp::getInstance()->getFactory()->createNetRequest();
105
+ m_pNetRequest->sslVerifyPeer(m_sslVerifyPeer);
106
+
107
+ }
108
+
109
+ void CAsyncHttp::CHttpCommand::cancel()
110
+ {
111
+ if (m_pNetRequest!=null && !m_pNetRequest->isCancelled() )
112
+ m_pNetRequest->cancel();
113
+ }
114
+
115
+ void CAsyncHttp::CHttpCommand::execute()
116
+ {
117
+ INetResponse* resp = null;
121
118
  switch( m_eCmd )
122
119
  {
123
120
  case hcGet:
124
- m_pNetResponse = m_pNetRequest->doRequest("GET", m_strUrl, m_strBody, null, &m_mapHeaders);
121
+ resp = m_pNetRequest->doRequest("GET", m_strUrl, m_strBody, null, &m_mapHeaders);
125
122
  break;
126
123
  case hcPost:
127
- m_pNetResponse = m_pNetRequest->doRequest("POST", m_strUrl, m_strBody, null, &m_mapHeaders);
124
+ resp = m_pNetRequest->doRequest("POST", m_strUrl, m_strBody, null, &m_mapHeaders);
128
125
  break;
129
126
 
130
127
  case hcDownload:
131
- m_pNetResponse = m_pNetRequest->pullFile(m_strUrl, m_strFilePath, null, &m_mapHeaders);
128
+ resp = m_pNetRequest->pullFile(m_strUrl, m_strFilePath, null, &m_mapHeaders);
132
129
  break;
133
130
 
134
131
  case hcUpload:
@@ -148,23 +145,24 @@ void CAsyncHttp::run()
148
145
  arMultipartItems.addElement(pItem);
149
146
  }
150
147
 
151
- m_pNetResponse = m_pNetRequest->pushMultipartData( m_strUrl, arMultipartItems, null, &m_mapHeaders );
148
+ resp = m_pNetRequest->pushMultipartData( m_strUrl, arMultipartItems, null, &m_mapHeaders );
152
149
  break;
153
150
  }
154
151
  }
155
152
 
156
153
  if ( !m_pNetRequest->isCancelled())
157
- {
158
- //processResponse(*m_pNetResponse);
159
- callNotify(*m_pNetResponse,0);
160
- }
154
+ callNotify(resp,0);
155
+ }
161
156
 
162
- LOG(INFO) + "RhoHttp thread end.";
157
+ unsigned long CAsyncHttp::CHttpCommand::getRetValue()
158
+ {
159
+ if ( m_strCallback.length() == 0 )
160
+ return rho_ruby_create_string(m_strResBody.c_str());
163
161
 
164
- m_bFinished = true;
162
+ return rho_ruby_get_NIL();
165
163
  }
166
164
 
167
- String CAsyncHttp::makeHeadersString()
165
+ String CAsyncHttp::CHttpCommand::makeHeadersString()
168
166
  {
169
167
  String strRes = "";
170
168
 
@@ -182,39 +180,10 @@ String CAsyncHttp::makeHeadersString()
182
180
  return strRes;
183
181
  }
184
182
 
185
- extern "C" VALUE rjson_tokener_parse(const char *str, char** pszError );
186
- unsigned long CAsyncHttp::getObjectValue()
187
- {
188
- rho::net::INetResponse& resp = *m_pNetResponse;
189
- if (resp.isOK())
190
- {
191
- String strContType = m_mapHeaders.get("content-type");
192
- if ( strContType.find("application/json") != String::npos )
193
- {
194
- char* szError = 0;
195
- unsigned long valBody = rjson_tokener_parse(resp.getCharData(), &szError);
196
- if ( valBody != 0 )
197
- return valBody;
198
-
199
- LOG(ERROR) + "Incorrect json body.Error:" + (szError ? szError : "");
200
- if ( szError )
201
- free(szError);
202
- }
203
- }
204
-
205
- return rho_ruby_create_string(resp.getCharData());
206
- }
207
-
208
- unsigned long CAsyncHttp::getRetValue()
183
+ void CAsyncHttp::CHttpCommand::callNotify(rho::net::INetResponse* pResp, int nError )
209
184
  {
210
- if ( m_strCallback.length() == 0 )
211
- return rho_ruby_create_string(m_strResBody.c_str());
185
+ rho::net::INetResponse& resp = *pResp;
212
186
 
213
- return rho_ruby_get_NIL();
214
- }
215
-
216
- void CAsyncHttp::callNotify(rho::net::INetResponse& resp, int nError )
217
- {
218
187
  m_strResBody = "rho_callback=1";
219
188
  m_strResBody += "&status=";
220
189
  if ( nError > 0 )
@@ -240,7 +209,8 @@ void CAsyncHttp::callNotify(rho::net::INetResponse& resp, int nError )
240
209
  if (strHeaders.length() > 0 )
241
210
  m_strResBody += "&" + strHeaders;
242
211
 
243
- m_strResBody += "&" + RHODESAPP().addCallbackObject(this, "body");
212
+ m_strResBody += "&" + RHODESAPP().addCallbackObject(
213
+ new CAsyncHttpResponse(pResp, m_mapHeaders.get("content-type")), "body");
244
214
  }
245
215
 
246
216
  if ( m_strCallbackParams.length() > 0 )
@@ -248,12 +218,33 @@ void CAsyncHttp::callNotify(rho::net::INetResponse& resp, int nError )
248
218
 
249
219
  if ( m_strCallback.length() > 0 )
250
220
  {
251
- common::CAutoPtr<INetRequest> pNetRequest = m_ptrFactory->createNetRequest();
252
- String strFullUrl = pNetRequest->resolveUrl(m_strCallback);
253
- NetResponse(resp1,pNetRequest->pushData( strFullUrl, m_strResBody, null ));
254
- if ( !resp1.isOK() )
255
- LOG(ERROR) + "AsyncHttp notification failed. Code: " + resp1.getRespCode() + "; Error body: " + resp1.getCharData();
221
+ String strFullUrl = m_pNetRequest->resolveUrl(m_strCallback);
222
+ m_pNetRequest->pushData( strFullUrl, m_strResBody, null );
223
+ }
224
+ }
225
+
226
+ CAsyncHttp::CAsyncHttpResponse::~CAsyncHttpResponse(){}
227
+
228
+ extern "C" VALUE rjson_tokener_parse(const char *str, char** pszError );
229
+ unsigned long CAsyncHttp::CAsyncHttpResponse::getObjectValue()
230
+ {
231
+ rho::net::INetResponse& resp = *m_pNetResponse;
232
+ if (resp.isOK())
233
+ {
234
+ if ( m_strContentType.find("application/json") != String::npos )
235
+ {
236
+ char* szError = 0;
237
+ unsigned long valBody = rjson_tokener_parse(resp.getCharData(), &szError);
238
+ if ( valBody != 0 )
239
+ return valBody;
240
+
241
+ LOG(ERROR) + "Incorrect json body.Error:" + (szError ? szError : "");
242
+ if ( szError )
243
+ free(szError);
244
+ }
256
245
  }
246
+
247
+ return rho_ruby_create_string(resp.getCharData());
257
248
  }
258
249
 
259
250
  } // namespace net
@@ -265,36 +256,44 @@ using namespace rho::net;
265
256
 
266
257
  unsigned long rho_asynchttp_get(const char* url, unsigned long headers, const char* callback, const char* callback_params, int ssl_verify_peer)
267
258
  {
268
- CAsyncHttp* pHttp = new CAsyncHttp(rho::common::createClassFactory(), CAsyncHttp::hcGet, url, headers, null, null, callback, callback_params, ssl_verify_peer!=0 );
259
+ CAsyncHttp::Create();
260
+
261
+ CAsyncHttp::CHttpCommand* pHttp = new CAsyncHttp::CHttpCommand(CAsyncHttp::hcGet, url, headers, null, null, callback, callback_params, ssl_verify_peer!=0 );
262
+ CAsyncHttp::getInstance()->addQueueCommand(pHttp);
269
263
  return pHttp->getRetValue();
270
264
  }
271
265
 
272
266
  unsigned long rho_asynchttp_post(const char* url, unsigned long headers, const char* body, const char* callback, const char* callback_params, int ssl_verify_peer)
273
267
  {
274
- CAsyncHttp* pHttp = new CAsyncHttp(rho::common::createClassFactory(), CAsyncHttp::hcPost, url, headers, body!=null?body:"", null, callback, callback_params, ssl_verify_peer!=0 );
268
+ CAsyncHttp::Create();
269
+
270
+ CAsyncHttp::CHttpCommand* pHttp = new CAsyncHttp::CHttpCommand(CAsyncHttp::hcPost, url, headers, body!=null?body:"", null, callback, callback_params, ssl_verify_peer!=0 );
271
+ CAsyncHttp::getInstance()->addQueueCommand(pHttp);
275
272
  return pHttp->getRetValue();
276
273
  }
277
274
 
278
275
  unsigned long rho_asynchttp_downloadfile(const char* url, unsigned long headers, const char* file_path, const char* callback, const char* callback_params, int ssl_verify_peer)
279
276
  {
280
- CAsyncHttp* pHttp = new CAsyncHttp(rho::common::createClassFactory(), CAsyncHttp::hcDownload, url, headers, "", file_path, callback, callback_params, ssl_verify_peer!=0 );
277
+ CAsyncHttp::Create();
278
+
279
+ CAsyncHttp::CHttpCommand* pHttp = new CAsyncHttp::CHttpCommand(CAsyncHttp::hcDownload, url, headers, "", file_path, callback, callback_params, ssl_verify_peer!=0 );
280
+ CAsyncHttp::getInstance()->addQueueCommand(pHttp);
281
281
  return pHttp->getRetValue();
282
282
  }
283
283
 
284
284
  unsigned long rho_asynchttp_uploadfile(const char* url, unsigned long headers, const char* body, const char* file_path, const char* callback, const char* callback_params, int ssl_verify_peer)
285
285
  {
286
- CAsyncHttp* pHttp = new CAsyncHttp(rho::common::createClassFactory(), CAsyncHttp::hcUpload, url, headers, body, file_path, callback, callback_params, ssl_verify_peer!=0 );
286
+ CAsyncHttp::Create();
287
+
288
+ CAsyncHttp::CHttpCommand* pHttp = new CAsyncHttp::CHttpCommand(CAsyncHttp::hcUpload, url, headers, body, file_path, callback, callback_params, ssl_verify_peer!=0 );
289
+ CAsyncHttp::getInstance()->addQueueCommand(pHttp);
287
290
  return pHttp->getRetValue();
288
291
  }
289
292
 
290
293
  void rho_asynchttp_cancel(const char* cancel_callback)
291
294
  {
292
- CAsyncHttp::cancelRequest(cancel_callback, false);
293
- }
294
-
295
- void rho_asynchttp_destroy()
296
- {
297
- CAsyncHttp::cancelRequest("*", true);
295
+ if ( CAsyncHttp::getInstance() )
296
+ CAsyncHttp::getInstance()->cancelRequest(cancel_callback, false);
298
297
  }
299
298
 
300
299
  }