CL_XMLTokenizer::CL_XMLTokenizer(CL_IODevice &input) : impl(new CL_XMLTokenizer_Generic) { impl->input = input; impl->size = input.get_size(); impl->pos = 0; CL_DataBuffer buffer(impl->size); input.receive(buffer.get_data(), buffer.get_size(), true); CL_StringHelp::BOMType bom_type = CL_StringHelp::detect_bom(buffer.get_data(), buffer.get_size()); switch (bom_type) { default: case CL_StringHelp::bom_none: impl->data = CL_StringHelp::utf8_to_text(CL_StringRef8(buffer.get_data(), buffer.get_size(), false)); break; case CL_StringHelp::bom_utf32_be: case CL_StringHelp::bom_utf32_le: throw CL_Exception("UTF-16 XML files not supported yet"); break; case CL_StringHelp::bom_utf16_be: case CL_StringHelp::bom_utf16_le: throw CL_Exception("UTF-32 XML files not supported yet"); break; case CL_StringHelp::bom_utf8: impl->data = CL_StringHelp::utf8_to_text(CL_StringRef8(buffer.get_data()+3, buffer.get_size()-3, false)); break; } }
CL_ShaderObject CL_ShaderObject::load(CL_GraphicContext &gc, const CL_StringRef &resource_id, CL_ResourceManager *resources) { CL_Resource resource = resources->get_resource(resource_id); CL_String filename = resource.get_element().get_attribute("file"); CL_String type = resource.get_element().get_tag_name(); CL_ShaderType shader_type; if (type == "fragment-shader") shader_type = cl_shadertype_fragment; else if (type == "vertex-shader") shader_type = cl_shadertype_vertex; else throw CL_Exception("CL_ShaderObject: Unknown shader type: " + type); CL_VirtualDirectory directory = resources->get_directory(resource); CL_IODevice file = directory.open_file(filename, CL_File::open_existing, CL_File::access_read, CL_File::share_read); int size = file.get_size(); CL_String8 source(size, 0); file.read(&source[0], size); CL_ShaderObject shader_object(gc, shader_type, CL_StringHelp::local8_to_text(source)); if (resource.get_element().get_attribute("compile", "true") == "true") if(!shader_object.compile()) throw CL_Exception(cl_format("Unable to compiler shader program %1: %2", resource_id, shader_object.get_info_log())); return shader_object; }
CL_ShaderObject CL_ShaderObject::load(CL_GraphicContext &gc, CL_ShaderType shader_type, CL_IODevice &file) { int size = file.get_size(); CL_String8 source(size, 0); file.read(&source[0], size); return CL_ShaderObject(gc, shader_type, CL_StringHelp::local8_to_text(source)); }
CL_PCXProvider_Impl::CL_PCXProvider_Impl( CL_IODevice &datafile) { image = NULL; bool little_endian = datafile.is_little_endian(); if (!little_endian) datafile.set_little_endian_mode(); read_pcx(datafile); if (!little_endian) datafile.set_big_endian_mode(); }
cl_byte64 CL_ZipReader_Impl::deflate_read(void *data, cl_byte64 size, bool read_all) { zs.next_out = (Bytef *) data; zs.avail_out = size; // Continue feeding zlib data until we get our data: while (zs.avail_out > 0) { // zlib needs more data: if (zs.avail_in == 0 && compressed_pos < local_header.compressed_size) { // Read some compressed data: int received_input = 0; while (received_input < 16*1024) { received_input += input.receive(zbuffer, int(cl_min(16*1024, local_header.compressed_size - compressed_pos)), true); if (compressed_pos + received_input == local_header.compressed_size) break; } compressed_pos += received_input; zs.next_in = (Bytef *) zbuffer; zs.avail_in = received_input; } // Decompress data: int result = inflate(&zs, (compressed_pos == local_header.compressed_size) ? Z_FINISH : Z_NO_FLUSH); if (result == Z_STREAM_END) break; if (result == Z_NEED_DICT) throw CL_Exception("Zlib inflate wants a dictionary!"); if (result == Z_DATA_ERROR) throw CL_Exception("Zip data stream is corrupted"); if (result == Z_STREAM_ERROR) throw CL_Exception("Zip stream structure was inconsistent!"); if (result == Z_MEM_ERROR) throw CL_Exception("Zlib did not have enough memory to decompress file!"); if (result == Z_BUF_ERROR) throw CL_Exception("Not enough data in buffer when Z_FINISH was used"); if (result != Z_OK) throw CL_Exception("Zlib inflate failed while decompressing zip file!"); } return size - zs.avail_out; }
void CL_CSSDocument_Impl::load(const CL_String &filename, const CL_VirtualDirectory &directory) { CL_String path = CL_PathHelp::get_fullpath(filename, CL_PathHelp::path_type_file); // Load document into a buffer: CL_IODevice input = directory.open_file_read(filename); int size = input.get_size(); if (size < 0) throw CL_Exception("IODevice does not support get_size()"); CL_DataBuffer data(size); int bytes_read = input.read(data.get_data(), data.get_size()); data.set_size(bytes_read); // Start parsing: unsigned char *data_ptr = (unsigned char *) data.get_data(); whitespace_comments(data_ptr, bytes_read); int pos = 0; while (pos < bytes_read) { unsigned char ch = data_ptr[pos]; switch (ch) { case ' ': case '\t': case '\r': case '\n': pos++; break; case '@': // import pos = load_import(data_ptr, pos, bytes_read, directory, path); break; default: // ruleset pos = load_ruleset(data_ptr, pos, bytes_read); break; } } }
unsigned int CL_SoundProvider_Wave_Impl::find_subchunk(const char *chunk, CL_IODevice &source, unsigned int file_offset, unsigned int max_offset ) { char subchunk1_id[4]; max_offset -= 8; // Each subchunk must contains at least name and size while(file_offset < max_offset) { source.seek(file_offset); source.read(subchunk1_id, 4); cl_ubyte32 subchunk1_size = source.read_uint32(); if (!memcmp(subchunk1_id, chunk, 4)) { // Found chunk return subchunk1_size; } file_offset += subchunk1_size + 8; } throw CL_Exception("Block not found!"); }
void CL_CSSDocument_Impl::load(const CL_StringRef &path, CL_IODevice &input) { // Load document into a buffer: int size = input.get_size(); if (size < 0) throw CL_Exception("IODevice does not support get_size()"); CL_DataBuffer data(size); int bytes_read = input.read(data.get_data(), data.get_size()); data.set_size(bytes_read); // Start parsing: unsigned char *data_ptr = (unsigned char *) data.get_data(); whitespace_comments(data_ptr, bytes_read); int pos = 0; while (pos < bytes_read) { unsigned char ch = data_ptr[pos]; switch (ch) { case ' ': case '\t': case '\r': case '\n': pos++; break; case '@': // import pos = load_import(data_ptr, pos, bytes_read, path); break; default: // ruleset pos = load_ruleset(data_ptr, pos, bytes_read); break; } } }
void CL_PCXProvider_Impl::read_pcx( CL_IODevice &_datafile) { // Read the file header and initialize the variables // This method was created to breakup the PCX decoding code // so the initializing code was separated from the actual // decoding algorithm unsigned char header[128]; { int read = _datafile.read(header, 128); if (read != 128) throw CL_Exception("File not big enough to read the PCX header"); } // only the useful fields that will be used more than once struct PCXHeader { unsigned char version; unsigned char encoding; unsigned char bits_per_pixel_per_plane; short xmin; short ymin; short xmax; short ymax; unsigned char color_map[48]; unsigned char nplanes; unsigned short bytes_per_line; } pcx_header; if (header[0] != 10) throw CL_Exception("Not a PCX file"); pcx_header.version = header[1]; pcx_header.encoding = header[2]; pcx_header.bits_per_pixel_per_plane = header[3]; pcx_header.xmin = (header[5] << 8) | header[4]; pcx_header.ymin = (header[7] << 8) | header[6]; pcx_header.xmax = (header[9] << 8) | header[8]; pcx_header.ymax = (header[11] << 8) | header[10]; const int width = (pcx_header.xmax - pcx_header.xmin) + 1; const int height = (pcx_header.ymax - pcx_header.ymin) + 1; memcpy(pcx_header.color_map, &header[16], sizeof(pcx_header.color_map)); pcx_header.nplanes = header[65]; pcx_header.bytes_per_line = (header[67] << 8) | header[66]; // both 8bit with palette and 24bit rgb modes require version 5 if (pcx_header.version < 5) throw CL_Exception("PCX version unsupported"); const int total_line_bytes = pcx_header.bytes_per_line * pcx_header.nplanes; int pitch = 0; // decide which pixelformat to use (8 bit palette or 24 bit) if (pcx_header.nplanes == 3 && pcx_header.bits_per_pixel_per_plane == 8) { // 24 bit RGB mode pitch = width * 3; image = new unsigned char[pitch * height]; if (image == 0) throw CL_Exception("Unable to allocate memory for pcx image"); unsigned char *p = image; const int extra = total_line_bytes - pitch; // get the data if (!pcx_header.encoding) { // uncompressed for (int y = 0; y < height; y++) { _datafile.read(p, pitch); if (extra > 0) _datafile.seek(extra, CL_IODevice::seek_cur); p += pitch; } } else { // compressed for (int y = 0; y < height; y++) { int count; // first red component int x = 0, xx = 0, comp = 0; while (x < total_line_bytes) { int ch = _datafile.read_uint8(); if ((ch & 0xC0) == 0xC0) { count = ch & 0x3F; ch = _datafile.read_uint8(); } else count = 1; while (count--) { if (xx < width) image[(y * pitch) + ((xx * 3) + comp)] = ch; x++; if (x == pcx_header.bytes_per_line) { // blue component now comp = 1; xx = 0; } else if (x == pcx_header.bytes_per_line*2) { // green component now comp = 2; xx = 0; } else xx++; } } } } CL_PCXProvider_Impl::sized_format = cl_bgr8; CL_PCXProvider_Impl::pitch = pitch; CL_PCXProvider_Impl::width = width; CL_PCXProvider_Impl::height = height; } else if (pcx_header.nplanes == 1 && pcx_header.bits_per_pixel_per_plane == 8) { // 8 bit indexed mode pitch = width; image = new unsigned char[pitch * height]; if (image == 0) throw CL_Exception("Unable to allocate memory for pcx image"); unsigned char *p = image; const int extra = total_line_bytes - pitch; // get the data if (!pcx_header.encoding) { // uncompressed for (int y = 0; y < height; y++) { _datafile.read(p, pitch); if (extra > 0) _datafile.seek(extra, CL_IODevice::seek_cur); p += pitch; } } else { // compressed for (int y = 0; y < height; y++) { int count; int x = 0; while (x < total_line_bytes) { int ch = _datafile.read_uint8(); if ((ch & 0xC0) == 0xC0) { count = ch & 0x3F; ch = _datafile.read_uint8(); } else count = 1; while (count--) { if (x < width) { *p = ch; p++; } x++; } } } } // read the palette if (_datafile.read_int8() != 12) { delete[] image; throw CL_Exception("Palette not found"); } for (int i = 0; i < 256; i++) { const int r = _datafile.read_uint8(); const int g = _datafile.read_uint8(); const int b = _datafile.read_uint8(); palette[i].set_color(r, g, b); } CL_PCXProvider_Impl::sized_format = cl_color_index; CL_PCXProvider_Impl::pitch = pitch; CL_PCXProvider_Impl::width = width; CL_PCXProvider_Impl::height = height; } else throw CL_Exception("Unsupported PCX format"); }
void CustomIOFunctions::write( png_structp png_ptr, png_bytep data, png_size_t length ) { CL_IODevice *iodev = (CL_IODevice*)png_get_io_ptr(png_ptr); iodev->write(data, length); }
void CL_SoundProvider_Wave_Impl::load(CL_IODevice &source) { source.set_little_endian_mode(); char chunk_id[4]; source.read(chunk_id, 4); if (memcmp(chunk_id, "RIFF", 4)) throw CL_Exception("Expected RIFF header!"); cl_ubyte32 chunk_size = source.read_uint32(); char format_id[4]; source.read(format_id, 4); if (memcmp(format_id, "WAVE", 4)) throw CL_Exception("Expected WAVE header!"); cl_ubyte32 subchunk_pos = source.get_position(); cl_ubyte32 subchunk1_size = find_subchunk("fmt ", source, subchunk_pos, chunk_size); cl_ubyte16 audio_format = source.read_uint16(); num_channels = source.read_uint16(); frequency = source.read_uint32(); cl_ubyte32 byte_rate = source.read_uint32(); cl_ubyte16 block_align = source.read_uint16(); cl_ubyte16 bits_per_sample = source.read_uint16(); if (bits_per_sample == 16) format = sf_16bit_signed; else if (bits_per_sample == 8) format = sf_8bit_unsigned; else throw CL_Exception("Unsupported wave sample format"); cl_ubyte32 subchunk2_size = find_subchunk("data", source, subchunk_pos, chunk_size); data = new char[subchunk2_size]; source.read(data, subchunk2_size); num_samples = subchunk2_size / block_align; }
void CL_ZipFileHeader::load(CL_IODevice &input) { signature = input.read_int32(); if (signature != 0x02014b50) { throw CL_Exception("Incorrect File Header signature"); } version_made_by = input.read_int16(); version_needed_to_extract = input.read_int16(); general_purpose_bit_flag = input.read_int16(); compression_method = input.read_int16(); last_mod_file_time = input.read_int16(); last_mod_file_date = input.read_int16(); crc32 = input.read_uint32(); compressed_size = input.read_int32(); uncompressed_size = input.read_int32(); file_name_length = input.read_int16(); extra_field_length = input.read_int16(); file_comment_length = input.read_int16(); disk_number_start = input.read_int16(); internal_file_attributes = input.read_int16(); external_file_attributes = input.read_int32(); relative_offset_of_local_header = input.read_int32(); filename.resize(file_name_length); char *str1 = new char[file_name_length]; char *str2 = new char[extra_field_length]; char *str3 = new char[file_comment_length]; try { input.read(str1, file_name_length); input.read(str2, extra_field_length); input.read(str3, file_comment_length); if (general_purpose_bit_flag & CL_ZIP_USE_UTF8) { filename = CL_StringHelp::utf8_to_text(CL_StringRef8(str1, file_name_length, false)); file_comment = CL_StringHelp::utf8_to_text(CL_StringRef8(str3, file_comment_length, false)); } else { filename = CL_StringHelp::cp437_to_text(CL_StringRef8(str1, file_name_length, false)); file_comment = CL_StringHelp::cp437_to_text(CL_StringRef8(str3, file_comment_length, false)); } extra_field = CL_DataBuffer(str2, extra_field_length); delete[] str1; delete[] str2; delete[] str3; } catch (...) { delete[] str1; delete[] str2; delete[] str3; throw; } }
void CL_ZipFileHeader::save(CL_IODevice &output) { CL_String8 str_filename; CL_String8 str_comment; if (general_purpose_bit_flag & CL_ZIP_USE_UTF8) { str_filename = CL_StringHelp::text_to_utf8(filename); str_comment = CL_StringHelp::text_to_utf8(file_comment); } else { str_filename = CL_StringHelp::text_to_cp437(filename); str_comment = CL_StringHelp::text_to_cp437(file_comment); } file_name_length = str_filename.length(); file_comment_length = str_comment.length(); output.write_int32(signature); output.write_int16(version_made_by); output.write_int16(version_needed_to_extract); output.write_int16(general_purpose_bit_flag); output.write_int16(compression_method); output.write_int16(last_mod_file_time); output.write_int16(last_mod_file_date); output.write_uint32(crc32); output.write_int32(compressed_size); output.write_int32(uncompressed_size); output.write_int16(file_name_length); output.write_int16(extra_field_length); output.write_int16(file_comment_length); output.write_int16(disk_number_start); output.write_int16(internal_file_attributes); output.write_int32(external_file_attributes); output.write_int32(relative_offset_of_local_header); output.write(str_filename.data(), file_name_length); output.write(extra_field.get_data(), extra_field_length); output.write(file_comment.data(), file_comment_length); }