Skip to content

Instantly share code, notes, and snippets.

@betawaffle
Created August 19, 2010 13:17
Show Gist options
  • Save betawaffle/537843 to your computer and use it in GitHub Desktop.
Save betawaffle/537843 to your computer and use it in GitHub Desktop.
File::NextCharacter() WIP
int
File::NextCharacter()
{
unsigned char b, e, s; /* [0-255], [0-8], [0-8] */
int c;
ssize_t i, r;
/*
* b (Byte) : Current byte.
* c (Character) : Current character. (32-bits for Unicode)
* e (Expected) : Bytes expected in sequence.
* i (Index) : Current index (offset from start of buffer).
* r (Read) : Bytes read into buffer.
* s (Shift) : Consecutive 1 bits from the highest-order bit.
*/
c = 0;
e = 0;
i = (ssize_t) this->mBufferIndex;
r = (ssize_t) this->mBufferLength;
loop:
if (i >= r) {
goto read;
}
b = this->mBuffer[i];
/* Count consecutive 1 bits. */
for (s = 0; b & 0x80 >> s; s++) {
if (s > 1 && e > 0) throw SequenceMissingByte();
if (s > 4) throw SequenceTooLong();
}
if (s != 1 && e > 0) throw SequenceMissingByte();
c <<= 7 - s;
c |= b & 0x7F >> s;
e = s - 1;
i += 1;
if (e > 0) {
goto loop;
}
goto done;
read: i = 0;
if (r = read(this->mDescriptor, this->mBuffer, this->mBuffer.Size()), r < 0) {
switch (errno) {
case EINTR:
/* Handle Interupt */
goto read;
default:
throw errno;
}
}
if (r == 0) {
if (e == 0) {
goto done;
}
throw SequenceMissingByte();
}
goto loop;
done:
this->mBufferIndex = (size_t) i;
this->mBufferLength = (size_t) r; /* TODO: I may need a cast here. */
return c;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment