CL_String CL_CSSLayoutNode_Impl::escape_text(CL_String text) { while (true) { CL_String::size_type pos = text.find('\r'); if (pos == CL_String::npos) break; text.replace(pos, 1, "\\r"); } while (true) { CL_String::size_type pos = text.find('\n'); if (pos == CL_String::npos) break; text.replace(pos, 1, "\\n"); } while (true) { CL_String::size_type pos = text.find('\t'); if (pos == CL_String::npos) break; text.replace(pos, 1, "\\t"); } return text; }
CL_String HTMLPage::download_url(const CL_String &page_url, const CL_String &refererer_url) { HTMLUrl url(page_url, refererer_url); CL_Console::write_line("Downloading URL: %1", url.to_string()); CL_String8 request; request = cl_format("GET %1 HTTP/1.1\r\n", url.path+url.query); if (refererer_url.empty()) request += cl_format("Host: %1\r\nConnection: close\r\nAccept: text/plain, text/html\r\nUser-Agent: CSSTokenize/0.1\r\n\r\n", url.host); else request += cl_format("Host: %1\r\nConnection: close\r\nReferer: %2\r\nAccept: text/plain, text/html\r\nUser-Agent: CSSTokenize/0.1\r\n\r\n", url.host, refererer_url); //MessageBoxW(0, CL_StringHelp::utf8_to_ucs2(cl_format("GET %1 HTTP/1.1\r\n", url.path+url.query)).c_str(), L"Download URL", MB_OK);; CL_TCPConnection connection(CL_SocketName(url.host, url.port)); connection.set_nodelay(true); connection.send(request.data(), request.length(), true); CL_String response; while (connection.get_read_event().wait(15000)) { char buffer[16*1024]; int received = connection.read(buffer, 16*1024, false); if (received == 0) break; response.append(buffer, received); } connection.disconnect_graceful(); CL_String response_header = response.substr(0, response.find("\r\n\r\n")); CL_String content = response.substr(response_header.length() + 4); if (response_header.find("Transfer-Encoding: chunked") != CL_String::npos) { CL_String::size_type start = 0; while (true) { CL_String::size_type end = content.find("\r\n", start); if (end == CL_String::npos) end = content.length(); CL_String str_length = content.substr(start, end-start); int length = CL_StringHelp::text_to_int(str_length, 16); content = content.substr(0, start) + content.substr(end+2); start += length; end = content.find("\r\n", start); if (end == CL_String::npos) end = content.length(); content = content.substr(0, start) + content.substr(end+2); if (length == 0) break; } } return content; }
CL_Image HTMLPage::load_image(CL_GraphicContext &gc, const CL_String &image_url) { HTMLUrl url(image_url, pageurl); CL_Console::write_line("Downloading image: %1", url.to_string()); CL_String8 request; request = cl_format("GET %1 HTTP/1.1\r\n", url.path+url.query); request += cl_format("Host: %1\r\nConnection: close\r\nReferer: %2\r\nAccept: image/png, image/jpeg\r\nUser-Agent: CSSTokenize/0.1\r\n\r\n", url.host, pageurl.to_string()); CL_TCPConnection connection(CL_SocketName(url.host, url.port)); connection.set_nodelay(true); connection.send(request.data(), request.length(), true); CL_String response; while (connection.get_read_event().wait(15000)) { char buffer[16*1024]; int received = connection.read(buffer, 16*1024, false); if (received == 0) break; response.append(buffer, received); } connection.disconnect_graceful(); CL_String response_header = response.substr(0, response.find("\r\n\r\n")); CL_String content = response.substr(response_header.length() + 4); if (response_header.find("Transfer-Encoding: chunked") != CL_String::npos) { CL_String::size_type start = 0; while (true) { CL_String::size_type end = content.find("\r\n", start); if (end == CL_String::npos) end = content.length(); CL_String str_length = content.substr(start, end-start); int length = CL_StringHelp::text_to_int(str_length, 16); content = content.substr(0, start) + content.substr(end+2); start += length; end = content.find("\r\n", start); if (end == CL_String::npos) end = content.length(); content = content.substr(0, start) + content.substr(end+2); if (length == 0) break; } } CL_DataBuffer buffer(content.data(), content.length()); CL_IODevice_Memory device(buffer); if (response_header.find("image/png") != CL_String::npos) { CL_PixelBuffer pb = CL_PNGProvider::load(device); return CL_Image(gc, pb, pb.get_size()); } else if (response_header.find("image/jpeg") != CL_String::npos) { CL_PixelBuffer pb = CL_JPEGProvider::load(device); return CL_Image(gc, pb, pb.get_size()); } else if (response_header.find("image/gif") != CL_String::npos) { CL_PixelBuffer pb = GIFProvider::load(device); return CL_Image(gc, pb, pb.get_size()); } else { CL_Console::write_line("Unknown image type: %1", CL_String8(buffer.get_data(), buffer.get_size())); return CL_Image(); } }
CL_String CL_PathHelp::make_relative( const CL_String &base_path, const CL_String &absolute_path, PathType path_type) { CL_String base = add_trailing_slash(normalize(base_path, path_type), path_type); CL_String absolute = normalize(absolute_path, path_type); if (path_type == path_type_file) { CL_String base_location = get_location(base, path_type_file); CL_String absolute_location = get_location(absolute, path_type_file); if (is_relative(base, path_type)) { #ifdef WIN32 if (base_location.length() == 2 && base_location[1] == ':') { int drive = 0; if (base_location[0] >= 'A' && base_location[0] <= 'Z') drive = base_location[0] - 'A' + 1; else if (base_location[0] >= 'a' && base_location[0] <= 'z') drive = base_location[0] - 'a' + 1; else throw CL_Exception(cl_format("Invalid drive: %1", base_location)); TCHAR working_dir[MAX_PATH]; memset(working_dir, 0, sizeof(TCHAR)*MAX_PATH); if (_tgetdcwd(drive, working_dir, MAX_PATH) == 0) throw CL_Exception(cl_format("Unable to get current working directory for %1!", base_location)); base = add_trailing_slash(working_dir, path_type) + base; } else if (base_location.empty()) { TCHAR working_dir[MAX_PATH]; memset(working_dir, 0, sizeof(TCHAR)*MAX_PATH); if (GetCurrentDirectory(MAX_PATH, working_dir) == FALSE) throw CL_Exception(cl_format("Unable to get current working directory for %1!", base_location)); base = add_trailing_slash(working_dir, path_type) + base; } else { throw CL_Exception(cl_format("Error in make_relative with base path: %1", base_path)); } #else char working_dir[1024]; memset(working_dir, 0, 1024); if (getcwd(working_dir, 1024) == 0) throw CL_Exception("Unable to get current working directory!"); base = add_trailing_slash(working_dir, path_type) + base; #endif } if (is_relative(absolute, path_type)) { #ifdef WIN32 if (absolute_location.length() == 2 && absolute_location[1] == ':') { int drive = 0; if (absolute_location[0] >= 'A' && absolute_location[0] <= 'Z') drive = absolute_location[0] - 'A' + 1; else if (absolute_location[0] >= 'a' && absolute_location[0] <= 'z') drive = absolute_location[0] - 'a' + 1; else throw CL_Exception(cl_format("Invalid drive: %1", absolute_location)); TCHAR working_dir[MAX_PATH]; memset(working_dir, 0, sizeof(TCHAR)*MAX_PATH); if (_tgetdcwd(drive, working_dir, MAX_PATH) == 0) throw CL_Exception(cl_format("Unable to get current working directory for %1!", absolute_location)); absolute = add_trailing_slash(working_dir, path_type) + absolute; } else if (absolute_location.empty()) { TCHAR working_dir[MAX_PATH]; memset(working_dir, 0, sizeof(TCHAR)*MAX_PATH); if (GetCurrentDirectory(MAX_PATH, working_dir) == FALSE) throw CL_Exception(cl_format("Unable to get current working directory for %1!", absolute_location)); absolute = add_trailing_slash(working_dir, path_type) + absolute; } else { throw CL_Exception(cl_format("Error in make_relative with absolute path: %1", absolute_path)); } #else char working_dir[1024]; memset(working_dir, 0, 1024); if (getcwd(working_dir, 1024) == 0) throw CL_Exception("Unable to get current working directory!"); absolute = add_trailing_slash(working_dir, path_type) + absolute; #endif } base_location = get_location(base, path_type_file); absolute_location = get_location(absolute, path_type_file); if (CL_StringHelp::compare(absolute_location, base_location, true) != 0) return absolute_path; } if (is_relative(base, path_type)) throw CL_Exception(cl_format("Relative path %1 used as base path for make_relative", base_path)); if (is_relative(absolute, path_type)) throw CL_Exception(cl_format("Relative path %1 used as absolute path for make_relative", absolute_path)); CL_String relative; CL_String relative_end; bool differs = false; CL_String::size_type start_pos = 0, end_pos = 0; while (true) { if (path_type == path_type_file) { end_pos = base.find_first_of("\\/", start_pos); } else { end_pos = base.find('/', start_pos); } if (end_pos == CL_String::npos) break; if (!differs) { CL_String base_element = base.substr(start_pos, end_pos - start_pos + 1); CL_String absolute_element = absolute.substr(start_pos, end_pos - start_pos + 1); bool same_element = false; if (path_type == path_type_file) { #ifdef WIN32 same_element = (CL_StringHelp::compare(base_element, absolute_element, true) == 0); #else same_element = (base_element == absolute_element); #endif } else { same_element = (base_element == absolute_element); } if (!same_element) { relative_end = absolute.substr(start_pos); differs = true; } else { relative_end = absolute.substr(end_pos+1); } } if (differs) { if (path_type_file) { #ifdef WIN32 relative += "..\\"; #else relative += "../"; #endif } else { relative += "../"; } } start_pos = end_pos + 1; } return relative + relative_end; }