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