* xmlCharEncInput: * @input: a parser input buffer * * Generic front-end for the encoding handler on parser input * * Returns the number of bytes written or an XML_ENC_ERR code. */
| 2307 | * Returns the number of bytes written or an XML_ENC_ERR code. |
| 2308 | */ |
| 2309 | int |
| 2310 | xmlCharEncInput(xmlParserInputBufferPtr input) |
| 2311 | { |
| 2312 | int ret; |
| 2313 | size_t avail; |
| 2314 | size_t toconv; |
| 2315 | int c_in; |
| 2316 | int c_out; |
| 2317 | xmlBufPtr in; |
| 2318 | xmlBufPtr out; |
| 2319 | const xmlChar *inData; |
| 2320 | size_t inTotal = 0; |
| 2321 | |
| 2322 | if ((input == NULL) || (input->encoder == NULL) || |
| 2323 | (input->buffer == NULL) || (input->raw == NULL)) |
| 2324 | return(XML_ENC_ERR_INTERNAL); |
| 2325 | out = input->buffer; |
| 2326 | in = input->raw; |
| 2327 | |
| 2328 | toconv = xmlBufUse(in); |
| 2329 | if (toconv == 0) |
| 2330 | return (0); |
| 2331 | inData = xmlBufContent(in); |
| 2332 | inTotal = 0; |
| 2333 | |
| 2334 | do { |
| 2335 | c_in = toconv > INT_MAX / 2 ? INT_MAX / 2 : toconv; |
| 2336 | |
| 2337 | avail = xmlBufAvail(out); |
| 2338 | if (avail > INT_MAX) |
| 2339 | avail = INT_MAX; |
| 2340 | if (avail < 4096) { |
| 2341 | if (xmlBufGrow(out, 4096) < 0) { |
| 2342 | input->error = XML_ERR_NO_MEMORY; |
| 2343 | return(XML_ENC_ERR_MEMORY); |
| 2344 | } |
| 2345 | avail = xmlBufAvail(out); |
| 2346 | } |
| 2347 | |
| 2348 | c_in = toconv; |
| 2349 | c_out = avail; |
| 2350 | ret = xmlEncInputChunk(input->encoder, xmlBufEnd(out), &c_out, |
| 2351 | inData, &c_in); |
| 2352 | inTotal += c_in; |
| 2353 | inData += c_in; |
| 2354 | toconv -= c_in; |
| 2355 | xmlBufAddLen(out, c_out); |
| 2356 | } while (ret == XML_ENC_ERR_SPACE); |
| 2357 | |
| 2358 | xmlBufShrink(in, inTotal); |
| 2359 | |
| 2360 | if (input->rawconsumed > ULONG_MAX - (unsigned long)c_in) |
| 2361 | input->rawconsumed = ULONG_MAX; |
| 2362 | else |
| 2363 | input->rawconsumed += c_in; |
| 2364 | |
| 2365 | if (((ret != 0) && (c_out == 0)) || |
| 2366 | (ret == XML_ENC_ERR_MEMORY)) { |
no test coverage detected