~ubuntu-branches/ubuntu/quantal/aria2/quantal

« back to all changes in this revision

Viewing changes to src/RpcMethodImpl.cc

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry
  • Date: 2011-11-08 20:25:08 UTC
  • mfrom: (2.5.7 sid)
  • Revision ID: package-import@ubuntu.com-20111108202508-scfph8rj6tz0cckk
Tags: 1.13.0-1
* New upstream version:
  + Depends on libgcrypt11 (>= 1.5.0-3) (Closes: #642989)

Show diffs side-by-side

added added

removed removed

Lines of Context:
64
64
#include "TimedHaltCommand.h"
65
65
#include "PeerStat.h"
66
66
#include "Base64.h"
 
67
#include "BitfieldMan.h"
67
68
#ifdef ENABLE_MESSAGE_DIGEST
68
69
# include "MessageDigest.h"
69
70
# include "message_digest_helper.h"
178
179
} // namespace
179
180
 
180
181
namespace {
181
 
void getPosParam(const RpcRequest& req, size_t posParamIndex,
182
 
                 bool& posGiven, size_t& pos)
 
182
bool checkPosParam(const Integer* posParam)
183
183
{
184
 
  const Integer* p = req.getIntegerParam(posParamIndex);
185
 
  if(p) {
186
 
    if(p->i() >= 0) {
187
 
      pos = p->i();
188
 
      posGiven = true;
189
 
      return;
 
184
  if(posParam) {
 
185
    if(posParam->i() >= 0) {
 
186
      return true;
190
187
    } else {
191
188
      throw DL_ABORT_EX("Position must be greater than or equal to 0.");
192
189
    }
193
190
  }
194
 
  posGiven = false;
195
 
 
191
  return false;
 
192
}
196
193
} // namespace
197
194
 
198
195
namespace {
199
 
a2_gid_t getRequiredGidParam
200
 
(const RpcRequest& req, size_t posParamIndex)
 
196
a2_gid_t str2Gid(const String* str)
201
197
{
202
 
  const String* gidParam = req.getStringParam(posParamIndex);
203
 
  if(gidParam) {
204
 
    return util::parseLLInt(gidParam->s());
205
 
  } else {
206
 
    throw DL_ABORT_EX(MSG_GID_NOT_PROVIDED);
207
 
  }
 
198
  assert(str);
 
199
  return util::parseLLInt(str->s());
208
200
}
209
201
} // namespace
210
202
 
215
207
  if(src) {
216
208
    for(List::ValueType::const_iterator i = src->begin(), eoi = src->end();
217
209
        i != eoi; ++i) {
218
 
      const String* uri = asString(*i);
 
210
      const String* uri = downcast<String>(*i);
219
211
      if(uri) {
220
212
        out++ = uri->s();
221
213
      }
227
219
SharedHandle<ValueBase> AddUriRpcMethod::process
228
220
(const RpcRequest& req, DownloadEngine* e)
229
221
{
 
222
  const List* urisParam = checkRequiredParam<List>(req, 0);
 
223
  const Dict* optsParam = checkParam<Dict>(req, 1);
 
224
  const Integer* posParam = checkParam<Integer>(req, 2);
 
225
 
230
226
  std::vector<std::string> uris;
231
 
  extractUris(std::back_inserter(uris), req.getListParam(0));
 
227
  extractUris(std::back_inserter(uris), urisParam);
232
228
  if(uris.empty()) {
233
229
    throw DL_ABORT_EX("URI is not provided.");
234
230
  }
235
231
 
236
232
  SharedHandle<Option> requestOption(new Option(*e->getOption()));
237
 
  gatherRequestOption(requestOption, req.getDictParam(1));
 
233
  gatherRequestOption(requestOption, optsParam);
238
234
 
239
 
  size_t pos = 0;
240
 
  bool posGiven = false;
241
 
  getPosParam(req, 2, posGiven, pos);
 
235
  bool posGiven = checkPosParam(posParam);
 
236
  size_t pos = posGiven ? posParam->i() : 0;
242
237
 
243
238
  std::vector<SharedHandle<RequestGroup> > result;
244
239
  createRequestGroupForUri(result, requestOption, uris,
268
263
SharedHandle<ValueBase> AddTorrentRpcMethod::process
269
264
(const RpcRequest& req, DownloadEngine* e)
270
265
{
271
 
  const String* torrentParam = req.getStringParam(0);
272
 
  if(!torrentParam) {
273
 
    throw DL_ABORT_EX("Torrent data is not provided.");
274
 
  }
 
266
  const String* torrentParam = checkRequiredParam<String>(req, 0);
 
267
  const List* urisParam = checkParam<List>(req, 1);
 
268
  const Dict* optsParam = checkParam<Dict>(req, 2);
 
269
  const Integer* posParam = checkParam<Integer>(req, 3);
 
270
 
275
271
  SharedHandle<String> tempTorrentParam;
276
272
  if(req.jsonRpc) {
277
273
    tempTorrentParam = String::g(Base64::decode(torrentParam->s()));
278
274
    torrentParam = tempTorrentParam.get();
279
275
  }
280
276
  std::vector<std::string> uris;
281
 
  extractUris(std::back_inserter(uris), req.getListParam(1));
 
277
  extractUris(std::back_inserter(uris), urisParam);
282
278
 
283
279
  SharedHandle<Option> requestOption(new Option(*e->getOption()));
284
 
  gatherRequestOption(requestOption, req.getDictParam(2));
 
280
  gatherRequestOption(requestOption, optsParam);
285
281
 
286
 
  size_t pos = 0;
287
 
  bool posGiven = false;
288
 
  getPosParam(req, 3, posGiven, pos);
 
282
  bool posGiven = checkPosParam(posParam);
 
283
  size_t pos = posGiven ? posParam->i() : 0;
289
284
 
290
285
  std::string filename = util::applyDir
291
286
    (requestOption->get(PREF_DIR), getHexSha1(torrentParam->s())+".torrent");
315
310
SharedHandle<ValueBase> AddMetalinkRpcMethod::process
316
311
(const RpcRequest& req, DownloadEngine* e)
317
312
{
318
 
  const String* metalinkParam = req.getStringParam(0);
319
 
  if(!metalinkParam) {
320
 
    throw DL_ABORT_EX("Metalink data is not provided.");
321
 
  }
 
313
  const String* metalinkParam = checkRequiredParam<String>(req, 0);
 
314
  const Dict* optsParam = checkParam<Dict>(req, 1);
 
315
  const Integer* posParam = checkParam<Integer>(req, 2);
 
316
 
322
317
  SharedHandle<String> tempMetalinkParam;
323
318
  if(req.jsonRpc) {
324
319
    tempMetalinkParam = String::g(Base64::decode(metalinkParam->s()));
325
320
    metalinkParam = tempMetalinkParam.get();
326
321
  }
327
322
  SharedHandle<Option> requestOption(new Option(*e->getOption()));
328
 
  gatherRequestOption(requestOption, req.getDictParam(1));
 
323
  gatherRequestOption(requestOption, optsParam);
329
324
 
330
 
  size_t pos = 0;
331
 
  bool posGiven = false;
332
 
  getPosParam(req, 2, posGiven, pos);
 
325
  bool posGiven = checkPosParam(posParam);
 
326
  size_t pos = posGiven ? posParam->i() : 0;
333
327
 
334
328
  std::vector<SharedHandle<RequestGroup> > result;
335
329
#ifdef ENABLE_MESSAGE_DIGEST
374
368
SharedHandle<ValueBase> removeDownload
375
369
(const RpcRequest& req, DownloadEngine* e, bool forceRemove)
376
370
{
377
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
 
371
  const String* gidParam = checkRequiredParam<String>(req, 0);
378
372
 
 
373
  a2_gid_t gid = str2Gid(gidParam);
379
374
  SharedHandle<RequestGroup> group =
380
375
    e->getRequestGroupMan()->findRequestGroup(gid);
381
376
  if(!group) {
446
441
SharedHandle<ValueBase> pauseDownload
447
442
(const RpcRequest& req, DownloadEngine* e, bool forcePause)
448
443
{
449
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
 
444
  const String* gidParam = checkRequiredParam<String>(req, 0);
450
445
 
 
446
  a2_gid_t gid = str2Gid(gidParam);
451
447
  bool reserved = false;
452
448
  SharedHandle<RequestGroup> group =
453
449
    e->getRequestGroupMan()->findRequestGroup(gid);
519
515
SharedHandle<ValueBase> UnpauseRpcMethod::process
520
516
(const RpcRequest& req, DownloadEngine* e)
521
517
{
522
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
 
518
  const String* gidParam = checkRequiredParam<String>(req, 0);
 
519
 
 
520
  a2_gid_t gid = str2Gid(gidParam);
523
521
  SharedHandle<RequestGroup> group =
524
522
    e->getRequestGroupMan()->findReservedGroup(gid);
525
523
  if(!group || !group->isPauseRequested()) {
579
577
namespace {
580
578
template<typename InputIterator>
581
579
void createFileEntry
582
 
(const SharedHandle<List>& files, InputIterator first, InputIterator last)
 
580
(const SharedHandle<List>& files,
 
581
 InputIterator first, InputIterator last,
 
582
 const BitfieldMan* bf)
583
583
{
584
584
  size_t index = 1;
585
585
  for(; first != last; ++first, ++index) {
588
588
    entry->put(KEY_PATH, (*first)->getPath());
589
589
    entry->put(KEY_SELECTED, (*first)->isRequested()?VLB_TRUE:VLB_FALSE);
590
590
    entry->put(KEY_LENGTH, util::uitos((*first)->getLength()));
 
591
    uint64_t completedLength = bf->getOffsetCompletedLength
 
592
      ((*first)->getOffset(), (*first)->getLength());
 
593
    entry->put(KEY_COMPLETED_LENGTH, util::uitos(completedLength));
591
594
 
592
595
    SharedHandle<List> uriList = List::g();
593
596
    createUriEntry(uriList, *first);
598
601
} // namespace
599
602
 
600
603
namespace {
 
604
template<typename InputIterator>
 
605
void createFileEntry
 
606
(const SharedHandle<List>& files,
 
607
 InputIterator first, InputIterator last,
 
608
 uint64_t totalLength,
 
609
 size_t pieceLength,
 
610
 const std::string& bitfieldStr)
 
611
{
 
612
  std::string bitfield = util::fromHex(bitfieldStr);
 
613
  BitfieldMan bf(pieceLength, totalLength);
 
614
  bf.setBitfield(reinterpret_cast<const unsigned char*>(bitfield.data()),
 
615
                 bitfield.size());
 
616
  createFileEntry(files, first, last, &bf);
 
617
}
 
618
} // namespace
 
619
 
 
620
namespace {
 
621
template<typename InputIterator>
 
622
void createFileEntry
 
623
(const SharedHandle<List>& files,
 
624
 InputIterator first, InputIterator last,
 
625
 uint64_t totalLength,
 
626
 size_t pieceLength,
 
627
 const SharedHandle<PieceStorage>& ps)
 
628
{
 
629
  BitfieldMan bf(pieceLength, totalLength);
 
630
  if(ps) {
 
631
    bf.setBitfield(ps->getBitfield(), ps->getBitfieldLength());
 
632
  }
 
633
  createFileEntry(files, first, last, &bf);
 
634
}
 
635
} // namespace
 
636
 
 
637
namespace {
601
638
bool requested_key
602
639
(const std::vector<std::string>& keys, const std::string& k)
603
640
{
610
647
 const SharedHandle<RequestGroup>& group,
611
648
 const std::vector<std::string>& keys)
612
649
{
 
650
  const SharedHandle<PieceStorage>& ps = group->getPieceStorage();
613
651
  if(requested_key(keys, KEY_GID)) {
614
652
    entryDict->put(KEY_GID, util::itos(group->getGID()));
615
653
  }
637
675
    entryDict->put(KEY_CONNECTIONS, util::uitos(group->getNumConnection()));
638
676
  }
639
677
  if(requested_key(keys, KEY_BITFIELD)) {
640
 
    SharedHandle<PieceStorage> ps = group->getPieceStorage();
641
678
    if(ps) {
642
679
      if(ps->getBitfieldLength() > 0) {
643
680
        entryDict->put(KEY_BITFIELD,
671
708
  if(requested_key(keys, KEY_FILES)) {
672
709
    SharedHandle<List> files = List::g();
673
710
    createFileEntry
674
 
      (files, dctx->getFileEntries().begin(), dctx->getFileEntries().end());
 
711
      (files, dctx->getFileEntries().begin(), dctx->getFileEntries().end(),
 
712
       dctx->getTotalLength(), dctx->getPieceLength(), ps);
675
713
    entryDict->put(KEY_FILES, files);
676
714
  }
677
715
  if(requested_key(keys, KEY_DIR)) {
829
867
  }
830
868
  if(requested_key(keys, KEY_FILES)) {
831
869
    SharedHandle<List> files = List::g();
832
 
    createFileEntry(files, ds->fileEntries.begin(), ds->fileEntries.end());
 
870
    createFileEntry(files, ds->fileEntries.begin(), ds->fileEntries.end(),
 
871
                    ds->totalLength, ds->pieceLength, ds->bitfieldStr);
833
872
    entryDict->put(KEY_FILES, files);
834
873
  }
835
874
  if(requested_key(keys, KEY_TOTAL_LENGTH)) {
877
916
SharedHandle<ValueBase> GetFilesRpcMethod::process
878
917
(const RpcRequest& req, DownloadEngine* e)
879
918
{
880
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
 
919
  const String* gidParam = checkRequiredParam<String>(req, 0);
 
920
 
 
921
  a2_gid_t gid = str2Gid(gidParam);
881
922
  SharedHandle<List> files = List::g();
882
923
  SharedHandle<RequestGroup> group =
883
924
    findRequestGroup(e->getRequestGroupMan(), gid);
889
930
        (fmt("No file data is available for GID#%s",
890
931
             util::itos(gid).c_str()));
891
932
    } else {
892
 
      createFileEntry(files, dr->fileEntries.begin(), dr->fileEntries.end());
 
933
      createFileEntry(files, dr->fileEntries.begin(), dr->fileEntries.end(),
 
934
                      dr->totalLength, dr->pieceLength, dr->bitfieldStr);
893
935
    }
894
936
  } else {
 
937
    const SharedHandle<PieceStorage>& ps = group->getPieceStorage();
 
938
    const SharedHandle<DownloadContext>& dctx = group->getDownloadContext();
895
939
    createFileEntry(files,
896
940
                    group->getDownloadContext()->getFileEntries().begin(),
897
 
                    group->getDownloadContext()->getFileEntries().end());
 
941
                    group->getDownloadContext()->getFileEntries().end(),
 
942
                    dctx->getTotalLength(),
 
943
                    dctx->getPieceLength(),
 
944
                    ps);
898
945
  }
899
946
  return files;
900
947
}
902
949
SharedHandle<ValueBase> GetUrisRpcMethod::process
903
950
(const RpcRequest& req, DownloadEngine* e)
904
951
{
905
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
 
952
  const String* gidParam = checkRequiredParam<String>(req, 0);
 
953
 
 
954
  a2_gid_t gid = str2Gid(gidParam);
906
955
  SharedHandle<RequestGroup> group =
907
956
    findRequestGroup(e->getRequestGroupMan(), gid);
908
957
  if(!group) {
922
971
SharedHandle<ValueBase> GetPeersRpcMethod::process
923
972
(const RpcRequest& req, DownloadEngine* e)
924
973
{
925
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
 
974
  const String* gidParam = checkRequiredParam<String>(req, 0);
926
975
 
 
976
  a2_gid_t gid = str2Gid(gidParam);
927
977
  SharedHandle<RequestGroup> group =
928
978
    findRequestGroup(e->getRequestGroupMan(), gid);
929
979
  if(!group) {
944
994
SharedHandle<ValueBase> TellStatusRpcMethod::process
945
995
(const RpcRequest& req, DownloadEngine* e)
946
996
{
947
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
948
 
  
949
 
  const List* keysParam = req.getListParam(1);
 
997
  const String* gidParam = checkRequiredParam<String>(req, 0);
 
998
  const List* keysParam = checkParam<List>(req, 1);
 
999
 
 
1000
  a2_gid_t gid = str2Gid(gidParam);
950
1001
  std::vector<std::string> keys;
951
1002
  toStringList(std::back_inserter(keys), keysParam);
952
1003
 
987
1038
SharedHandle<ValueBase> TellActiveRpcMethod::process
988
1039
(const RpcRequest& req, DownloadEngine* e)
989
1040
{
990
 
  const List* keysParam = req.getListParam(0);
 
1041
  const List* keysParam = checkParam<List>(req, 0);
991
1042
  std::vector<std::string> keys;
992
1043
  toStringList(std::back_inserter(keys), keysParam);
993
1044
  SharedHandle<List> list = List::g();
1052
1103
SharedHandle<ValueBase> RemoveDownloadResultRpcMethod::process
1053
1104
(const RpcRequest& req, DownloadEngine* e)
1054
1105
{
1055
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
 
1106
  const String* gidParam = checkRequiredParam<String>(req, 0);
 
1107
 
 
1108
  a2_gid_t gid = str2Gid(gidParam);
1056
1109
  if(!e->getRequestGroupMan()->removeDownloadResult(gid)) {
1057
1110
    throw DL_ABORT_EX
1058
1111
      (fmt("Could not remove download result of GID#%s",
1064
1117
SharedHandle<ValueBase> ChangeOptionRpcMethod::process
1065
1118
(const RpcRequest& req, DownloadEngine* e)
1066
1119
{
1067
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
 
1120
  const String* gidParam = checkRequiredParam<String>(req, 0);
 
1121
  const Dict* optsParam = checkRequiredParam<Dict>(req, 1);
1068
1122
 
 
1123
  a2_gid_t gid = str2Gid(gidParam);
1069
1124
  SharedHandle<RequestGroup> group =
1070
1125
    findRequestGroup(e->getRequestGroupMan(), gid);
1071
1126
  if(!group) {
1074
1129
           util::itos(gid).c_str()));
1075
1130
  }
1076
1131
  SharedHandle<Option> option(new Option());
1077
 
  const Dict* optionsParam = req.getDictParam(1);
1078
 
  if(optionsParam) {
1079
 
    gatherChangeableOption(option, optionsParam);
1080
 
    applyChangeableOption(group->getOption().get(), option.get());
1081
 
    if(option->defined(PREF_MAX_DOWNLOAD_LIMIT)) {
1082
 
      group->setMaxDownloadSpeedLimit
1083
 
        (option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT));
1084
 
    }
1085
 
    if(option->defined(PREF_MAX_UPLOAD_LIMIT)) {
1086
 
      group->setMaxUploadSpeedLimit(option->getAsInt(PREF_MAX_UPLOAD_LIMIT));
1087
 
    }
 
1132
  gatherChangeableOption(option, optsParam);
 
1133
  applyChangeableOption(group->getOption().get(), option.get());
 
1134
  if(option->defined(PREF_MAX_DOWNLOAD_LIMIT)) {
 
1135
    group->setMaxDownloadSpeedLimit
 
1136
      (option->getAsInt(PREF_MAX_DOWNLOAD_LIMIT));
 
1137
  }
 
1138
  if(option->defined(PREF_MAX_UPLOAD_LIMIT)) {
 
1139
    group->setMaxUploadSpeedLimit(option->getAsInt(PREF_MAX_UPLOAD_LIMIT));
 
1140
  }
1088
1141
#ifdef ENABLE_BITTORRENT
1089
 
    BtObject btObject = e->getBtRegistry()->get(group->getGID());
1090
 
    if(!btObject.isNull()) {
1091
 
      if(option->defined(PREF_BT_MAX_PEERS)) {
1092
 
        btObject.btRuntime_->setMaxPeers(option->getAsInt(PREF_BT_MAX_PEERS));
1093
 
      }
 
1142
  BtObject btObject = e->getBtRegistry()->get(group->getGID());
 
1143
  if(!btObject.isNull()) {
 
1144
    if(option->defined(PREF_BT_MAX_PEERS)) {
 
1145
      btObject.btRuntime_->setMaxPeers(option->getAsInt(PREF_BT_MAX_PEERS));
1094
1146
    }
 
1147
  }
1095
1148
#endif // ENABLE_BITTORRENT
1096
 
  }
1097
1149
  return VLB_OK;
1098
1150
}
1099
1151
 
1100
1152
SharedHandle<ValueBase> ChangeGlobalOptionRpcMethod::process
1101
1153
(const RpcRequest& req, DownloadEngine* e)
1102
1154
{
1103
 
  const Dict* optionsParam = req.getDictParam(0);
1104
 
  if(!optionsParam) {
1105
 
    return VLB_OK;
1106
 
  }
 
1155
  const Dict* optsParam = checkRequiredParam<Dict>(req, 0);
 
1156
 
1107
1157
  SharedHandle<Option> option(new Option());
1108
 
  gatherChangeableGlobalOption(option, optionsParam);
 
1158
  gatherChangeableGlobalOption(option, optsParam);
1109
1159
  applyChangeableGlobalOption(e->getOption(), option.get());
1110
1160
 
1111
1161
  if(option->defined(PREF_MAX_OVERALL_DOWNLOAD_LIMIT)) {
1171
1221
SharedHandle<ValueBase> GetOptionRpcMethod::process
1172
1222
(const RpcRequest& req, DownloadEngine* e)
1173
1223
{
1174
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
 
1224
  const String* gidParam = checkRequiredParam<String>(req, 0);
1175
1225
 
 
1226
  a2_gid_t gid = str2Gid(gidParam);
1176
1227
  SharedHandle<RequestGroup> group =
1177
1228
    findRequestGroup(e->getRequestGroupMan(), gid);
1178
1229
  if(!group) {
1203
1254
SharedHandle<ValueBase> ChangePositionRpcMethod::process
1204
1255
(const RpcRequest& req, DownloadEngine* e)
1205
1256
{
1206
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
1207
 
  const Integer* posParam = req.getIntegerParam(1);
1208
 
  const String* howParam = req.getStringParam(2);
 
1257
  const String* gidParam = checkRequiredParam<String>(req, 0);
 
1258
  const Integer* posParam = checkRequiredParam<Integer>(req, 1);
 
1259
  const String* howParam = checkRequiredParam<String>(req, 2);
1209
1260
 
1210
 
  if(!posParam || !howParam) {
1211
 
    throw DL_ABORT_EX("Illegal argument.");
1212
 
  }
 
1261
  a2_gid_t gid = str2Gid(gidParam);
1213
1262
  int pos = posParam->i();
1214
1263
  const std::string& howStr = howParam->s();
1215
1264
  RequestGroupMan::HOW how;
1239
1288
SharedHandle<ValueBase> GetServersRpcMethod::process
1240
1289
(const RpcRequest& req, DownloadEngine* e)
1241
1290
{
1242
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
 
1291
  const String* gidParam = checkRequiredParam<String>(req, 0);
 
1292
 
 
1293
  a2_gid_t gid = str2Gid(gidParam);
1243
1294
  SharedHandle<RequestGroup> group =
1244
1295
    e->getRequestGroupMan()->findRequestGroup(gid);
1245
1296
  if(!group) {
1278
1329
SharedHandle<ValueBase> ChangeUriRpcMethod::process
1279
1330
(const RpcRequest& req, DownloadEngine* e)
1280
1331
{
1281
 
  a2_gid_t gid = getRequiredGidParam(req, 0);
1282
 
  const Integer* indexParam = req.getIntegerParam(1);
1283
 
  const List* delUrisParam = req.getListParam(2);
1284
 
  const List* addUrisParam = req.getListParam(3);
1285
 
  if(!indexParam || !delUrisParam || ! addUrisParam) {
1286
 
    throw DL_ABORT_EX("Bad request");
1287
 
  }
1288
 
  size_t pos = 0;
1289
 
  bool posGiven = false;
1290
 
  getPosParam(req, 4, posGiven, pos);
 
1332
  const String* gidParam = checkRequiredParam<String>(req, 0);
 
1333
  const Integer* indexParam = checkRequiredParam<Integer>(req, 1);
 
1334
  const List* delUrisParam = checkRequiredParam<List>(req, 2);
 
1335
  const List* addUrisParam = checkRequiredParam<List>(req, 3);
 
1336
  const Integer* posParam = checkParam<Integer>(req, 4);
1291
1337
 
 
1338
  a2_gid_t gid = str2Gid(gidParam);
 
1339
  bool posGiven = checkPosParam(posParam);
 
1340
  size_t pos = posGiven ? posParam->i() : 0;
1292
1341
  size_t index = indexParam->i()-1;
1293
1342
  SharedHandle<RequestGroup> group =
1294
1343
    findRequestGroup(e->getRequestGroupMan(), gid);
1306
1355
  size_t delcount = 0;
1307
1356
  for(List::ValueType::const_iterator i = delUrisParam->begin(),
1308
1357
        eoi = delUrisParam->end(); i != eoi; ++i) {
1309
 
    const String* uri = asString(*i);
 
1358
    const String* uri = downcast<String>(*i);
1310
1359
    if(uri && s->removeUri(uri->s())) {
1311
1360
      ++delcount;
1312
1361
    }
1315
1364
  if(posGiven) {
1316
1365
    for(List::ValueType::const_iterator i = addUrisParam->begin(),
1317
1366
          eoi = addUrisParam->end(); i != eoi; ++i) {
1318
 
      const String* uri = asString(*i);
 
1367
      const String* uri = downcast<String>(*i);
1319
1368
      if(uri && s->insertUri(uri->s(), pos)) {
1320
1369
        ++addcount;
1321
1370
        ++pos;
1324
1373
  } else {
1325
1374
    for(List::ValueType::const_iterator i = addUrisParam->begin(),
1326
1375
          eoi = addUrisParam->end(); i != eoi; ++i) {
1327
 
      const String* uri = asString(*i);
 
1376
      const String* uri = downcast<String>(*i);
1328
1377
      if(uri && s->addUri(uri->s())) {
1329
1378
        ++addcount;
1330
1379
      }
1383
1432
SharedHandle<ValueBase> SystemMulticallRpcMethod::process
1384
1433
(const RpcRequest& req, DownloadEngine* e)
1385
1434
{
1386
 
  const List* methodSpecs = req.getListParam(0);
1387
 
  if(!methodSpecs) {
1388
 
    throw DL_ABORT_EX("Illegal argument. One item list is expected.");
1389
 
  }
 
1435
  const List* methodSpecs = checkRequiredParam<List>(req, 0);
1390
1436
  SharedHandle<List> list = List::g();
1391
1437
  for(List::ValueType::const_iterator i = methodSpecs->begin(),
1392
1438
        eoi = methodSpecs->end(); i != eoi; ++i) {
1393
 
    const Dict* methodDict = asDict(*i);
 
1439
    const Dict* methodDict = downcast<Dict>(*i);
1394
1440
    if(!methodDict) {
1395
1441
      list->append(createErrorResponse
1396
1442
                   (DL_ABORT_EX("system.multicall expected struct."), req));
1397
1443
      continue;
1398
1444
    }
1399
 
    const String* methodName = asString(methodDict->get(KEY_METHOD_NAME));
 
1445
    const String* methodName = downcast<String>(methodDict->get(KEY_METHOD_NAME));
1400
1446
    if(!methodName) {
1401
1447
      list->append(createErrorResponse
1402
1448
                   (DL_ABORT_EX("Missing methodName."), req));
1409
1455
    }
1410
1456
    const SharedHandle<ValueBase>& tempParamsList = methodDict->get(KEY_PARAMS);
1411
1457
    SharedHandle<List> paramsList;
1412
 
    if(asList(tempParamsList)) {
 
1458
    if(downcast<List>(tempParamsList)) {
1413
1459
      paramsList = static_pointer_cast<List>(tempParamsList);
1414
1460
    } else {
1415
1461
      paramsList = List::g();