1: // Copyright (C) 1994-1998 by Symantec
  2: // Copyright (C) 2000-2009 by Digital Mars
  3: // All Rights Reserved
  4: // http://www.digitalmars.com
  5: // Written by Walter Bright
  6: /*
  7:  * This source file is made available for personal use
  8:  * only. The license is in /dmd/src/dmd/backendlicense.txt
  9:  * or /dm/src/dmd/backendlicense.txt
 10:  * For any other uses, please contact Digital Mars.
 11:  */
 12: 
 13: // Output buffer
 14: 
 15: #include <string.h>
 16: #include <stdlib.h>
 17: #include <time.h>
 18: 
 19: #include "cc.h"
 20: 
 21: #include "outbuf.h"
 22: #include "mem.h"
 23: 
 24: #if DEBUG
 25: static char __file__[] = __FILE__;      // for tassert.h
 26: #include        "tassert.h"
 27: #endif
 28: 
 29: Outbuffer::Outbuffer()
 30: {
 31:     buf = NULL;
 32:     pend = NULL;
 33:     p = NULL;
 34:     len = 0;
 35:     inc = 0;
 36: }
 37: 
 38: Outbuffer::Outbuffer(unsigned bufinc)
 39: {
 40:     buf = NULL;
 41:     pend = NULL;
 42:     p = NULL;
 43:     len = 0;
 44:     inc = bufinc;
 45: }
 46: 
 47: Outbuffer::~Outbuffer()
 48: {
 49: #if MEM_DEBUG
 50:     mem_free(buf);
 51: #else
 52:     if (buf)
 53:         free(buf);
 54: #endif
 55: }
 56: 
 57: void Outbuffer::reset()
 58: {
 59:     p = buf;
 60: }
 61: 
 62: // Reserve nbytes in buffer
 63: void Outbuffer::reserve(unsigned nbytes)
 64: {
 65:     if (pend - p < nbytes)
warning C4018: '<' : signed/unsigned mismatch
66: { unsigned oldlen = len; 67: unsigned used = p - buf; 68: 69: if (inc > nbytes) 70: { 71: len = used + inc; 72: } 73: else 74: { 75: len = used + nbytes; 76: if (len < 2 * oldlen) 77: { len = 2 * oldlen; 78: if (len < 8) 79: len = 8; 80: } 81: } 82: #if MEM_DEBUG 83: buf = (unsigned char *)mem_realloc(buf, len); 84: #else 85: if (buf) 86: buf = (unsigned char *) realloc(buf,len);
warning C6308: 'realloc' might return null pointer: assigning null pointer to 'buf', which is passed as an argument to 'realloc', will cause the original memory block to be leaked
87: else 88: buf = (unsigned char *) malloc(len); 89: #endif 90: pend = buf + len; 91: p = buf + used; 92: } 93: } 94: 95: // Position buffer for output at a specified location and size. 96: // If data will extend buffer size, reserve space 97: // If data will rewrite existing data 98: // position for write and return previous buffer size 99: // 100: // If data will append to buffer 101: // position for write and return new size 102: int Outbuffer::position(unsigned pos, unsigned nbytes) 103: { 104: int current_sz = size(); 105: unsigned char *fend = buf+pos+nbytes; // future end of buffer 106: if (fend >= pend) 107: { 108: reserve (fend - pend); 109: } 110: setsize(pos); 111: return pos+nbytes > current_sz ? pos+nbytes : current_sz;
warning C4018: '>' : signed/unsigned mismatch
112: } 113: 114: // Write an array to the buffer. 115: void Outbuffer::write(const void *b, int len) 116: { 117: if (pend - p < len) 118: reserve(len); 119: memcpy(p,b,len); 120: p += len; 121: } 122: 123: // Write n zeros to the buffer. 124: void *Outbuffer::writezeros(unsigned len) 125: { 126: if (pend - p < len)
warning C4018: '<' : signed/unsigned mismatch
127: reserve(len); 128: void *pstart = memset(p,0,len); 129: p += len; 130: return pstart; 131: } 132: 133: /** 134: * Writes an 8 bit byte. 135: */ 136: void Outbuffer::writeByte(int v) 137: { 138: if (pend == p) 139: reserve(1); 140: *p++ = v; 141: } 142: 143: /** 144: * Writes a 32 bit int. 145: */ 146: void Outbuffer::write32(int v) 147: { 148: if (pend - p < 4) 149: reserve(4); 150: *(int *)p = v; 151: p += 4; 152: } 153: 154: /** 155: * Writes a 64 bit long. 156: */ 157: 158: #if __INTSIZE == 4 159: void Outbuffer::write64(long long v) 160: { 161: if (pend - p < 8) 162: reserve(8); 163: *(long long *)p = v; 164: p += 8; 165: } 166: #endif 167: 168: /** 169: * Writes a 32 bit float. 170: */ 171: void Outbuffer::writeFloat(float v) 172: { 173: if (pend - p < sizeof(float)) 174: reserve(sizeof(float)); 175: *(float *)p = v; 176: p += sizeof(float); 177: } 178: 179: /** 180: * Writes a 64 bit double. 181: */ 182: void Outbuffer::writeDouble(double v) 183: { 184: if (pend - p < sizeof(double)) 185: reserve(sizeof(double)); 186: *(double *)p = v; 187: p += sizeof(double); 188: } 189: 190: /** 191: * Writes a String as a sequence of bytes. 192: */ 193: void Outbuffer::write(const char *s) 194: { 195: write(s,strlen(s)); 196: } 197: 198: 199: /** 200: * Writes a String as a sequence of bytes. 201: */ 202: void Outbuffer::write(const unsigned char *s) 203: { 204: write(s,strlen((const char *)s)); 205: } 206: 207: 208: /** 209: * Writes a NULL terminated String 210: */ 211: void Outbuffer::writeString(const char *s) 212: { 213: write(s,strlen(s)+1); 214: } 215: 216: /** 217: * Inserts string at beginning of buffer. 218: */ 219: 220: void Outbuffer::prependBytes(const char *s) 221: { 222: size_t len = strlen(s); 223: 224: reserve(len); 225: memmove(buf + len,buf,p - buf); 226: memcpy(buf,s,len); 227: p += len; 228: } 229: 230: /** 231: */ 232: 233: void Outbuffer::bracket(char c1,char c2) 234: { 235: reserve(2); 236: memmove(buf + 1,buf,p - buf); 237: buf[0] = c1; 238: p[1] = c2; 239: p += 2; 240: } 241: 242: /** 243: * Convert to a string. 244: */ 245: 246: char *Outbuffer::toString() 247: { 248: if (pend == p) 249: reserve(1); 250: *p = 0; // terminate string 251: return (char *)buf; 252: } 253: 254: /** 255: * Set current size of buffer. 256: */ 257: 258: void Outbuffer::setsize(unsigned size) 259: { 260: p = buf + size; 261: } 262: 263: void Outbuffer::writesLEB128(int value) 264: { 265: while (1) 266: { 267: unsigned char b = value & 0x7F; 268: 269: value >>= 7; // arithmetic right shift 270: if (value == 0 && !(b & 0x40) || 271: value == -1 && (b & 0x40)) 272: { 273: writeByte(b); 274: break; 275: } 276: writeByte(b | 0x80); 277: } 278: } 279: 280: void Outbuffer::writeuLEB128(unsigned value) 281: { 282: do 283: { unsigned char b = value & 0x7F; 284: 285: value >>= 7; 286: if (value) 287: b |= 0x80; 288: writeByte(b); 289: } while (value); 290: } 291: 292: