| // Protocol Buffers - Google's data interchange format | |
| // Copyright 2023 Google LLC. All rights reserved. | |
| // | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file or at | |
| // https://developers.google.com/open-source/licenses/bsd | |
| #include "upb/wire/eps_copy_input_stream.h" | |
| #include <stdint.h> | |
| #include <string.h> | |
| #include "upb/base/error_handler.h" | |
| #include "upb/wire/internal/eps_copy_input_stream.h" | |
| // Must be last. | |
| #include "upb/port/def.inc" | |
| UPB_NORETURN UPB_NOINLINE void UPB_PRIVATE( | |
| upb_EpsCopyInputStream_ThrowMalformed)(upb_EpsCopyInputStream* e) { | |
| e->error = true; | |
| upb_ErrorHandler_ThrowError(e->err, kUpb_ErrorCode_Malformed); | |
| } | |
| const char* UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)( | |
| struct upb_EpsCopyInputStream* e, const char* ptr, int overrun) { | |
| if (overrun < e->limit) { | |
| // Need to copy remaining data into patch buffer. | |
| UPB_ASSERT(overrun < kUpb_EpsCopyInputStream_SlopBytes); | |
| const char* old_end = ptr; | |
| const char* new_start = &e->patch[overrun]; | |
| memset(&e->patch[kUpb_EpsCopyInputStream_SlopBytes], 0, | |
| kUpb_EpsCopyInputStream_SlopBytes); | |
| memcpy(e->patch, e->end, kUpb_EpsCopyInputStream_SlopBytes); | |
| ptr = new_start; | |
| e->end = &e->patch[kUpb_EpsCopyInputStream_SlopBytes]; | |
| e->limit -= kUpb_EpsCopyInputStream_SlopBytes; | |
| e->limit_ptr = e->end + e->limit; | |
| UPB_ASSERT(ptr < e->limit_ptr); | |
| e->input_delta = (uintptr_t)old_end - (uintptr_t)new_start; | |
| UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)( | |
| e, kUpb_EpsCopyInputStream_SlopBytes); | |
| return new_start; | |
| } else { | |
| UPB_ASSERT(overrun > e->limit); | |
| return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(e); | |
| } | |
| } |