#include #include #ifndef __SCC_CORE_NO_MEM_PROBE_STREAM__ static int mem_probe_stream_consume(scc_probe_stream_t *_stream) { Assert(_stream != null); scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream; if (stream->curr_pos >= stream->data_length) { return scc_stream_eof; } unsigned char ch = stream->data[stream->curr_pos++]; // 如果探针位置落后于当前读取位置,则更新探针位置 if (stream->probe_pos < stream->curr_pos) { stream->probe_pos = stream->curr_pos; } return (int)ch; } static int mem_probe_stream_peek(scc_probe_stream_t *_stream) { Assert(_stream != null); scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream; if (stream->probe_pos >= stream->data_length) { return scc_stream_eof; } // 只查看而不移动探针位置 return (int)(unsigned char)stream->data[stream->probe_pos]; } static int mem_probe_stream_next(scc_probe_stream_t *_stream) { Assert(_stream != null); scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream; if (stream->probe_pos >= stream->data_length) { return scc_stream_eof; } // 返回探针位置的字符,并将探针位置向前移动 int ch = (int)(unsigned char)stream->data[stream->probe_pos]; stream->probe_pos++; return ch; } static void mem_probe_stream_sync(scc_probe_stream_t *_stream) { Assert(_stream != null); scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream; // 移动头指针到探针位置(消费已查看的字符) if (stream->probe_pos > stream->curr_pos) { stream->curr_pos = stream->probe_pos; } } static cbool mem_probe_stream_back(scc_probe_stream_t *_stream) { Assert(_stream != null); scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream; // 只能回退一个字符,且不能回退到探针位置之前 if (stream->curr_pos == 0 || stream->curr_pos <= stream->probe_pos) { return false; } stream->curr_pos--; return true; } static usize mem_probe_stream_read_buf(scc_probe_stream_t *_stream, char *buffer, usize count) { Assert(_stream != null); scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream; if (buffer == null) { LOG_WARN("Buffer is null"); return 0; } usize remaining = stream->data_length - stream->curr_pos; usize to_read = (remaining < count) ? remaining : count; if (to_read > 0) { scc_memcpy(buffer, stream->data + stream->curr_pos, to_read); stream->curr_pos += to_read; // 更新探针位置 if (stream->probe_pos < stream->curr_pos) { stream->probe_pos = stream->curr_pos; } } else { LOG_WARN("Reading past end of stream [maybe count is too large or " "negative?]"); } return to_read; } static void mem_probe_stream_reset(scc_probe_stream_t *_stream) { Assert(_stream != null); scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream; // 重置探针位置到头指针位置 stream->probe_pos = stream->curr_pos; } static cbool mem_probe_stream_is_at_end(scc_probe_stream_t *_stream) { Assert(_stream != null); scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream; return stream->curr_pos >= stream->data_length; } static void mem_probe_stream_drop(scc_probe_stream_t *_stream) { Assert(_stream != null); scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream; scc_cstring_free(&stream->stream.name); if (stream->owned) { scc_free((void *)stream->data); stream->data = null; } } scc_probe_stream_t *scc_mem_probe_stream_init(scc_mem_probe_stream_t *stream, const char *data, usize length, cbool owned) { if (stream == null || data == null) { LOG_ERROR("param error"); return null; } if (length == 0) { LOG_WARN("input memory is empty"); owned = false; } stream->owned = owned; stream->data = data; stream->data_length = length; stream->curr_pos = 0; stream->probe_pos = 0; stream->stream.name = scc_cstring_from_cstr("mem_probe_stream"); // 设置函数指针 stream->stream.consume = mem_probe_stream_consume; stream->stream.peek = mem_probe_stream_peek; stream->stream.next = mem_probe_stream_next; stream->stream.sync = mem_probe_stream_sync; stream->stream.back = mem_probe_stream_back; stream->stream.read_buf = mem_probe_stream_read_buf; stream->stream.reset = mem_probe_stream_reset; stream->stream.is_at_end = mem_probe_stream_is_at_end; stream->stream.drop = mem_probe_stream_drop; return (scc_probe_stream_t *)stream; } static void scc_owned_mem_stream_drop(scc_probe_stream_t *_stream) { scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)_stream; mem_probe_stream_drop(_stream); scc_free(stream); } scc_probe_stream_t *scc_mem_probe_stream_alloc(const char *data, usize length, cbool owned) { scc_mem_probe_stream_t *stream = (scc_mem_probe_stream_t *)scc_malloc(sizeof(scc_mem_probe_stream_t)); if (stream == null) { return null; } scc_probe_stream_t *ret = scc_mem_probe_stream_init(stream, data, length, owned); stream->stream.drop = scc_owned_mem_stream_drop; Assert(ret != null); return ret; } #endif /* __SCC_CORE_NO_MEM_PROBE_STREAM__ */