long rb_u_string_rindex(VALUE self, VALUE rbsubstring, long offset) { const struct rb_u_string *string = RVAL2USTRING(self); const struct rb_u_string *substring = RVAL2USTRING_ANY(rbsubstring); if (USTRING_LENGTH(string) < USTRING_LENGTH(substring)) return -1; const char *s = rb_u_string_begin_from_offset(string, offset); if (s == NULL) return -1; if (USTRING_LENGTH(substring) == 0) return offset; const char *begin = USTRING_STR(string); const char *t = USTRING_STR(substring); long t_length = USTRING_LENGTH(substring); while (s >= begin) { if (rb_memcmp(s, t, t_length) == 0) return u_pointer_to_offset(begin, s); s--; } return -1; }
VALUE rb_utf_chomp_bang(int argc, VALUE *argv, UNUSED(VALUE self)) { VALUE str, rs; rb_scan_args(argc, argv, "11", &str, &rs); if (RSTRING(str)->len == 0) return Qnil; if (argc == 1) { rs = rb_rs; if (rs == rb_default_rs) rb_utf_chomp_default(str); } if (NIL_P(rs)) return Qnil; StringValue(rs); long rs_len = RSTRING(rs)->len; if (rs_len == 0) return rb_utf_chomp_newlines(str); long len = RSTRING(str)->len; if (rs_len > len) return Qnil; char last_char = RSTRING(rs)->ptr[rs_len - 1]; if (rs_len == 1 && last_char == '\n') rb_utf_chomp_default(str); char *p = RSTRING(str)->ptr; if (p[len - 1] != last_char || (rs_len > 1 && rb_memcmp(RSTRING(rs)->ptr, p + len - rs_len, rs_len) != 0)) return Qnil; rb_str_modify(str); RSTRING(str)->len -= rs_len; RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; return str; }
EXPORT_DEF at_res_t at_read_result_classification (struct ringbuffer * rb, size_t len) { at_res_t at_res = RES_UNKNOWN; unsigned idx; for(idx = at_responses.ids_first; idx < at_responses.ids; idx++) { if (rb_memcmp (rb, at_responses.responses[idx].id, at_responses.responses[idx].idlen) == 0) { at_res = at_responses.responses[idx].res; break; } } switch (at_res) { case RES_SMS_PROMPT: len = 2; break; case RES_CMGR: len += 7; break; case RES_CSSI: len = 8; break; default: len += 1; break; } rb_read_upd (rb, len); /* ast_debug (5, "receive result '%s'\n", at_res2str (at_res)); */ return at_res; }
EXPORT_DEF int at_read_result_iov (const char * dev, int * read_result, struct ringbuffer* rb, struct iovec iov[2]) { int iovcnt = 0; int res; size_t s; s = rb_used (rb); if (s > 0) { /* ast_debug (5, "[%s] d_read_result %d len %d input [%.*s]\n", dev, *read_result, s, MIN(s, rb->size - rb->read), (char*)rb->buffer + rb->read); */ if (*read_result == 0) { res = rb_memcmp (rb, "\r\n", 2); if (res == 0) { rb_read_upd (rb, 2); *read_result = 1; return at_read_result_iov (dev, read_result, rb, iov); } else if (res > 0) { if (rb_memcmp (rb, "\n", 1) == 0) { ast_debug (5, "[%s] multiline response\n", dev); rb_read_upd (rb, 1); return at_read_result_iov (dev, read_result, rb, iov); } if (rb_read_until_char_iov (rb, iov, '\r') > 0) { s = iov[0].iov_len + iov[1].iov_len + 1; } rb_read_upd (rb, s); return at_read_result_iov (dev, read_result, rb, iov); } return 0; } else { if (rb_memcmp (rb, "+CSSI:", 6) == 0) { iovcnt = rb_read_n_iov (rb, iov, 8); if (iovcnt > 0) { *read_result = 0; } return iovcnt; } else if (rb_memcmp (rb, "\r\n+CSSU:", 8) == 0 || rb_memcmp (rb, "\r\n+CMS ERROR:", 13) == 0 || rb_memcmp (rb, "\r\n+CMGS:", 8) == 0) { rb_read_upd (rb, 2); return at_read_result_iov (dev, read_result, rb, iov); } else if (rb_memcmp (rb, "> ", 2) == 0) { *read_result = 0; return rb_read_n_iov (rb, iov, 2); } else if (rb_memcmp (rb, "+CMGR:", 6) == 0 || rb_memcmp (rb, "+CNUM:", 6) == 0 || rb_memcmp (rb, "ERROR+CNUM:", 11) == 0 || rb_memcmp (rb, "+CLCC:", 6) == 0) { iovcnt = rb_read_until_mem_iov (rb, iov, "\n\r\nOK\r\n", 7); if (iovcnt > 0) { *read_result = 0; } return iovcnt; } else { iovcnt = rb_read_until_mem_iov (rb, iov, "\r\n", 2); if (iovcnt > 0) { *read_result = 0; s = iov[0].iov_len + iov[1].iov_len + 1; return rb_read_n_iov (rb, iov, s); } } } } return 0; }