#include "NibStr.h" #include extern "C" { #ifdef SYSV #include #define bcopy(from, to, len) (memcpy((to), (from), (len))) #else #include #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 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); }