rhodes 2.0.0.beta7 → 2.0.0.beta8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  }