17993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2d6ff721eb077759ac8f672dc15094e65968bc45eBill Richardson * Use of this source code is governed by a BSD-style license that can be 3d6ff721eb077759ac8f672dc15094e65968bc45eBill Richardson * found in the LICENSE file. 4d6ff721eb077759ac8f672dc15094e65968bc45eBill Richardson * 537dff84dbbe7fc683fce04382e68eca7aa19ea83Gaurav Shah * Implementations of stateful memory operations. 6d6ff721eb077759ac8f672dc15094e65968bc45eBill Richardson */ 7d6ff721eb077759ac8f672dc15094e65968bc45eBill Richardson 80c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson#include "sysincludes.h" 90c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson 10d6ff721eb077759ac8f672dc15094e65968bc45eBill Richardson#include "stateful_util.h" 11f302905224a346718910e56f5f1593d4b19253f1Randall Spangler#include "utility.h" 12d6ff721eb077759ac8f672dc15094e65968bc45eBill Richardson 137993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spanglervoid StatefulInit(MemcpyState *state, void *buf, uint64_t len) 147993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler{ 157993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->remaining_buf = buf; 167993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->remaining_len = len; 177993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->overrun = 0; 181f5d53f7bd4dc590b47f21f858d021ac53190a17Randall Spangler} 191f5d53f7bd4dc590b47f21f858d021ac53190a17Randall Spangler 207993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spanglervoid *StatefulSkip(MemcpyState *state, uint64_t len) 217993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler{ 227993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler if (state->overrun) 237993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler return NULL; 247993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler if (len > state->remaining_len) { 257993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->overrun = 1; 267993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler return NULL; 277993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler } 287993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->remaining_buf += len; 297993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->remaining_len -= len; 307993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler return state; /* Must return something non-NULL. */ 31a9f17aa44aa7beae7d9cdcf0bcb5ef588f128d73Randall Spangler} 32a9f17aa44aa7beae7d9cdcf0bcb5ef588f128d73Randall Spangler 337993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spanglervoid *StatefulMemcpy(MemcpyState *state, void *dst, uint64_t len) 347993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler{ 357993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler if (state->overrun) 367993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler return NULL; 377993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler if (len > state->remaining_len) { 387993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->overrun = 1; 397993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler return NULL; 407993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler } 417993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler Memcpy(dst, state->remaining_buf, len); 427993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->remaining_buf += len; 437993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->remaining_len -= len; 447993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler return dst; 45d6ff721eb077759ac8f672dc15094e65968bc45eBill Richardson} 46d6ff721eb077759ac8f672dc15094e65968bc45eBill Richardson 477993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spanglerconst void *StatefulMemcpy_r(MemcpyState *state, const void *src, uint64_t len) 487993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler{ 497993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler if (state->overrun) 507993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler return NULL; 517993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler if (len > state->remaining_len) { 527993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->overrun = 1; 537993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler return NULL; 547993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler } 557993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler Memcpy(state->remaining_buf, src, len); 567993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->remaining_buf += len; 577993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->remaining_len -= len; 587993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler return src; 59d6ff721eb077759ac8f672dc15094e65968bc45eBill Richardson} 60d6ff721eb077759ac8f672dc15094e65968bc45eBill Richardson 617993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spanglerconst void *StatefulMemset_r(MemcpyState *state, const uint8_t val, 627993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler uint64_t len) 637993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler{ 647993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler if (state->overrun) 657993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler return NULL; 667993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler if (len > state->remaining_len) { 677993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->overrun = 1; 687993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler return NULL; 697993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler } 707993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler Memset(state->remaining_buf, val, len); 717993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->remaining_buf += len; 727993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler state->remaining_len -= len; 737993f257af87c7c38cdc71b76bc67cde6c3cdbcaRandall Spangler return state; /* Must return something non-NULL. */ 74d6ff721eb077759ac8f672dc15094e65968bc45eBill Richardson} 75