/** Create space in the binary for count bytes starting at index. The memory in the new space is uninitialized. \param buf Initialized binary buffer. \param index Position to expand at. \param count Number of bytes to expand. */ void ur_binExpand( UBuffer* buf, int index, int count ) { ur_binReserve( buf, buf->used + count ); if( index < buf->used ) { uint8_t* mem = buf->ptr.b + index; memMove( mem + count, mem, buf->used - index ); } buf->used += count; }
static int _readInfoBuf( HANDLE fd, UBuffer* buf ) { #define BUFSIZE 1024 DWORD nr; if( buf->type == UT_STRING ) ur_arrReserve( buf, buf->used + BUFSIZE ); else ur_binReserve( buf, buf->used + BUFSIZE ); if( ReadFile(fd, buf->ptr.c + buf->used, BUFSIZE, &nr, NULL) == 0 ) return -1; // GetLastError(); if( nr > 0 ) buf->used += nr; return nr; }
static void itemview_rebuildAttr( UThread* ut, GItemView* ep, const UBuffer* items, int page ) { #define MAX_ITEM_TRIS 400 #define MAX_DEC_TRIS 100 #define TRI_ATTR_BYTES (3 * AttrCount * sizeof(GLfloat)) DrawContext dc; UBlockIter bi; UBlockIter layout; UBuffer* fcBuf; const UCell* loStart; UCell* cell; float* attr; int bsize; int height = ep->itemHeight; int caOffset = items->used + DECORATION_GROUPS; // Reserve triangles for each item. ur_binReserve( &glEnv.tmpBin, (MAX_DEC_TRIS + (items->used * MAX_ITEM_TRIS)) * TRI_ATTR_BYTES ); attr = glEnv.tmpBin.ptr.f; // Reserve first & count arrays. fcBuf->used tracks the number of items // and view decorations, which is half the number of integers used for // both arrays. fcBuf = &ep->fc[ page ]; ur_arrReserve( fcBuf, caOffset * 2 ); fcBuf->used = 0; dc.attr = attr; dc.drawFirst = 0; dc.penX = 0.0; #if 1 // Build selected background tris. dc.drawCount = 0; if( ep->selRow > -1 ) { dc.color[0] = 1.0; dc.color[1] = dc.color[2] = 0.0; dc.penY = ep->wid.area.h; cell = glEnv.guiStyle + CI_STYLE_AREA; //ur_setId(cell, UT_COORD) cell->coord.len = 4; cell->coord.n[0] = 0; cell->coord.n[1] = (ep->selRow + 1) * -height; cell->coord.n[2] = ep->itemWidth; cell->coord.n[3] = height; layout.buf = ur_buffer( ep->selectBgBlkN ); layout.it = layout.buf->ptr.cell; layout.end = layout.it + layout.buf->used; if( ! itemview_parse( &dc, ut, &layout, (GWidget*) ep ) ) { boron_reset(ut); printf( "KR itemview_parse failed\n" ); } } fcBuf->ptr.i[ fcBuf->used ] = dc.drawFirst; fcBuf->ptr.i[ fcBuf->used + caOffset ] = dc.drawCount; ++fcBuf->used; dc.attr = attr + MAX_DEC_TRIS * 3 * AttrCount; dc.drawFirst = MAX_DEC_TRIS * 3; #endif dc.penY = ep->wid.area.h; // Setup the data item and layout iterators. bi.it = items->ptr.cell; bi.end = bi.it + items->used; layout.buf = ur_buffer( ep->layoutBlkN ); loStart = layout.buf->ptr.cell; layout.end = loStart + layout.buf->used; ur_foreach( bi ) { // Set item word to current data value. cell = ur_ctxCell( ur_buffer( ep->bindCtxN ), 0 ); *cell = *bi.it; dc.drawCount = 0; dc.color[0] = 1.0; dc.color[1] = dc.color[2] = 0.0; dc.penY -= height; layout.it = loStart; if( ! itemview_parse( &dc, ut, &layout, (GWidget*) ep ) ) { boron_reset(ut); printf( "KR itemview_parse failed\n" ); } //printf( "KR fc %d,%d\n", dc.drawFirst, dc.drawCount ); fcBuf->ptr.i[ fcBuf->used ] = dc.drawFirst; fcBuf->ptr.i[ fcBuf->used + caOffset ] = dc.drawCount; ++fcBuf->used; dc.drawFirst += dc.drawCount; //dc.drawFirst += MAX_ITEM_TRIS; } assert( fcBuf->used == caOffset ); // Transfer vertex data to GPU. bsize = dc.drawFirst * TRI_ATTR_BYTES; if( ep->vboSize[ page ] < bsize ) { ep->vboSize[ page ] = bsize; glBufferData( GL_ARRAY_BUFFER, bsize, attr, GL_STATIC_DRAW ); } else { float* abuf = (float*) glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); if( abuf ) { memCpy( abuf, attr, bsize ); glUnmapBuffer( GL_ARRAY_BUFFER ); } } }
/** Append encoded ASCII string to binary buffer. \param buf Initialized binary buffer. \param it Start of string \param end End of string \param enc Encoding of string. \return End of string or position where non-hex or non-whitespace character was found. */ const char* ur_binAppendBase( UBuffer* buf, const char* it, const char* end, enum UrlanBinaryEncoding enc ) { int c; int high; uint32_t byte = 0; uint8_t* out; c = end - it; if( enc == UR_BENC_16 ) c = (c + 1) / 2; else if( enc == UR_BENC_2 ) c = (c + 7) / 8; ur_binReserve( buf, buf->used + c ); out = buf->ptr.b + buf->used; switch( enc ) { case UR_BENC_16: high = 0; while( it != end ) { c = *it++; if( ur_bitIsSet(charset_hex, c) ) { byte |= hexNibble(c); if( high ) { *out++ = byte; byte = high = 0; } else { byte <<= 4; high = 1; } } else if( ! ur_bitIsSet(charset_white, c) ) { --it; break; } } if( high ) --it; break; case UR_BENC_2: high = 0x80; while( it != end ) { c = *it++; if( c == '0' || c == '1' ) { if( c == '1' ) byte |= high; if( high == 1 ) { high = 0x80; *out++ = byte; byte = 0; } else high >>= 1; } else if( ! ur_bitIsSet(charset_white, c) ) { --it; break; } } // TODO: Should subtract the correct number of characters not // emitted to out, but this is good enough for the caller // (like ur_tokenize) to know the input ended early. if( high != 0x80 ) --it; break; case UR_BENC_64: { high = 0; while( it != end ) { c = *it++; if( ur_bitIsSet(charset_base64, c) ) { if( c == '=' ) continue; byte = (byte << 6) | base64_decodeChar( c ); if( high == 3 ) { high = 0; *out++ = byte >> 16; *out++ = byte >> 8; *out++ = byte; } else ++high; } else if( ! ur_bitIsSet(charset_white, c) )
/** Append data to binary buffer. \param buf Initialized binary buffer. \param data Data to append. \param len Number of bytes from data to append. */ void ur_binAppendData( UBuffer* buf, const uint8_t* data, int len ) { ur_binReserve( buf, buf->used + len ); memCpy( buf->ptr.b + buf->used, data, len ); buf->used += len; }