void BinaryMeshFileReader::read_face(ReaderAdapter& reader, IMeshBuilder& builder) { uint16 count; checked_read(reader, count); ensure_minimum_size(m_vertices, count); ensure_minimum_size(m_vertex_normals, count); ensure_minimum_size(m_tex_coords, count); for (uint16 i = 0; i < count; ++i) { uint32 face_vertex; checked_read(reader, face_vertex); m_vertices[i] = face_vertex; uint32 face_vertex_normal; checked_read(reader, face_vertex_normal); m_vertex_normals[i] = face_vertex_normal; uint32 face_tex_coords; checked_read(reader, face_tex_coords); m_tex_coords[i] = face_tex_coords; } uint16 material; checked_read(reader, material); builder.begin_face(count); builder.set_face_vertices(&m_vertices[0]); builder.set_face_vertex_normals(&m_vertex_normals[0]); builder.set_face_vertex_tex_coords(&m_tex_coords[0]); builder.set_face_material(material); builder.end_face(); }
int dict_decompress (MemSize BlockSize, int MinCompression, int MinWeakChars, int MinLargeCnt, int MinMediumCnt, int MinSmallCnt, int MinRatio, CALLBACK_FUNC *callback, void *auxdata) { BYTE* In = NULL; // указатель на входные данные BYTE* Out= NULL; // указатель на выходные данные int x; // код произошедшей ошибки for(;;) { int InSize; unsigned OutSize; // количество байт во входном и выходном буфере, соответственно checked_read (&InSize, sizeof(InSize)); if (InSize<0) { // скопируем неупакованные данные In = (BYTE*) BigAlloc(-InSize); checked_read (In, -InSize); checked_write (In, -InSize); BigFreeAndNil(In); } else { // Произвести декодирование и получить размер выходных данных In = (BYTE*) BigAlloc(InSize); Out = (BYTE*) BigAlloc(BlockSize); checked_read (In, InSize); x = DictDecode (In, InSize, Out, &OutSize); //x = DictDecode (InSize, callback, auxdata); // для работы в фиксированном объёме памяти if (x) break; BigFreeAndNil(In); //Out = (BYTE*) realloc (Out, OutSize); -- impossible since we used BigAlloc checked_write (Out, OutSize); BigFreeAndNil(Out); } } finished: BigFreeAndNil(In); BigFreeAndNil(Out); return x<=0? x : FREEARC_ERRCODE_GENERAL; // 0, если всё в порядке, и код ошибки иначе }
string BinaryMeshFileReader::read_string(ReaderAdapter& reader) { uint16 length; checked_read(reader, length); string s; s.resize(length); checked_read(reader, &s[0], length); return s; }
void BinaryMeshFileReader::read_texture_coordinates(ReaderAdapter& reader, IMeshBuilder& builder) { uint32 count; checked_read(reader, count); for (uint32 i = 0; i < count; ++i) { Vector2d v; checked_read(reader, v); builder.push_tex_coords(v); } }
void BinaryMeshFileReader::read_vertex_normals(ReaderAdapter& reader, IMeshBuilder& builder) { uint32 count; checked_read(reader, count); for (uint32 i = 0; i < count; ++i) { Vector3d v; checked_read(reader, v); builder.push_vertex_normal(v); } }
void walk_ask_child_val(const child_pipe *child) /* Procedure awaits for signal from parent, than asks [child] for one value * * and sends it to the output. Procedure assuming that process is currently * * WALKing through tree values. */ { int count, val = 1, signal; checked_read(0, &signal, sizeof(signal)); checked_write(child->out, &val, sizeof(val)); checked_read(child->in, &count, sizeof(count)); checked_read(child->in, &val, sizeof(val)); checked_write(1, &count, sizeof(count)); checked_write(1, &val, sizeof(val)); return ; }
void find(vertex *v, command com) /* Procedure checks if BST cointains [com.arg] value. * * * * If current vertex contains [com.arg] value it returns [v->counter] * * into output. If not so, it sends a [com] (FIND) command into suitable * * (right if [com.arg] > [v->value], left otherwise) child, awaits for * * answer and prints it into output. If there is no proper child, * * procedure prints `0`. */ { int result; child_pipe *child; if(com.arg == v->value) { checked_write(1, &v->count, sizeof(v->count)); } else { child = (com.arg > v->value ? &v->right : &v->left); if(child->in == -1) { result = 0; checked_write(1, &result, sizeof(result)); } else { checked_write(child->out, &com, sizeof(com)); checked_read(child->in, &result, sizeof(result)); checked_write(1, &result, sizeof(result)); } } return ; }
void add(vertex *v, command com) /* Procedure * * - Increments counter in [v] if [com.arg] is equal to [v->value] * * or * * - Sends [com] into suitable (right if [com.arg] > [v->value], left * * otherwise) * * and then prints `1` as confirmation message into output. * * * * MUTABLE PARAMETERS: v */ { int result = 1; child_pipe *child; if(com.arg == v->value) { v->count++; checked_write(1, &result, sizeof(result)); return ; } child = (com.arg > v->value ? &v->right : &v->left); if(child->in == -1) add_fork(child, com.arg, v); else { checked_write(child->out, &com, sizeof(com)); checked_read(child->in, &result, sizeof(result)); checked_write(1, &result, sizeof(result)); } return ; }
void BinaryMeshFileReader::read_faces(ReaderAdapter& reader, IMeshBuilder& builder) { uint32 count; checked_read(reader, count); for (uint32 i = 0; i < count; ++i) read_face(reader, builder); }
void walk_ask_childs_count(const vertex *v, int *lcount, int *rcount) /* Procedure sends a WALK command to the children, then reads sizes of * * subtrees and puts them in [lcount] and [rcount]. * * * * MUTABLE PARAMETERS: lcount, rcount */ { command com; com.code = COM_WALK; if(v->left.in != -1) checked_write(v->left.out, &com, sizeof(com)); if(v->right.in != -1) checked_write(v->right.out, &com, sizeof(com)); /* Reading from the first child before sending request to the second one * * will freeze the program, so the calculation would not be parallel. * * Although, it is not very lucrative in this particular case, it * * would be for more complex vertex operations. */ if(v->left.in != -1) checked_read(v->left.in, lcount, sizeof(int)); if(v->right.in != -1) checked_read(v->right.in, rcount, sizeof(int)); return ; }
void BinaryMeshFileReader::read_and_check_signature(BufferedFile& file) { static const char ExpectedSig[10] = { 'B', 'I', 'N', 'A', 'R', 'Y', 'M', 'E', 'S', 'H' }; char signature[sizeof(ExpectedSig)]; checked_read(file, signature, sizeof(signature)); if (memcmp(signature, ExpectedSig, sizeof(ExpectedSig))) throw ExceptionIOError("invalid binarymesh format signature"); }
void BinaryMeshFileReader::read_and_check_signature(BufferedFile& file) { static const char ExpectedSig[10] = { 'B', 'I', 'N', 'A', 'R', 'Y', 'M', 'E', 'S', 'H' }; char signature[sizeof(ExpectedSig)]; checked_read(file, signature, sizeof(signature)); if (memcmp(signature, ExpectedSig, sizeof(ExpectedSig))) throw ExceptionIOError(); // todo: throw better-qualified exception }
void BinaryMeshFileReader::read_material_slots(ReaderAdapter& reader, IMeshBuilder& builder) { uint16 count; checked_read(reader, count); for (uint16 i = 0; i < count; ++i) { const string material_slot = read_string(reader); builder.push_material_slot(material_slot.c_str()); } }
bool CUnbufferedReadWriteSeq::get(void *dst) { size32_t toread = size; while (toread) { int read = checked_read(fh, dst, toread); if (!read) return false; toread -= read; dst = (char *) dst + read; } return true; }
void * consume(void *arg_) { struct consume_arg *arg = arg_; struct queue *q = arg->q; struct kmp_table *t = arg->t; char buffer[BUFFER_SIZE]; for (;;) { char *path = dequeue(q); int pos = 0; int file; int bytes_read = 0; struct kmp_result r; if (!path) { return (NULL); } file = checked_open(path, O_RDONLY); if (file == -1) { fprintf_ts(stderr, "Cannot open %s\n", path); free(path); continue; } while ((bytes_read = checked_read(file, buffer, BUFFER_SIZE)) > 0) { int i; for (i = 0; i < bytes_read; i++) { advance(t, &r, buffer[i], pos); pos = r.pos; if (r.match) { fprintf_ts(stdout, "%s\n", path); break; } } if (r.match) { break; } } free(path); checked_close(file); } }
unsigned CUnbufferedReadWriteSeq::getn(void *dst, unsigned n) { size32_t toread = size*n; size32_t totread = 0; while (toread) { int read = checked_read(fh, dst, toread); if (!read) break; toread -= read; totread += read; dst = (char *) dst + read; } return totread/size; }
void walk(const vertex *v) /* Procedure calculates size of the tree, sends its into output, and than * * sends values from the tree in infix order. Every value transmition have * * to be invoked by parent. */ { int lcount = 0, rcount = 0, count, i, signal; walk_ask_childs_count(v, &lcount, &rcount); count = lcount + rcount + 1; checked_write(1, &count, sizeof(count)); for(i = 0; i < lcount; i++) walk_ask_child_val(&v->left); checked_read(0, &signal, sizeof(signal)); checked_write(1, &v->count, sizeof(v->count)); checked_write(1, &v->value, sizeof(v->value)); for(i = 0; i < rcount; i++) walk_ask_child_val(&v->right); return ; }
void BinaryMeshFileReader::read(IMeshBuilder& builder) { BufferedFile file( m_filename.c_str(), BufferedFile::BinaryType, BufferedFile::ReadMode); if (!file.is_open()) throw ExceptionIOError(); read_and_check_signature(file); uint16 version; checked_read(file, version); auto_ptr<ReaderAdapter> reader; switch (version) { // Uncompressed. case 1: reader.reset(new PassthroughReaderAdapter(file)); break; // LZO-compressed. case 2: throw ExceptionIOError( "binarymesh format version 2 is no longer supported; " "please use the convertmeshfile tool that ships with appleseed 1.1.0 alpha-21 or earlier"); // LZ4-compressed. case 3: reader.reset(new LZ4CompressedReaderAdapter(file)); break; // Unknown format. default: throw ExceptionIOError("unknown binarymesh format version"); } read_meshes(*reader.get(), builder); }
static void on_datalink_event(int fd, short event __attribute__((unused)), void *arg) { char buf[255]; int bytes_read; bytes_read = checked_read(fd, buf, sizeof(buf) - 1); struct DownlinkTransport *tp = (struct DownlinkTransport *) arg; struct udp_transport *udp_impl = tp->impl; //printf("on datalink event: %d bytes\n",bytes_read); int i = 0; while (i<bytes_read) { parse_udp_dl(udp_impl, buf[i]); i++; if (udp_impl->udp_dl_msg_received) { memcpy(gcs_com.my_dl_buffer, udp_impl->udp_dl_payload, udp_impl->udp_dl_payload_len); dl_handle_msg(tp); udp_impl->udp_dl_msg_received = FALSE; } } }
void BinaryMeshFileReader::read(IMeshBuilder& builder) { BufferedFile file( m_filename.c_str(), BufferedFile::BinaryType, BufferedFile::ReadMode); if (!file.is_open()) throw ExceptionIOError(); read_and_check_signature(file); uint16 version; checked_read(file, version); auto_ptr<ReaderAdapter> reader; switch (version) { case 1: // uncompressed reader.reset(new PassthroughReaderAdapter(file)); break; case 2: // LZO-compressed (deprecated) reader.reset(new LZOCompressedReaderAdapter(file)); break; case 3: // LZ4-compressed reader.reset(new LZ4CompressedReaderAdapter(file)); break; default: // unknown format throw ExceptionIOError(); // todo: throw better-qualified exception } read_meshes(*reader.get(), builder); }
int main(int argc, char *argv[]) { vertex v; command com; v.left.in = -1; v.right.in = -1; vertex_init(&v, 0); sscanf(argv[1], "%d", &v.value); while(checked_read(0, &com, sizeof(com))) { switch(com.code) { case COM_ADD: add(&v, com); break; case COM_FIND: find(&v, com); break; case COM_WALK: walk(&v); break; case COM_STOP: if(v.left.in != -1) destroy_child(&v.left); if(v.right.in != -1) destroy_child(&v.right); close(0); close(1); exit(0); break; default: fatal("code unknown"); break; } } return 0; }
extern jlib_decl size32_t checked_pread(int file, void *buffer, size32_t len, offset_t pos) { if (0==len) return 0; #ifdef WIN32 if (atomicsupported) { HANDLE hFile = (HANDLE)_get_osfhandle(file); DWORD rread; OVERLAPPED overlapped; memset(&overlapped, 0, sizeof(overlapped)); overlapped.Offset = (DWORD) pos; overlapped.OffsetHigh = (DWORD)(pos>>32); if (ReadFile(hFile, buffer, len, &rread, &overlapped)) return rread; int err = (int)GetLastError(); if (err == ERROR_HANDLE_EOF) return 0; if (err == ERROR_INVALID_PARAMETER) // Win98 etc atomicsupported = false; else throw makeOsException(GetLastError(), "checked_pread"); } { CriticalBlock blk(atomicsection); checked_lseeki64(file, pos, FILE_BEGIN); return checked_read(file, buffer, len); } #else size32_t ret = 0; unsigned attempts = 0; unsigned __int64 startCycles = get_cycles_now(); loop { ssize_t readNow = ::pread(file, buffer, len, pos); if (readNow == (ssize_t)-1) { switch (errno) { case EINTR: readNow = 0; break; default: if (attempts < ioRetryCount) { attempts++; StringBuffer callStr("pread"); callStr.append("[errno=").append(errno); unsigned __int64 elapsedMs = cycle_to_nanosec(get_cycles_now() - startCycles)/1000000; callStr.append(", took=").append(elapsedMs); callStr.append(", attempt=").append(attempts).append("](handle="); callStr.append(file).append(", pos=").append(pos).append(", len=").append(len).append(")"); PROGLOG("%s", callStr.str()); readNow = 0; break; } throw makeErrnoException(errno, "checked_pread"); } } else if (!readNow) break; ret += readNow; if (readNow == (ssize_t)len) break; pos += readNow; buffer = ((char *) buffer) + readNow; len -= readNow; } return ret; #endif }
static bool R_LoadX42Swapped( model_t *mod, void *buffer, size_t header_size, int filesize, const char *name, const x42header_t *h ) { uint i; bool stat; x42PackHeader_v5_t pack; size_t inPos; const byte *inBuf; x42data_t *ret; const uint persist_flags = X42_PERSIST_EVERYTHING; ret = (x42data_t*)ri.Hunk_Alloc( sizeof( x42data_t ), h_low ); x42_SetupBufferPointers( ret, h, persist_flags ); inPos = sizeof( x42Header_ident_t ); switch( h->ident.version ) { case X42_VER_V5: inPos += sizeof( x42Header_v5_t ); break; default: ri.Printf( PRINT_ERROR, "Invalid x42 file version in model '%s'\n", name ); return false; } inBuf = (const byte*)buffer + inPos; #define read_check() if( !stat ) return false; else (void)0 #define checked_read( buf, type, count ) \ if( !const_cond_false ) \ { \ uint _i; \ size_t cb = sizeof( type ) * (count); \ \ stat = inPos + cb <= filesize; \ read_check(); \ \ Com_Memcpy( buf, inBuf, cb ); \ inBuf += cb; \ inPos += cb; \ \ for( _i = 0; _i < (count); _i++ ) \ swap_##type( buf + _i ); \ } \ else \ (void)0 #define checked_align( a ) \ if( !const_cond_false ) \ { \ size_t _a = (a); \ \ if( _a ) \ { \ size_t ofs = ((_a - (inPos % _a)) % _a); \ \ stat = inPos + ofs <= filesize; \ read_check(); \ \ inBuf += ofs; \ inPos += ofs; \ } \ } \ else \ (void)0 #define checked_read_a( buf, type, count, a ) \ if( !const_cond_false ) \ { \ checked_align( a ); \ checked_read( buf, type, count ); \ } \ else \ (void)0 #define checked_skip( size, a ) \ if( !const_cond_false ) \ { \ size_t cb = (size); \ \ checked_align( a ); \ stat = inPos + cb <= filesize; \ read_check(); \ \ inBuf += cb; \ inPos += cb; \ } \ else \ (void)0 checked_read( &pack, x42PackHeader_v5_t, 1 ); checked_read_a( ret->bones, x42Bone_v5_t, h->numBones, 8 ); checked_read_a( ret->animGroups, x42AnimGroup_v5_t, h->numAnimGroups, 8 ); for( i = 0; i < h->numAnimGroups; i++ ) { uint j; for( j = ret->animGroups[i].beginBone; j < ret->animGroups[i].endBone; j++ ) ret->boneGroups[j] = (u8)i; } checked_align( 2 ); stat = read_packed_floats_swp( &inBuf, filesize, &inPos, pack.animPosPack, 3, (float*)ret->posValues, h->numPosValues, sizeof( vec3_t ) ); read_check(); if( h->modelFlags & X42_MF_UNIFORM_SCALE ) { stat = read_packed_floats_swp( &inBuf, filesize, &inPos, &pack.animScalePack, 1, (float*)ret->scaleValues, h->numScaleValues, sizeof( vec3_t ) ); read_check(); for( i = 0; i < h->numScaleValues; i++ ) { ret->scaleValues[i][1] = ret->scaleValues[i][0]; ret->scaleValues[i][2] = ret->scaleValues[i][0]; } } else { vec2_t bdxyz[3]; bdxyz[0][0] = bdxyz[1][0] = bdxyz[2][0] = pack.animScalePack[0]; bdxyz[0][1] = bdxyz[1][1] = bdxyz[2][1] = pack.animScalePack[1]; stat = read_packed_floats_swp( &inBuf, filesize, &inPos, bdxyz, 3, (float*)ret->scaleValues, h->numScaleValues, sizeof( vec3_t ) ); read_check(); } stat = read_packed_floats_s16n_swp( &inBuf, filesize, &inPos, 4, (float*)ret->rotValues, h->numRotValues, sizeof( quat_t ) ); read_check(); checked_read_a( ret->keyStream, x42KeyStreamEntry_v5_t, h->keyStreamLength, 8 ); checked_read_a( ret->animations, x42Animation_v5_t, h->numAnims, 8 ); checked_read_a( ret->tags, x42Tag_v5_t, h->numTags, 8 ); checked_read_a( ret->influences, x42Influence_v5_t, h->numInfluences, 8 ); checked_read_a( ret->lods, x42LodRange_v5_t, h->numLods, 8 ); checked_read_a( ret->groups, x42Group_v5_t, h->numGroups, 8 ); checked_align( 2 ); stat = read_packed_floats_swp( &inBuf, filesize, &inPos, pack.vertPosPack, 3, (float*)&ret->vertPos[0].pos, h->numVerts, sizeof( x42vertAnim_t ) ); read_check(); for( i = 0; i < h->numGroups; i++ ) { uint j; const x42group_t *g = ret->groups + i; size_t cbElem; if( !g->maxVertInfluences ) continue; cbElem = sizeof( byte ) * ((g->maxVertInfluences - 1) * 2 + 1); for( j = 0; j < g->numVerts; j++ ) { uint k; u8 in[7]; float sum; x42vertAnim_t *v; checked_read( in, u8, cbElem ); v = ret->vertPos + g->firstVert + j; sum = 0; for( k = 0; k < g->maxVertInfluences - 1U; k++ ) { v->idx[k] = in[k * 2 + 0]; v->wt[k] = X42_FLOAT_U8N_UNPACK( in[k * 2 + 1] ); sum += v->wt[k]; } v->idx[k] = in[k * 2 + 0]; v->wt[k] = 1.0F - sum; } } if( ret->vertNorm ) { stat = read_packed_floats_s8n_swp( &inBuf, filesize, &inPos, 3, (float*)&ret->vertNorm[0].norm, h->numVerts, sizeof( x42vertNormal_t ) ); read_check(); } else if( h->modelFlags & X42_MF_HAS_NORMALS ) checked_skip( sizeof( s8[3] ) * h->numVerts, 0 ); if( ret->vertTan ) { stat = read_packed_floats_s8n_swp( &inBuf, filesize, &inPos, 7, (float*)&ret->vertTan[0].tan, h->numVerts, sizeof( x42vertTangent_t ) ); read_check(); for( i = 0; i < h->numVerts; i++ ) ret->vertTan[i].nfac1 = ret->vertTan[i].nfac0; } else if( h->modelFlags & X42_MF_HAS_TANGENT_BASIS ) checked_skip( sizeof( s8[7] ) * h->numVerts, 0 ); if( ret->vertTc ) { checked_align( 2 ); stat = read_packed_floats_swp( &inBuf, filesize, &inPos, pack.vertTcPack, 2, (float*)ret->vertTc, h->numVerts, sizeof( vec2_t ) ); read_check(); } else if( h->modelFlags & X42_MF_HAS_TEXTURE_COORDINATES ) checked_skip( sizeof( u16[2] ) * h->numVerts, 2 ); if( ret->vertCl ) { checked_read_a( ret->vertCl, rgba_t, h->numVerts, 4 ); } else if( h->modelFlags & X42_MF_HAS_COLORS ) checked_skip( sizeof( rgba_t ) * h->numVerts, 4 ); checked_read_a( ret->indices, x42Index_t, h->numIndices, 4 ); checked_read( (char*)ret->strings, u8, h->nameBlobLen ); #undef checked_skip #undef checked_read_a #undef checked_read #undef checked_align #undef read_check mod->type = MOD_X42; mod->x42 = ret; return true; }