⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 checkpoint.cc

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 CC
字号:
#include <stdarg.h>#include <stdio.h>#include <string.h>#include <time.h>#include "checkpoint.hh"#include "inttypes.hh"#include "serial.hh"#include "sulima.hh"const char *Checkpoint::EOFError::what() const{    if (cp.fp && feof(cp.fp)) {	// Premature end of file.	Checkpoint::SyntaxError err(cp, "unexpected end of file");	return err.what();    }    else {	// A genuine file error.	return FileError::what();    }}Checkpoint::SyntaxError::SyntaxError(Checkpoint &cp)    : Error("Bad checkpoint file \"%s\" (line %d)", cp.name(), cp.lineno()){    // otherwise empty}Checkpoint::SyntaxError::SyntaxError(Checkpoint &cp, const char *cause, ...){    char buf[sizeof(msg)];    va_list ap;    va_start(ap, cause);    vecho(buf, sizeof(buf), cause, ap);    va_end(ap);    if (echo(msg, sizeof(msg), "Bad checkpoint file \"%s\" (line %d: %s)",	     cp.name(), cp.lineno(), buf) >= sizeof(msg))    {	strcpy(msg + sizeof(msg) - 5, "...");    }}// Function used to implement 8 and 16-bit integer extractors. (max) is one// larger than the maximum return value. (sign) is true for signed types.  The// delimiter character after the last digit is considered part of the integer.intCheckpoint::extract_int(int max, bool sign){    int c = getc(fp);    bool neg;    // Read the sign.    if (!sign || c != '-')	neg = false;    else {	neg = true;	c = getc(fp);    }    // There must be at least one digit.    if (c < '0' || c > '9') {	if (c == EOF)	    throw EOFError(*this);	else if (!sign)	    throw SyntaxError(*this, "an unsigned integer expected");	else {	    throw SyntaxError(*this, "an integer expected");	}    }    // Parse the integer.    int x = 0;    do {	x = x * 10 + c - '0';	if (x >= max && (!neg || x > max))	    throw SyntaxError(*this, "integer too large");	c = getc(fp);    } while (c >= '0' && c <= '9');    if (c == EOF && ferror(fp))	throw EOFError(*this);    return (neg ? -x : x);}longCheckpoint::extract_long(long max, bool sign){    int c = getc(fp);    bool neg;    // Read the sign.    if (!sign || c != '-')	neg = false;    else {	neg = true;	c = getc(fp);    }    // There must be at least one digit.    if (c < '0' || c > '9') {	if (c == EOF)	    throw EOFError(*this);	else if (!sign)	    throw SyntaxError(*this, "an unsigned integer expected");	else {	    throw SyntaxError(*this, "an integer expected");	}    }    // Parse the integer.    long x = 0;    do {	x = x * 10 + c - '0';	if (x >= max && (!neg || x > max))	    throw SyntaxError(*this, "integer too large");	c = getc(fp);    } while (c >= '0' && c <= '9');    if (c == EOF && ferror(fp))	throw EOFError(*this);    return (neg ? -x : x);}// String inserter, complicated by the need (?) to maintain line numbers.Checkpoint&Checkpoint::operator<<(const char *s){    fputs(s, fp);    while ((s = strchr(s, '\n')) != 0)	++ln;    return *this;}// Inserters for 64-bit integers. On 32 bit platforms, this is a bit of a hack// as C89 does not define a portable fprintf() format specifier for objects// larger than unsigned long.Checkpoint&Checkpoint::operator<<(UInt64 x){    if (sizeof(x) <= sizeof(unsigned long))	fprintf(fp, "%lu", (unsigned long)x);    else {	// Write x as multiple longs.	const UInt64 block = 1000000000UL;	unsigned long a = x % block; x /= block;	unsigned long b = x % block; x /= block;	unsigned long c = x;	if (c)	    fprintf(fp, "%lu%09lu%09lu", c, b, a);	else if (b)	    fprintf(fp, "%lu%09lu", b, a);	else {	    fprintf(fp, "%lu", a);	}    }    return *this;}Checkpoint&Checkpoint::operator<<(Int64 x){    if (sizeof(x) <= sizeof(long))	fprintf(fp, "%ld", (long)x);    else {	// Process the sign.	UInt64 ux;	if (x >= 0)	    ux = x;	else {	    ux = -x; // |x| is a valid UInt64, even if x == -2^63.	    putc('-', fp);	}	// Write x as multiple longs.	const UInt64 block = 1000000000UL;	unsigned long a = ux % block; ux /= block;	unsigned long b = ux % block; ux /= block;	unsigned long c = ux;	if (c)	    fprintf(fp, "%lu%09lu%09lu", c, b, a);	else if (b)	    fprintf(fp, "%lu%09lu", b, a);	else {	    fprintf(fp, "%lu", a);	}    }    return *this;}// The below extractors are very unforgiving. No additional whitespaces are// tolerated before or after the token.Checkpoint&Checkpoint::operator>>(bool& b){    int c = getc(fp);    switch (c) {    case EOF:	throw EOFError(*this);    case '0':	b = false;	return *this;    case '1':	b = true;	return *this;    default:	throw SyntaxError(*this, "'0' or '1' expected");    }}Checkpoint&Checkpoint::operator>>(char *&s){    // The returned string is delimited by any of the characters in (s). It    // is dynamically allocated using new char[]. The returned string can be    // empty. The delimiter is considered part of the input string, and is    // replaced by '\0' in the result.    char buffer[4096]; // temporary buffer used for short strings    char *start = buffer, *p = start, *end = start + sizeof(buffer);    int c, start_ln = lineno();    for (;;) {	c = getc(fp);	if (c == EOF) {	    if (ferror(fp))		throw EOFError(*this);	    else {		// The delimiter is missing.		ln = start_ln;		throw SyntaxError(*this, "missing string delimiter (%#s)", s);	    }	}	if (c == '\n')	    ++ln;	if (p == end) {	    // The buffer is too small, so double its size.	    size_t n = end - start;	    char *buf = new char[n * 2];	    memcpy(buf, start, n);	    if (start != buffer)		delete start;	    start = buf;	    p = start + n;	    end = start + n * 2;	}	if (!strchr(s, c))	    *p++ = c;	else {	    *p++ = '\0';	    s = (start == buffer ? copy(start) : start);	    return *this;	}    }}Checkpoint&Checkpoint::operator>>(Int16& x){    if (sizeof(Int16) < sizeof(int))	x = extract_int(0x7fff + 1, true);    else	x = extract_long(0x7fffL + 1, true);    return *this;}Checkpoint&Checkpoint::operator>>(Int32& x){    if (sizeof(Int32) < sizeof(long))	x = extract_int(0x7fffffffL + 1, true);    else {	Int64 y; *this >> y;	if (y < -((Int64)1 << 31) || y > ((Int64)1 << 31) + 1)	    throw SyntaxError(*this, "integer too large");	x = y;    }    return *this;}Checkpoint&Checkpoint::operator>>(Int64& x){    int c = getc(fp);    bool neg;    // Read the sign.    if (c != '-')	neg = false;    else {	neg = true;	c = getc(fp);    }    // There must be at least one digit.    if (c < '0' || c > '9') {	if (c == EOF)	    throw EOFError(*this);	else {	    throw SyntaxError(*this, "an integer expected");	}    }    // Parse the integer.    UInt64 y = 0;    do {	UInt64 old = y;	y = y * 10 + c - '0';	if (old > y)	    throw SyntaxError(*this, "integer too large");	c = getc(fp);    } while (c >= '0' && c <= '9');    if (c == EOF && ferror(fp))	throw EOFError(*this);    if (neg) {	if (y > ((UInt64)1 << 63))	    throw SyntaxError(*this, "integer too large");	x = -y;    }    else {	if (y > ((UInt64)1 << 63) - 1)	    throw SyntaxError(*this, "integer too large");	x = y;    }    return *this;}Checkpoint&Checkpoint::operator>>(UInt16& x){    if (sizeof(UInt16) < sizeof(int))	x = extract_int(0xffff + 1, false);    else	x = extract_long(0xffffL + 1, false);    return *this;}Checkpoint&Checkpoint::operator>>(UInt32& x){    if (sizeof(Int32) < sizeof(long))	x = extract_int(0xffffffffL + 1, false);    else {	UInt64 y; *this >> y;	if (y > ((UInt64)1 >> 32) - 1)	    throw SyntaxError(*this, "integer too large");	x = y;    }    return *this;}Checkpoint&Checkpoint::operator>>(UInt64& x){    int c = getc(fp);    // There must be at least one digit.    if (c < '0' || c > '9') {	if (c == EOF)	    throw EOFError(*this);	else {	    throw SyntaxError(*this, "an unsigned integer expected");	}    }    // Parse the integer.    UInt64 y = 0;    do {	UInt64 old = y;	y = y * 10 + c - '0';	if (old > y)	    throw SyntaxError(*this, "integer too large");	c = getc(fp);    } while (c >= '0' && c <= '9');    if (c == EOF && ferror(fp))	throw EOFError(*this);    x = y;    return *this;}// Finally, the string pattern-matching extractor. It throw a SyntaxError// exception unless it can read the string (s) from the input.Checkpoint&Checkpoint::operator>>(const char *s){    const char *p = s;    while (*p) {	int c = getc(fp);	if (c != *p) {	    if (c == EOF)		throw EOFError(*this);	    else {		throw SyntaxError(*this, "\"%#s\" expected", s);	    }	}	if (c == '\n')	    ++ln;	++p;    }    return *this;}// Create a checkpoint. Exactly one argument is expected (the file name).SimArgCheckpoint::create(const SimArgs &args){    // Check the arguments.    if (args.length() == 0)	throw Error("No checkpoint file name specified.");    else if (args.length() > 1)	throw Error("Too many arguments specified to \"checkpoint\".");    // Create the checkpoint object.    Checkpoint cp(args[0]);    // Open the file.    if ((cp.fp = fopen(cp.name(), "w")) == 0)	throw FileError(cp.name());    // Create the checkpoint.    try {    	// Write the initial header.	cp << sulima->banner << ' ' << "Checkpoint\n";	// Write the time stamp.	time_t t; time(&t);	cp << ctime(&t);	// Checkpoint all serializable objects in the system.  Note that the	// empty line between objects is supressed if the previous object	// didn't write any data.	int prev_ln = -1;	for (ObjectIterator i; i; ++i) {	    if (cp.ln > prev_ln)		cp << '\n'; // a line separator	    i->checkpoint(cp, true);	    prev_ln = cp.ln;	}	// Close the file, detecting fflush errors.	if (fclose(cp.fp))	    throw FileError(cp.name());        }    catch (...) {	// Remove the partial file.	fclose(cp.fp);	remove(cp.name());	throw;    }    // We're done.    return "";}// Restore a checkpoint. Exactly one argument is expected (the file name).SimArgCheckpoint::restore(const SimArgs &args){    // Check the arguments.    if (args.length() == 0)	throw Error("No checkpoint file name specified.");    else if (args.length() > 1)	throw Error("Too many arguments specified to \"restore\".");    // Create the checkpoint object.    Checkpoint cp(args[0]);    // Open the file.    if ((cp.fp = fopen(cp.name(), "r")) == 0)	throw FileError(cp.name());    // Read the checkpoint data.    try {    	// Read the initial header.	cp >> sulima->banner >> ' ' >> "Checkpoint\n";	// Read and display the time stamp.	const char *timestamp = extract_line(cp);	sulima->msg("Restoring checkpoint made on %s.\n", timestamp);	delete timestamp;	// Restore all objects from the file;	while (!feof(cp.fp)) {	    // The first word of each object specifies its type.	    BasicSerialType *type;	    cp >> '\n' >> type;	    type->restore(cp);	}	// Close the file.	fclose(cp.fp);    }    catch (...) {	// Remove the partial file.	fclose(cp.fp);	throw;    }    // We're done.    return "";}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -