Merge branch 'development' into LTS_development

# Conflicts:
#	lib/http_parser.cpp
This commit is contained in:
Thulinma 2020-03-03 12:28:04 +01:00
commit eb8694052d
17 changed files with 401 additions and 304 deletions

View file

@ -186,6 +186,7 @@ set(libHeaders
lib/ebml.h
lib/ebml_socketglue.h
lib/websocket.h
lib/url.h
)
########################################
@ -240,6 +241,7 @@ add_library (mist
lib/ebml.cpp
lib/ebml_socketglue.cpp
lib/websocket.cpp
lib/url.cpp
)
if (NOT APPLE)
set (LIBRT -lrt)

View file

@ -1,4 +1,5 @@
#include "http_parser.h"
#include "url.h"
#include "socket.h"
namespace HTTP{

View file

@ -7,282 +7,9 @@
#include "defines.h"
#include "encode.h"
#include "timing.h"
#include "url.h"
#include <iomanip>
/// Helper function to check if the given c-string is numeric or not
static bool is_numeric(const char *str){
while (str[0] != 0){
if (str[0] < 48 || str[0] > 57){return false;}
++str;
}
return true;
}
/// Constructor that does the actual parsing
HTTP::URL::URL(const std::string &url){
IPv6Addr = false;
// first detect protocol at the start, if any
size_t proto_sep = url.find("://");
if (proto_sep != std::string::npos){
protocol = url.substr(0, proto_sep);
proto_sep += 3;
}else{
proto_sep = 0;
if (url.substr(0, 2) == "//"){proto_sep = 2;}
}
// proto_sep now points to the start of the host, guaranteed
// continue by finding the path, if any
size_t first_slash = url.find_first_of("/?#", proto_sep);
if (first_slash != std::string::npos){
if (url[first_slash] == '/'){
path = url.substr(first_slash + 1);
}else{
path = url.substr(first_slash);
}
if (protocol != "rtsp"){
size_t hmark = path.find('#');
if (hmark != std::string::npos){
frag = Encodings::URL::decode(path.substr(hmark + 1));
path.erase(hmark);
}
size_t qmark = path.find('?');
if (qmark != std::string::npos){
args = path.substr(qmark + 1);
path.erase(qmark);
}
}
if (path.size()){
if (path[0] == '/'){path.erase(0, 1);}
size_t dots = path.find("/./");
while (dots != std::string::npos){
DONTEVEN_MSG("%s (/./ -> /)", path.c_str());
path.erase(dots, 2);
dots = path.find("/./");
}
dots = path.find("//");
while (dots != std::string::npos){
DONTEVEN_MSG("%s (// -> /)", path.c_str());
path.erase(dots, 1);
dots = path.find("//");
}
if (path[0] == '/'){path.erase(0, 1);}
dots = path.find("/../");
while (dots != std::string::npos){
size_t prevslash = path.rfind('/', dots - 1);
if (prevslash == std::string::npos || dots == 0){
path.erase(0, dots + 4);
}else{
path.erase(prevslash + 1, dots - prevslash + 3);
}
dots = path.find("/../");
}
if (path.substr(0, 2) == "./"){path.erase(0, 2);}
if (path.substr(0, 3) == "../"){path.erase(0, 3);}
path = Encodings::URL::decode(path);
}
}
// user, pass, host and port are now definitely between proto_sep and first_slash
std::string uphp = url.substr(proto_sep, first_slash - proto_sep); // user+pass+host+port
// Check if we have a user/pass before the host
size_t at_sign = uphp.find('@');
if (at_sign != std::string::npos){
std::string creds = uphp.substr(0, at_sign);
uphp.erase(0, at_sign + 1);
size_t colon = creds.find(':');
if (colon != std::string::npos){
user = Encodings::URL::decode(creds.substr(0, colon));
pass = Encodings::URL::decode(creds.substr(colon + 1));
}else{
user = Encodings::URL::decode(creds);
}
}
// we check for [ at the start because we may have an IPv6 address as host
if (uphp[0] == '['){
// IPv6 address - find matching brace
IPv6Addr = true;
size_t closing_brace = uphp.find(']');
host = uphp.substr(1, closing_brace - 1);
// continue by finding port, if any
size_t colon = uphp.find(':', closing_brace);
if (colon == std::string::npos){
// no port. Assume default
port = "";
}else{
// we have a port number, read it
port = uphp.substr(colon + 1);
if (!is_numeric(port.c_str())){
host += ":" + port;
port = "";
}
}
}else{
//"normal" host - first find port, if any
size_t colon = uphp.rfind(':');
if (colon == std::string::npos){
// no port. Assume default
port = "";
host = uphp;
}else{
// we have a port number, read it
port = uphp.substr(colon + 1);
host = uphp.substr(0, colon);
if (!is_numeric(port.c_str())){
IPv6Addr = true;
host += ":" + port;
port = "";
}
}
}
// if the host is numeric, assume it is a port, instead
if (host.size() && is_numeric(host.c_str())){
port = host;
host = "";
}
EXTREME_MSG("URL: %s", getUrl().c_str());
}
/// Returns the port in numeric format
uint32_t HTTP::URL::getPort() const{
if (!port.size()){return getDefaultPort();}
return atoi(port.c_str());
}
/// Returns the default port for the protocol in numeric format
uint32_t HTTP::URL::getDefaultPort() const{
if (protocol == "http"){return 80;}
if (protocol == "https"){return 443;}
if (protocol == "rtmp"){return 1935;}
if (protocol == "rtmps"){return 443;}
if (protocol == "dtsc"){return 4200;}
if (protocol == "rtsp"){return 554;}
return 0;
}
/// Returns the file extension of the URL, or an empty string if none.
std::string HTTP::URL::getExt() const{
if (path.rfind('.') == std::string::npos){
return "";
}
return path.substr(path.rfind('.')+1);
}
/// Returns the full URL in string format
std::string HTTP::URL::getUrl() const{
std::string ret;
if (protocol.size()){
ret = protocol + "://";
}else{
ret = "//";
}
if (user.size() || pass.size()){
ret += Encodings::URL::encode(user) + ":" + Encodings::URL::encode(pass) + "@";
}
if (IPv6Addr){
ret += "[" + host + "]";
}else{
ret += host;
}
if (port.size() && getPort() != getDefaultPort()){ret += ":" + port;}
ret += "/";
if (protocol == "rtsp"){
if (path.size()){ret += Encodings::URL::encode(path, "/:=@[]#?&");}
}else{
if (path.size()){ret += Encodings::URL::encode(path, "/:=@[]");}
}
if (args.size()){ret += "?" + args;}
if (frag.size()){ret += "#" + Encodings::URL::encode(frag, "/:=@[]#?&");}
return ret;
}
/// Returns the full file path, in case this is a local file URI
std::string HTTP::URL::getFilePath() const{
return "/"+path;
}
/// Returns the URL in string format without auth and frag
std::string HTTP::URL::getProxyUrl() const{
std::string ret;
if (protocol.size()){
ret = protocol + "://";
}else{
ret = "//";
}
if (IPv6Addr){
ret += "[" + host + "]";
}else{
ret += host;
}
if (port.size() && getPort() != getDefaultPort()){ret += ":" + port;}
ret += "/";
if (protocol == "rtsp"){
if (path.size()){ret += Encodings::URL::encode(path, "/:=@[]#?&");}
}else{
if (path.size()){ret += Encodings::URL::encode(path, "/:=@[]");}
}
if (args.size()){ret += "?" + args;}
return ret;
}
/// Returns the URL in string format without args and frag
std::string HTTP::URL::getBareUrl() const{
std::string ret;
if (protocol.size()){
ret = protocol + "://";
}else{
ret = "//";
}
if (user.size() || pass.size()){
ret += Encodings::URL::encode(user) + ":" + Encodings::URL::encode(pass) + "@";
}
if (IPv6Addr){
ret += "[" + host + "]";
}else{
ret += host;
}
if (port.size() && getPort() != getDefaultPort()){ret += ":" + port;}
ret += "/";
if (protocol == "rtsp"){
if (path.size()){ret += Encodings::URL::encode(path, "/:=@[]#?&");}
}else{
if (path.size()){ret += Encodings::URL::encode(path, "/:=@[]");}
}
return ret;
}
/// Returns a URL object for the given link, resolved relative to the current URL object.
HTTP::URL HTTP::URL::link(const std::string &l) const{
// Full link
if (l.find("://") < l.find('/') && l.find('/' != std::string::npos)){
DONTEVEN_MSG("Full link: %s", l.c_str());
return URL(l);
}
// Absolute link
if (l[0] == '/'){
DONTEVEN_MSG("Absolute link: %s", l.c_str());
if (l.size() > 1 && l[1] == '/'){
// Same-protocol full link
return URL(protocol + ":" + l);
}else{
// Same-domain/port absolute link
URL tmp = *this;
tmp.args.clear();
tmp.path = l.substr(1);
// Abuse the fact that we don't check for arguments in getUrl()
return URL(tmp.getUrl());
}
}
// Relative link
std::string tmpUrl = getBareUrl();
size_t slashPos = tmpUrl.rfind('/');
if (slashPos == std::string::npos){
tmpUrl += "/";
}else{
tmpUrl.erase(slashPos + 1);
}
DONTEVEN_MSG("Relative link: %s+%s", tmpUrl.c_str(), l.c_str());
return URL(tmpUrl + l);
}
/// This constructor creates an empty HTTP::Parser, ready for use for either reading or writing.
/// All this constructor does is call HTTP::Parser::Clean().
HTTP::Parser::Parser(){

View file

@ -73,28 +73,5 @@ namespace HTTP{
void Trim(std::string &s);
};
/// URL parsing class. Parses full URL into its subcomponents
class URL{
public:
URL(const std::string &url = "");
uint32_t getPort() const;
uint32_t getDefaultPort() const;
std::string getExt() const;
std::string getUrl() const;
std::string getFilePath() const;
std::string getBareUrl() const;
std::string getProxyUrl() const;
std::string host; ///< Hostname or IP address of URL
std::string protocol; ///< Protocol of URL
std::string port; ///< Port of URL
std::string path; ///< Path after the first slash (not inclusive) but before any question mark
std::string args; ///< Everything after the question mark in the path, if it was present
std::string frag; ///< Everything after the # in the path, if it was present
std::string user; ///< Username, if it was present
std::string pass; ///< Password, if it was present
URL link(const std::string &l) const;
bool IPv6Addr;
};
}// namespace HTTP

View file

@ -6,6 +6,7 @@
#include "h265.h"
#include "http_parser.h"
#include "util.h"
#include "url.h"
namespace SDP{

281
lib/url.cpp Normal file
View file

@ -0,0 +1,281 @@
/// \file http_parser.cpp
/// Holds all code for the HTTP namespace.
#include "url.h"
#include "defines.h"
#include "encode.h"
/// Helper function to check if the given c-string is numeric or not
static bool is_numeric(const char *str){
while (str[0] != 0){
if (str[0] < 48 || str[0] > 57){return false;}
++str;
}
return true;
}
/// Constructor that does the actual parsing
HTTP::URL::URL(const std::string &url){
IPv6Addr = false;
// first detect protocol at the start, if any
size_t proto_sep = url.find("://");
if (proto_sep != std::string::npos){
protocol = url.substr(0, proto_sep);
proto_sep += 3;
}else{
proto_sep = 0;
if (url.substr(0, 2) == "//"){proto_sep = 2;}
}
// proto_sep now points to the start of the host, guaranteed
// continue by finding the path, if any
size_t first_slash = url.find_first_of("/?#", proto_sep);
if (first_slash != std::string::npos){
if (url[first_slash] == '/'){
path = url.substr(first_slash + 1);
}else{
path = url.substr(first_slash);
}
if (protocol != "rtsp"){
size_t hmark = path.find('#');
if (hmark != std::string::npos){
frag = Encodings::URL::decode(path.substr(hmark + 1));
path.erase(hmark);
}
size_t qmark = path.find('?');
if (qmark != std::string::npos){
args = path.substr(qmark + 1);
path.erase(qmark);
}
}
if (path.size()){
if (path[0] == '/'){path.erase(0, 1);}
size_t dots = path.find("/./");
while (dots != std::string::npos){
DONTEVEN_MSG("%s (/./ -> /)", path.c_str());
path.erase(dots, 2);
dots = path.find("/./");
}
dots = path.find("//");
while (dots != std::string::npos){
DONTEVEN_MSG("%s (// -> /)", path.c_str());
path.erase(dots, 1);
dots = path.find("//");
}
if (path[0] == '/'){path.erase(0, 1);}
dots = path.find("/../");
while (dots != std::string::npos){
size_t prevslash = path.rfind('/', dots - 1);
if (prevslash == std::string::npos || dots == 0){
path.erase(0, dots + 4);
}else{
path.erase(prevslash + 1, dots - prevslash + 3);
}
dots = path.find("/../");
}
if (path.substr(0, 2) == "./"){path.erase(0, 2);}
if (path.substr(0, 3) == "../"){path.erase(0, 3);}
path = Encodings::URL::decode(path);
}
}
// user, pass, host and port are now definitely between proto_sep and first_slash
std::string uphp = url.substr(proto_sep, first_slash - proto_sep); // user+pass+host+port
// Check if we have a user/pass before the host
size_t at_sign = uphp.find('@');
if (at_sign != std::string::npos){
std::string creds = uphp.substr(0, at_sign);
uphp.erase(0, at_sign + 1);
size_t colon = creds.find(':');
if (colon != std::string::npos){
user = Encodings::URL::decode(creds.substr(0, colon));
pass = Encodings::URL::decode(creds.substr(colon + 1));
}else{
user = Encodings::URL::decode(creds);
}
}
// we check for [ at the start because we may have an IPv6 address as host
if (uphp[0] == '['){
// IPv6 address - find matching brace
IPv6Addr = true;
size_t closing_brace = uphp.find(']');
host = uphp.substr(1, closing_brace - 1);
// continue by finding port, if any
size_t colon = uphp.find(':', closing_brace);
if (colon == std::string::npos){
// no port. Assume default
port = "";
}else{
// we have a port number, read it
port = uphp.substr(colon + 1);
if (!is_numeric(port.c_str())){
host += ":" + port;
port = "";
}
}
}else{
//"normal" host - first find port, if any
size_t colon = uphp.rfind(':');
if (colon == std::string::npos){
// no port. Assume default
port = "";
host = uphp;
}else{
// we have a port number, read it
port = uphp.substr(colon + 1);
host = uphp.substr(0, colon);
if (!is_numeric(port.c_str())){
IPv6Addr = true;
host += ":" + port;
port = "";
}
}
}
// if the host is numeric, assume it is a port, instead
if (host.size() && is_numeric(host.c_str())){
port = host;
host = "";
}
EXTREME_MSG("URL: %s", getUrl().c_str());
}
/// Returns the port in numeric format
uint32_t HTTP::URL::getPort() const{
if (!port.size()){return getDefaultPort();}
return atoi(port.c_str());
}
/// Returns the default port for the protocol in numeric format
uint32_t HTTP::URL::getDefaultPort() const{
if (protocol == "http"){return 80;}
if (protocol == "https"){return 443;}
if (protocol == "rtmp"){return 1935;}
if (protocol == "rtmps"){return 443;}
if (protocol == "dtsc"){return 4200;}
if (protocol == "rtsp"){return 554;}
return 0;
}
/// Returns the file extension of the URL, or an empty string if none.
std::string HTTP::URL::getExt() const{
if (path.rfind('.') == std::string::npos){
return "";
}
return path.substr(path.rfind('.')+1);
}
/// Returns the full URL in string format
std::string HTTP::URL::getUrl() const{
std::string ret;
if (protocol.size()){
ret = protocol + "://";
}else{
ret = "//";
}
if (user.size() || pass.size()){
ret += Encodings::URL::encode(user) + ":" + Encodings::URL::encode(pass) + "@";
}
if (IPv6Addr){
ret += "[" + host + "]";
}else{
ret += host;
}
if (port.size() && getPort() != getDefaultPort()){ret += ":" + port;}
ret += "/";
if (protocol == "rtsp"){
if (path.size()){ret += Encodings::URL::encode(path, "/:=@[]#?&");}
}else{
if (path.size()){ret += Encodings::URL::encode(path, "/:=@[]");}
}
if (args.size()){ret += "?" + args;}
if (frag.size()){ret += "#" + Encodings::URL::encode(frag, "/:=@[]#?&");}
return ret;
}
/// Returns the full file path, in case this is a local file URI
std::string HTTP::URL::getFilePath() const{
return "/"+path;
}
/// Returns the URL in string format without auth and frag
std::string HTTP::URL::getProxyUrl() const{
std::string ret;
if (protocol.size()){
ret = protocol + "://";
}else{
ret = "//";
}
if (IPv6Addr){
ret += "[" + host + "]";
}else{
ret += host;
}
if (port.size() && getPort() != getDefaultPort()){ret += ":" + port;}
ret += "/";
if (protocol == "rtsp"){
if (path.size()){ret += Encodings::URL::encode(path, "/:=@[]#?&");}
}else{
if (path.size()){ret += Encodings::URL::encode(path, "/:=@[]");}
}
if (args.size()){ret += "?" + args;}
return ret;
}
/// Returns the URL in string format without args and frag
std::string HTTP::URL::getBareUrl() const{
std::string ret;
if (protocol.size()){
ret = protocol + "://";
}else{
ret = "//";
}
if (user.size() || pass.size()){
ret += Encodings::URL::encode(user) + ":" + Encodings::URL::encode(pass) + "@";
}
if (IPv6Addr){
ret += "[" + host + "]";
}else{
ret += host;
}
if (port.size() && getPort() != getDefaultPort()){ret += ":" + port;}
ret += "/";
if (protocol == "rtsp"){
if (path.size()){ret += Encodings::URL::encode(path, "/:=@[]#?&");}
}else{
if (path.size()){ret += Encodings::URL::encode(path, "/:=@[]");}
}
return ret;
}
/// Returns a URL object for the given link, resolved relative to the current URL object.
HTTP::URL HTTP::URL::link(const std::string &l) const{
// Full link
if (l.find("://") < l.find('/') && l.find('/' != std::string::npos)){
DONTEVEN_MSG("Full link: %s", l.c_str());
return URL(l);
}
// Absolute link
if (l[0] == '/'){
DONTEVEN_MSG("Absolute link: %s", l.c_str());
if (l.size() > 1 && l[1] == '/'){
// Same-protocol full link
return URL(protocol + ":" + l);
}else{
// Same-domain/port absolute link
URL tmp = *this;
tmp.args.clear();
tmp.path = l.substr(1);
// Abuse the fact that we don't check for arguments in getUrl()
return URL(tmp.getUrl());
}
}
// Relative link
std::string tmpUrl = getBareUrl();
size_t slashPos = tmpUrl.rfind('/');
if (slashPos == std::string::npos){
tmpUrl += "/";
}else{
tmpUrl.erase(slashPos + 1);
}
DONTEVEN_MSG("Relative link: %s+%s", tmpUrl.c_str(), l.c_str());
return URL(tmpUrl + l);
}

35
lib/url.h Normal file
View file

@ -0,0 +1,35 @@
/// \file url.h
/// Holds all headers for the HTTP::URL class.
#pragma once
#include <stdlib.h>
#include <string>
/// Holds all HTTP processing related code.
namespace HTTP{
/// URL parsing class. Parses full URL into its subcomponents
class URL{
public:
URL(const std::string &url = "");
uint32_t getPort() const;
uint32_t getDefaultPort() const;
std::string getExt() const;
std::string getUrl() const;
std::string getFilePath() const;
std::string getBareUrl() const;
std::string getProxyUrl() const;
std::string host; ///< Hostname or IP address of URL
std::string protocol; ///< Protocol of URL
std::string port; ///< Port of URL
std::string path; ///< Path after the first slash (not inclusive) but before any question mark
std::string args; ///< Everything after the question mark in the path, if it was present
std::string frag; ///< Everything after the # in the path, if it was present
std::string user; ///< Username, if it was present
std::string pass; ///< Password, if it was present
URL link(const std::string &l) const;
bool IPv6Addr;
};
}// namespace HTTP

View file

@ -8,6 +8,7 @@
#include <mist/procs.h>
#include <mist/stream.h>
#include <mist/bitfields.h>
#include <mist/url.h>
#include "controller_statistics.h"
#include "controller_limits.h"
#include "controller_push.h"

View file

@ -2,6 +2,7 @@
#include <mist/stream.h>
#include <mist/http_parser.h>
#include <mist/encode.h>
#include <mist/url.h>
#include "input_balancer.h"
namespace Mist {

View file

@ -4,6 +4,7 @@
#include <mist/nal.h>
#include <mist/rtp.h>
#include <mist/sdp.h>
#include <mist/url.h>
#include <set>
#include <string>

View file

@ -1,5 +1,6 @@
#include "output_hls.h"
#include <mist/stream.h>
#include <mist/url.h>
#include <mist/langcodes.h> /*LTS*/
#include <unistd.h>

View file

@ -3,6 +3,7 @@
#include <mist/stream.h>
#include <mist/encode.h>
#include <mist/langcodes.h>
#include <mist/url.h>
#include "flashPlayer.h"
#include "oldFlashPlayer.h"
#include <mist/websocket.h>

View file

@ -4,6 +4,7 @@
#include <mist/stream.h>
#include <unistd.h>
#include <mist/procs.h>
#include <mist/url.h>
namespace Mist{
OutHTTPTS::OutHTTPTS(Socket::Connection & conn) : TSOutput(conn){

View file

@ -3,6 +3,7 @@
#include <mist/amf.h>
#include <mist/rtmpchunks.h>
#include <mist/http_parser.h>
#include <mist/url.h>
namespace Mist {

View file

@ -6,6 +6,7 @@
#include <mist/rtp.h>
#include <mist/sdp.h>
#include <mist/socket.h>
#include <mist/url.h>
namespace Mist{
class OutRTSP : public Output{

View file

@ -1,6 +1,7 @@
#include "output_ts.h"
#include <mist/http_parser.h>
#include <mist/defines.h>
#include <mist/url.h>
namespace Mist {
OutTS::OutTS(Socket::Connection & conn) : TSOutput(conn){

View file

@ -1,25 +1,89 @@
///\file sourcery.cpp
///Utility program used for c-string dumping files.
#undef DEBUG
#define DEBUG -1
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <string>
#include "../lib/url.h"
#include "../lib/url.cpp"
#include "../lib/encode.h"
#include "../lib/encode.cpp"
std::string getContents(const char * fileName){
std::ifstream inFile(fileName);
std::string fullText;
if (inFile){
std::ostringstream contents;
contents << inFile.rdbuf();
inFile.close();
return contents.str();
}
return "";
}
int main(int argc, char* argv[]){
if (argc < 4) {
std::cerr << "Usage: " << argv[0] << " <inputFile> <variableName> <outputFile>" << std::endl;
std::cerr << "Usage: " << argv[0] << " <inputFile> <variableName> <outputFile> [<splittext>]" << std::endl;
return 42;
}
const char * splitText = 0;
if (argc >= 5){splitText = argv[4];}
char workDir[512];
getcwd(workDir, 512);
HTTP::URL inUri(std::string("file://") + workDir + "/");
inUri = inUri.link(argv[1]);
//Read the entire first argument into a string buffer
std::string fullText = getContents(inUri.getFilePath().c_str());
//replace every <script src="*"></script> with the contents of the file '*'
while (fullText.find("<script src=\"") != std::string::npos){
size_t locStart = fullText.find("<script src=\"");
size_t locEnd = fullText.find("\"></script>", locStart);
//Assume we should abort if the strlen of the filename is > 230 chars
if (locEnd - locStart >= 230){break;}
HTTP::URL fileName = inUri.link(fullText.substr(locStart+13, locEnd-locStart-13));
std::string subText = getContents(fileName.getFilePath().c_str());
fullText = fullText.substr(0, locStart) + "<script>" + subText + fullText.substr(locEnd+2);
}
size_t splitPoint = std::string::npos;
size_t splitLen = 0;
if (splitText){
splitPoint = fullText.find(splitText);
if (splitPoint != std::string::npos){
splitLen = strlen(splitText);
}
}
std::ofstream tmp(argv[3]);
//begin the first line
tmp << "const char *" << argv[2] << " = " << std::endl << " \"";
if (!splitLen){
tmp << "const char *" << argv[2] << " = " << std::endl << " \"";
}else{
tmp << "const char *" << argv[2] << "_prefix = " << std::endl << " \"";
}
uint32_t i = 0; //Current line byte counter
uint32_t total = 0; //Finished lines so far byte counter
std::ifstream inFile(argv[1]);
bool sawQ = false;
while (inFile.good()){
unsigned char thisChar = inFile.get();
if (!inFile.good()){break;}
for (size_t pos = 0; pos < fullText.size(); ++pos){
if (pos == splitPoint){
tmp << "\";" << std::endl << "uint32_t " << argv[2] << "_prefix_len = " << i + total << ";" << std::endl;
tmp << "const char *" << argv[2] << "_suffix = " << std::endl << " \"";
i = 0;
total = 0;
sawQ = false;
pos += splitLen;
}
unsigned char thisChar = fullText.at(pos);
switch (thisChar){
//Filter special characters.
case '\n': tmp << "\\n"; break;
@ -51,7 +115,7 @@ int main(int argc, char* argv[]){
}
}
//end the last line, plus length variable
tmp << "\";" << std::endl << "uint32_t " << argv[2] << "_len = " << i + total << ";" << std::endl;
tmp << "\";" << std::endl << "uint32_t " << argv[2] << (splitLen?"_suffix":"") << "_len = " << i + total << ";" << std::endl;
tmp.close();
return 0;
}