source: gsdl/trunk/runtime-src/src/oaiservr/resumptiontoken.cpp@ 16708

Last change on this file since 16708 was 15380, checked in by mdewsnip, 16 years ago

Three fixes to the resumption token code to prevent crashes when specifying a set that isn't at collection-level. By DL Consulting Ltd.

  • Property svn:keywords set to Author Date Id Revision
File size: 3.9 KB
Line 
1#include "resumptiontoken.h"
2#include "oaitools.h"
3
4/**
5 * Generate an initial resumption token from some basic details.
6 *
7 * TODO: add optional argument to set the server name.
8 */
9ResumptionToken::ResumptionToken(const text_t &collection, const text_t &node,
10 const text_t &buildDate)
11{ this->collection = collection;
12 this->browseNode = node;
13 this->buildDate = buildDate;
14 this->startItem = 0;
15}
16
17/**
18 * Generate a resumption token from a URN-style format.
19 *
20 * See getToken() for details of the format.
21 *
22 * TODO: support inclusion of an optional server name.
23 */
24ResumptionToken::ResumptionToken(const text_t &URN)
25{ text_t::const_iterator first = URN.begin();
26 text_t::const_iterator last = URN.end();
27 text_t::const_iterator second;
28
29 this->collection = "";
30 this->browseNode = "";
31 this->startItem = -1;
32
33 text_t::const_iterator here = findchar(first, last, ':');
34 if (here == first) {
35 return;
36 }
37
38 text_t oainamespace = substr(first, here);
39 if (oainamespace != "gsdloai") {
40 return;
41 }
42
43 // increment past the first colon to get the location
44 first = ++here;
45
46 // get the collection, browseNode
47 here = findchar(first, last, ',');
48 if (here == last) {
49 return;
50 }
51
52 second = findchar(first, here,'.');
53 this->collection = substr(first, second);
54
55 // cerr << "Collection " << this->collection << endl;
56
57 if (second != here) {
58 // get past the '.'
59 ++second;
60 this->browseNode = substr(second, here);
61 }
62 else {
63 first = here;
64 }
65 // get past the ','
66 first = ++here;
67
68 // find the second ',' to delimit the position stack
69 second = findchar(first, last, ',');
70
71 // if not found, then get build and start item
72 if (second != first) {
73 // extract list and step past it
74 text_t offsetList = substr(first, second);
75 first = ++second;
76
77 do {
78 second = findchar(offsetList.begin(), offsetList.end(), '.');
79 if (second == offsetList.end())
80 break;
81
82 // extract and push the next position
83 text_t thisPos = substr(offsetList.begin(), second);
84 this->browsePosition.push_back(thisPos.getint());
85
86 // pop the position from the list
87 offsetList = substr(++second, offsetList.end());
88 } while (true);
89 this->browsePosition.push_back(offsetList.getint());
90 }
91 else {
92 first ++;
93 }
94
95 // now find the build date marker
96 here = findchar(first, last, '-');
97 if (here == first) {
98 this->startItem = substr(first, last).getint();
99 }
100 else {
101 this->startItem = substr(first, here).getint();
102 this->buildDate = substr(++here, last);
103 }
104}
105
106/**
107 * Get a resumption token in text_t format.
108 *
109 * Resumption tokens are in the format:
110 *
111 * gsdloai:<serverName>:collectionname.browseNode,startItem-BuildDate
112 *
113 * The resumption token format does not currently implement the use of
114 * the optional <serverName> item; it is taken to default to the name of
115 * the receiving server.
116 *
117 * TODO: add server identity as an optional argument; also change
118 * ResumptionToken(text_t &) accordingly.
119 */
120text_t ResumptionToken::getToken()
121{ text_t reply = "gsdloai:";
122 reply = reply + this->collection;
123 if (this->browseNode != "") {
124 reply = reply + "." + this->browseNode;
125 }
126 reply = reply + ",";
127 for (int i = 0; i < this->browsePosition.size(); i++) {
128 if (i != 0) {
129 reply.append(".");
130 }
131 reply.appendint(i);
132 }
133 reply = reply + ",";
134 reply.append(this->startItem);
135 reply = reply + "-" + buildDate;
136
137 return reply;
138}
139
140/**
141 * Update the position of an existing resumption token
142 */
143void ResumptionToken::setPosition(const text_t &node, int startItem)
144{ this->browseNode = node;
145 this->startItem = startItem;
146}
147
148/**
149 * Check if the resumption token is valid - only a very primitive
150 * check is done here; one ought to check for an existing collection
151 * and valid browse Node, build date and startItem
152 *
153 * TODO: implement improved validation checking.
154 */
155bool ResumptionToken::isValid()
156{ return this->collection != "";
157}
Note: See TracBrowser for help on using the repository browser.