1 /*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "stdafx.h"
17
18 #include <zorba/transcode_stream.h>
19
20 #include "diagnostics/assert.h"
21 #include "diagnostics/xquery_diagnostics.h"
22
23 #include "runtime/fetch/fetch.h"
24 #include "system/globalenv.h"
25 #include "store/api/item_factory.h"
26
27 #include "context/static_context.h"
28 #include "context/uri_resolver.h"
29
30
31 namespace zorba {
32
33 /*******************************************************************************
34 ********************************************************************************/
35 std::auto_ptr<internal::StreamResource>
getFetchResource(const store::Item_t & aUri,const store::Item_t & aKind,const static_context * aSctx,const QueryLoc & aLoc)36 getFetchResource(
37 const store::Item_t& aUri,
38 const store::Item_t& aKind,
39 const static_context* aSctx,
40 const QueryLoc& aLoc)
41 {
42 internal::EntityData::Kind lKind;
43 zstring lKindStr = aKind->getStringValue();
44
45 // Figure out the EntityKind (any better way to do this?)
46 if ( ! lKindStr.compare("SOME_CONTENT")) {
47 lKind = internal::EntityData::SOME_CONTENT;
48 }
49 else if ( ! lKindStr.compare("SCHEMA")) {
50 lKind = internal::EntityData::SCHEMA;
51 }
52 else if ( ! lKindStr.compare("MODULE")) {
53 lKind = internal::EntityData::MODULE;
54 }
55 #ifndef ZORBA_NO_FULL_TEXT
56 else if ( ! lKindStr.compare("THESAURUS")) {
57 lKind = internal::EntityData::THESAURUS;
58 }
59 else if ( ! lKindStr.compare("STOP_WORDS")) {
60 lKind = internal::EntityData::STOP_WORDS;
61 }
62 #endif /* ZORBA_NO_FULL_TEXT */
63 else {
64 throw XQUERY_EXCEPTION(
65 zerr::ZXQP0026_INVALID_ENUM_VALUE,
66 ERROR_PARAMS(lKindStr, "entityKind"),
67 ERROR_LOC(aLoc));
68 }
69
70 try {
71 // ask the uri mappers and resolvers to give
72 // me a resource of specified kind
73 zstring lErrorMessage;
74
75 std::auto_ptr<internal::Resource> lRes = aSctx->resolve_uri(
76 aUri->getStringValue(),
77 lKind,
78 lErrorMessage);
79
80 std::auto_ptr<internal::StreamResource> lStreamRes(
81 dynamic_cast<internal::StreamResource*>(lRes.get()));
82
83 if ( !lStreamRes.get() )
84 {
85 throw XQUERY_EXCEPTION(
86 zerr::ZXQP0025_COULD_NOT_FETCH_RESOURCE,
87 ERROR_PARAMS(
88 aUri->getStringValue(),
89 ZED(ZXQP0025_RESOURCE_NOT_FOUND)
90 ),
91 ERROR_LOC( aLoc )
92 );
93 }
94
95 lRes.release();
96
97 return lStreamRes;
98
99 } catch (ZorbaException const& e) {
100 throw XQUERY_EXCEPTION(
101 zerr::ZXQP0025_COULD_NOT_FETCH_RESOURCE,
102 ERROR_PARAMS( aUri->getStringValue(), e.what() ),
103 ERROR_LOC( aLoc )
104 );
105 }
106 }
107
108 /*******************************************************************************
109 ********************************************************************************/
110 void
destroyStream(std::istream & aStream)111 FetchContentIterator::destroyStream(std::istream& aStream)
112 {
113 delete &aStream;
114 }
115
116 bool
nextImpl(store::Item_t & result,PlanState & aPlanState) const117 FetchContentIterator::nextImpl(
118 store::Item_t& result,
119 PlanState& aPlanState) const
120 {
121 store::Item_t lUri;
122 store::Item_t lEntityKind;
123 store::Item_t lEncoding;
124 zstring lEncodingStr;
125 std::auto_ptr<internal::StreamResource> lRes;
126
127 PlanIteratorState* state;
128 DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
129
130 consumeNext(lUri, theChildren[0].getp(), aPlanState);
131 consumeNext(lEntityKind, theChildren[1].getp(), aPlanState);
132 consumeNext(lEncoding, theChildren[2].getp(), aPlanState);
133
134 lEncodingStr = lEncoding->getStringValue();
135
136 lRes = getFetchResource(lUri, lEntityKind, theSctx, loc);
137
138 if (transcode::is_necessary(lEncodingStr.c_str()))
139 {
140 if (!transcode::is_supported(lEncodingStr.c_str()))
141 {
142 throw XQUERY_EXCEPTION(
143 zerr::ZXQP0006_UNKNOWN_ENCODING,
144 ERROR_PARAMS( lEncodingStr.c_str() ),
145 ERROR_LOC( loc )
146 );
147 }
148 transcode::attach(*lRes->getStream(), lEncodingStr.c_str());
149 }
150
151 // return the resource in a streamable string. This transfers memory
152 // ownership of the istream (via its StreamReleaser) to the StreamableString
153 // object, so we then remove the StreamReleaser from the StreamResource.
154 GENV_ITEMFACTORY->createStreamableString(
155 result,
156 *lRes->getStream(),
157 lRes->getStreamReleaser(),
158 lRes->isStreamSeekable()
159 );
160 lRes->setStreamReleaser(nullptr);
161
162 STACK_PUSH(result != NULL, state);
163
164 STACK_END(state);
165 }
166
167
168 /*******************************************************************************
169 ********************************************************************************/
170 void
destroyStream(std::istream & aStream)171 FetchContentBinaryIterator::destroyStream(std::istream& aStream)
172 {
173 delete &aStream;
174 }
175
176 bool
nextImpl(store::Item_t & result,PlanState & aPlanState) const177 FetchContentBinaryIterator::nextImpl(
178 store::Item_t& result,
179 PlanState& aPlanState) const
180 {
181 store::Item_t lUri;
182 store::Item_t lEntityKind;
183 std::auto_ptr<internal::StreamResource> lRes;
184
185 PlanIteratorState* state;
186 DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
187
188 consumeNext(lUri, theChildren[0].getp(), aPlanState);
189 consumeNext(lEntityKind, theChildren[1].getp(), aPlanState);
190
191 lRes = getFetchResource(lUri, lEntityKind, theSctx, loc);
192
193 // return the resource in a streamable base64. This transfers memory
194 // ownership of the istream (via its StreamReleaser) to the StreamableBase64BinaryItem
195 // object, so we then remove the StreamReleaser from the StreamResource.
196 GENV_ITEMFACTORY->createStreamableBase64Binary(
197 result,
198 *lRes->getStream(),
199 lRes->getStreamReleaser(),
200 lRes->isStreamSeekable(),
201 false
202 );
203 lRes->setStreamReleaser(nullptr);
204
205 STACK_PUSH(result != NULL, state);
206
207 STACK_END(state);
208 }
209
210
211 /*******************************************************************************
212 ********************************************************************************/
213 bool
nextImpl(store::Item_t & result,PlanState & aPlanState) const214 FetchContentTypeIterator::nextImpl(
215 store::Item_t& result,
216 PlanState& aPlanState) const
217 {
218 PlanIteratorState* state;
219 DEFAULT_STACK_INIT(PlanIteratorState, state, aPlanState);
220
221 STACK_PUSH(false, state);
222
223 STACK_END(state);
224 }
225
226 } /* namespace zorba */
227 /* vim:set et sw=2 ts=2: */
228