MultiMC5/depends/pack200/src/bytes.h
Petr Mrázek f56eff04ef Fix (hopefully) library dependency resolution.
Installing libs is now enabled, hardcoded.
Enable -Wall for all builds.
Fix many warnings and latent bugs.
2013-12-01 16:34:51 +01:00

285 lines
5.5 KiB
C

/*
* Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
struct bytes
{
int8_t *ptr;
size_t len;
int8_t *limit()
{
return ptr + len;
}
void set(int8_t *ptr_, size_t len_)
{
ptr = ptr_;
len = len_;
}
void set(const char *str)
{
ptr = (int8_t *)str;
len = strlen(str);
}
bool inBounds(const void *p); // p in [ptr, limit)
void malloc(size_t len_);
void realloc(size_t len_);
void free();
void copyFrom(const void *ptr_, size_t len_, size_t offset = 0);
void saveFrom(const void *ptr_, size_t len_);
void saveFrom(const char *str)
{
saveFrom(str, strlen(str));
}
void copyFrom(bytes &other, size_t offset = 0)
{
copyFrom(other.ptr, other.len, offset);
}
void saveFrom(bytes &other)
{
saveFrom(other.ptr, other.len);
}
void clear(int fill_byte = 0)
{
memset(ptr, fill_byte, len);
}
int8_t *writeTo(int8_t *bp);
bool equals(bytes &other)
{
return 0 == compareTo(other);
}
int compareTo(bytes &other);
bool contains(int8_t c)
{
return indexOf(c) >= 0;
}
int indexOf(int8_t c);
// substrings:
static bytes of(int8_t *ptr, size_t len)
{
bytes res;
res.set(ptr, len);
return res;
}
bytes slice(size_t beg, size_t end)
{
bytes res;
res.ptr = ptr + beg;
res.len = end - beg;
assert(res.len == 0 ||(inBounds(res.ptr) && inBounds(res.limit() - 1)));
return res;
}
// building C strings inside byte buffers:
bytes &strcat(const char *str)
{
::strcat((char *)ptr, str);
return *this;
}
bytes &strcat(bytes &other)
{
::strncat((char *)ptr, (char *)other.ptr, other.len);
return *this;
}
char *strval()
{
assert(strlen((char *)ptr) == len);
return (char *)ptr;
}
};
#define BYTES_OF(var) (bytes::of((int8_t *)&(var), sizeof(var)))
struct fillbytes
{
bytes b;
size_t allocated;
int8_t *base()
{
return b.ptr;
}
size_t size()
{
return b.len;
}
int8_t *limit()
{
return b.limit();
} // logical limit
void setLimit(int8_t *lp)
{
assert(isAllocated(lp));
b.len = lp - b.ptr;
}
int8_t *end()
{
return b.ptr + allocated;
} // physical limit
int8_t *loc(size_t o)
{
assert(o < b.len);
return b.ptr + o;
}
void init()
{
allocated = 0;
b.set(nullptr, 0);
}
void init(size_t s)
{
init();
ensureSize(s);
}
void free()
{
if (allocated != 0)
b.free();
allocated = 0;
}
void empty()
{
b.len = 0;
}
int8_t *grow(size_t s); // grow so that limit() += s
int getByte(uint32_t i)
{
return *loc(i) & 0xFF;
}
void addByte(int8_t x)
{
*grow(1) = x;
}
void ensureSize(size_t s); // make sure allocated >= s
void trimToSize()
{
if (allocated > size())
b.realloc(allocated = size());
}
bool canAppend(size_t s)
{
return allocated > b.len + s;
}
bool isAllocated(int8_t *p)
{
return p >= base() && p <= end();
} // asserts
void set(bytes &src)
{
set(src.ptr, src.len);
}
void set(int8_t *ptr, size_t len)
{
b.set(ptr, len);
allocated = 0; // mark as not reallocatable
}
// block operations on resizing byte buffer:
fillbytes &append(const void *ptr_, size_t len_)
{
memcpy(grow(len_), ptr_, len_);
return (*this);
}
fillbytes &append(bytes &other)
{
return append(other.ptr, other.len);
}
fillbytes &append(const char *str)
{
return append(str, strlen(str));
}
};
struct ptrlist : fillbytes
{
typedef const void *cvptr;
int length()
{
return (int)(size() / sizeof(cvptr));
}
cvptr *base()
{
return (cvptr *)fillbytes::base();
}
cvptr &get(int i)
{
return *(cvptr *)loc(i * sizeof(cvptr));
}
cvptr *limit()
{
return (cvptr *)fillbytes::limit();
}
void add(cvptr x)
{
*(cvptr *)grow(sizeof(x)) = x;
}
void popTo(int l)
{
assert(l <= length());
b.len = l * sizeof(cvptr);
}
int indexOf(cvptr x);
bool contains(cvptr x)
{
return indexOf(x) >= 0;
}
void freeAll(); // frees every ptr on the list, plus the list itself
};
// Use a macro rather than mess with subtle mismatches
// between member and non-member function pointers.
#define PTRLIST_QSORT(ptrls, fn) ::qsort((ptrls).base(), (ptrls).length(), sizeof(void *), fn)
struct intlist : fillbytes
{
int length()
{
return (int)(size() / sizeof(int));
}
int *base()
{
return (int *)fillbytes::base();
}
int &get(int i)
{
return *(int *)loc(i * sizeof(int));
}
int *limit()
{
return (int *)fillbytes::limit();
}
void add(int x)
{
*(int *)grow(sizeof(x)) = x;
}
void popTo(int l)
{
assert(l <= length());
b.len = l * sizeof(int);
}
int indexOf(int x);
bool contains(int x)
{
return indexOf(x) >= 0;
}
};