| 495 | } |
| 496 | |
| 497 | void xs_socket_read(xsMachine *the) |
| 498 | { |
| 499 | xsSocket xss = xsmcGetHostDataValidate(xsThis, xs_socket_destructor); |
| 500 | xsType dstType; |
| 501 | int argc = xsmcArgc; |
| 502 | uint16 srcBytes; |
| 503 | unsigned char *srcData; |
| 504 | |
| 505 | if (NULL == xss) |
| 506 | xsUnknownError("read on closed socket"); |
| 507 | |
| 508 | if (!xss->buf || (xss->bufpos >= xss->buflen)) { |
| 509 | if (0 == argc) |
| 510 | xsResult = xsInteger(0); |
| 511 | else |
| 512 | xsUnknownError("nothing to read"); |
| 513 | return; |
| 514 | } |
| 515 | |
| 516 | srcData = xss->bufpos + (unsigned char *)xss->buf; |
| 517 | srcBytes = xss->buflen - xss->bufpos; |
| 518 | |
| 519 | if (0 == argc) { |
| 520 | xsResult = xsInteger(srcBytes); |
| 521 | return; |
| 522 | } |
| 523 | |
| 524 | // address limiter argument (count or terminator) |
| 525 | if (argc > 1) { |
| 526 | xsType limiterType = xsmcTypeOf(xsArg(1)); |
| 527 | if ((xsNumberType == limiterType) || (xsIntegerType == limiterType)) { |
| 528 | uint16 count = xsmcToInteger(xsArg(1)); |
| 529 | if (count < srcBytes) |
| 530 | srcBytes = count; |
| 531 | } |
| 532 | else |
| 533 | if (xsStringType == limiterType) { |
| 534 | char *str = xsmcToString(xsArg(1)); |
| 535 | char terminator = c_read8(str); |
| 536 | if (terminator) { |
| 537 | unsigned char *t = c_strchr(srcData, terminator); |
| 538 | if (t) { |
| 539 | uint16 count = (t - srcData) + 1; // terminator included in result |
| 540 | if (count < srcBytes) |
| 541 | srcBytes = count; |
| 542 | } |
| 543 | } |
| 544 | } |
| 545 | else if (xsUndefinedType == limiterType) |
| 546 | ; |
| 547 | } |
| 548 | |
| 549 | // generate output |
| 550 | dstType = xsmcTypeOf(xsArg(0)); |
| 551 | |
| 552 | if (xsNullType == dstType) |
| 553 | xsResult = xsInteger(srcBytes); |
| 554 | else if (xsReferenceType == dstType) { |
nothing calls this directly
no test coverage detected