#include "NibStr.h"
#include <set_error.h>
extern "C" {
#ifdef SYSV
#include <string.h>
#define bcopy(from, to, len) (memcpy((to), (from), (len)))
#else
#include <strings.h>
#endif
}
void NibStr::insert( unsigned long offset, const NibStr & replacement) {
unsigned long o = 0;
unsigned long l = replacement.length();
while (l >= 16) {
poke(offset+o, (unsigned long long) replacement.peek(o, 16), 16);
o += 16;
l -= 16;
}
if (l) {
poke(offset+o, (unsigned long long) replacement.peek(o,l), l);
}
}
void NibStr::poke (unsigned long offset, unsigned long long val, int nibs) {
if (nibs == 0) return;
char * a = adr + (offset >> 1);
bool nflag = (offset & 1)? true : false;
int cnt = nibs - 1;
do {
if (nflag) {
char c = *(a) & 0x0f;
c |= (val << 4) & 0xf0;
*(a) = c;
nflag = false;
a++;
} else {
char c = *(a) & 0xf0;
c |= val & 0x0f;
*(a) = c;
nflag = true;
}
val >>= 4;
} while (cnt--);
}
unsigned long long NibStr::peek (unsigned long offset, int nibs) const {
if (nibs == 0) return 0;
offset += nibs-1;
const char * a = adr + (offset >> 1);
bool nflag = (offset & 1)? true : false;
unsigned long long v = 0;
int cnt = nibs - 1;
do {
v <<= 4;
if (nflag) {
v |= ((*(a) & 0xf0) >> 4);
nflag = false;
} else {
v |= (*(a) & 0x0f);
nflag = true;
a--;
}
} while (cnt--);
return v;
}
NibStr NibStr::operator+ (const NibStr & rv) const {
NibStr res(length()+rv.length());
if (!res.fail) {
bcopy ( adr, res.adr, len );
if (even) {
if (rv.length()) {
bcopy ( rv.adr, res.adr+len, rv.len );
}
res.even = false;
if (rv.even) res.even = true;
} else {
if (rv.length() > 0) {
char * s = rv.adr;
char * d = res.adr + len - 1;
bool nflag = true;
char val = *s++;
int cnt = rv.length() - 1;
do {
if (nflag) {
char c = *(d) & 0x0f;
c |= (val << 4) & 0xf0;
*(d) = c;
nflag = false;
d++;
} else {
char c = *(d) & 0xf0;
c |= (val >> 4) & 0x0f;
*(d) = c;
val = *s++;
nflag = true;
}
} while (cnt--);
}
res.even = true;
if (rv.even) res.even = false;
}
}
return res;
}
NibStr NibStr::operator+= (const NibStr & rv) {
unsigned long newlen = (length() + rv.length() + 1) >> 1;
if (newlen > alloc_len) {
if (rv.len < 64*1024 && rv.len < len) {
expand();
if (alloc_len < newlen) {
set_error("NibStr::operator+= ","unable to allocate more memory");
return *this;
}
} else {
char * nadr = new char[newlen+1];
if (nadr == 0) {
fail = -1;
set_error("NibStr::operator+= ","unable to allocate more memory");
return *this;
}
bcopy(adr, nadr, len+1);
if (alloc_len) delete [] adr;
adr = nadr;
alloc_len = newlen;
}
}
if (even) {
if (rv.length()) {
bcopy ( rv.adr, adr+len, rv.len+1 );
}
len = newlen;
even = false;
if (rv.even) even = true;
} else {
if (rv.length() > 0) {
char * s = rv.adr;
char * d = adr + len - 1;
bool nflag = true;
char val = *s++;
int cnt = rv.length() - 1;
do {
if (nflag) {
char c = *(d) & 0x0f;
c |= (val << 4) & 0xf0;
*(d) = c;
nflag = false;
d++;
} else {
char c = *(d) & 0xf0;
c |= (val >> 4) & 0x0f;
*(d) = c;
val = *s++;
nflag = true;
}
} while (cnt--);
}
len = newlen;
*(adr+len) = 0;
even = true;
if (rv.even) even = false;
}
return *this;
}
#include <Bstream.h>
BOstream & operator<< (BOstream & out, const NibStr & n) {
out << n.even;
return operator<< (out, (Str &)n );
}
BIstream & operator>> (BIstream & in, NibStr & n) {
in >> n.even;
return operator>> (in, (Str &)n);
}
syntax highlighted by Code2HTML, v. 0.9.1