204 * @return string |
204 * @return string |
205 */ |
205 */ |
206 |
206 |
207 function makeUrlComplete($n, $t, $query = false, $escape = false) |
207 function makeUrlComplete($n, $t, $query = false, $escape = false) |
208 { |
208 { |
209 global $db, $session, $paths, $template, $plugins; // Common objects |
209 return get_server_url() . makeUrlNS($n, $t, $query, $escape); |
210 $flags = ''; |
210 } |
211 |
211 |
212 if(defined('ENANO_BASE_CLASSES_INITIALIZED')) |
212 /** |
213 { |
213 * Returns an http:// URL for this server. |
214 $sep = urlSeparator; |
214 * @return string |
215 } |
215 */ |
216 else |
216 |
217 { |
217 function get_server_url() |
218 $sep = (strstr($_SERVER['REQUEST_URI'], '?')) ? '&' : '?'; |
218 { |
219 } |
219 return 'http' . ( $GLOBALS['is_https'] ) . '://' . $_SERVER['HTTP_HOST']; |
220 if ( isset( $_GET['printable'] ) ) { |
|
221 $flags .= $sep . 'printable'; |
|
222 $sep = '&'; |
|
223 } |
|
224 if ( isset( $_GET['theme'] ) ) |
|
225 { |
|
226 $flags .= $sep . 'theme='.$session->theme; |
|
227 $sep = '&'; |
|
228 } |
|
229 if ( isset( $_GET['style'] ) ) |
|
230 { |
|
231 $flags .= $sep . 'style='.$session->style; |
|
232 $sep = '&'; |
|
233 } |
|
234 if ( isset($_GET['lang']) && preg_match('/^[a-z0-9_]+$/', @$_GET['lang']) ) |
|
235 { |
|
236 $flags .= $sep . 'lang=' . urlencode($_GET['lang']); |
|
237 $sep = '&'; |
|
238 } |
|
239 |
|
240 if(defined('ENANO_BASE_CLASSES_INITIALIZED')) |
|
241 { |
|
242 $url = $session->append_sid(contentPath . $paths->nslist[$n] . $t . $flags); |
|
243 } |
|
244 else |
|
245 { |
|
246 // If the path manager hasn't been initted yet, take an educated guess at what the URI should be |
|
247 $url = contentPath . $n . ':' . $t . $flags; |
|
248 } |
|
249 if($query) |
|
250 { |
|
251 if(strstr($url, '?')) $sep = '&'; |
|
252 else $sep = '?'; |
|
253 $url = $url . $sep . $query . $flags; |
|
254 } |
|
255 |
|
256 $baseprot = 'http' . ( isset($_SERVER['HTTPS']) ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST']; |
|
257 $url = $baseprot . $url; |
|
258 |
|
259 return ($escape) ? htmlspecialchars($url) : $url; |
|
260 } |
220 } |
261 |
221 |
262 /** |
222 /** |
263 * Returns the full page ID string of the main page. |
223 * Returns the full page ID string of the main page. |
264 * @return string |
224 * @return string |
1507 /** |
1467 /** |
1508 * A very basic single-character compression algorithm for binary strings/bitfields |
1468 * A very basic single-character compression algorithm for binary strings/bitfields |
1509 * @param string $bits the text to compress, should be only 1s and 0s |
1469 * @param string $bits the text to compress, should be only 1s and 0s |
1510 * @return string |
1470 * @return string |
1511 */ |
1471 */ |
1512 |
1472 |
1513 function compress_bitfield($bits) |
1473 function compress_bitfield($bits) |
1514 { |
1474 { |
1515 $crc32 = crc32($bits); |
1475 if ( !preg_match('/^[01]+$/', $bits) ) |
1516 $bits .= '0'; |
|
1517 $start_pos = 0; |
|
1518 $current = substr($bits, 1, 1); |
|
1519 $last = substr($bits, 0, 1); |
|
1520 $chunk_size = 1; |
|
1521 $len = strlen($bits); |
|
1522 $crc = $len; |
|
1523 $crcval = 0; |
|
1524 for ( $i = 1; $i < $len; $i++ ) |
|
1525 { |
|
1526 $current = substr($bits, $i, 1); |
|
1527 $last = substr($bits, $i - 1, 1); |
|
1528 $next = substr($bits, $i + 1, 1); |
|
1529 // Are we on the last character? |
|
1530 if($current == $last && $i+1 < $len) |
|
1531 $chunk_size++; |
|
1532 else |
|
1533 { |
|
1534 if($i+1 == $len && $current == $next) |
|
1535 { |
|
1536 // This character completes a chunk |
|
1537 $chunk_size++; |
|
1538 $i++; |
|
1539 $chunk = substr($bits, $start_pos, $chunk_size); |
|
1540 $chunklen = strlen($chunk); |
|
1541 $newchunk = $last . '[' . $chunklen . ']'; |
|
1542 $newlen = strlen($newchunk); |
|
1543 $bits = substr($bits, 0, $start_pos) . $newchunk . substr($bits, $i, $len); |
|
1544 $chunk_size = 1; |
|
1545 $i = $start_pos + $newlen; |
|
1546 $start_pos = $i; |
|
1547 $len = strlen($bits); |
|
1548 $crcval = $crcval + $chunklen; |
|
1549 } |
|
1550 else |
|
1551 { |
|
1552 // Last character completed a chunk |
|
1553 $chunk = substr($bits, $start_pos, $chunk_size); |
|
1554 $chunklen = strlen($chunk); |
|
1555 $newchunk = $last . '[' . $chunklen . '],'; |
|
1556 $newlen = strlen($newchunk); |
|
1557 $bits = substr($bits, 0, $start_pos) . $newchunk . substr($bits, $i, $len); |
|
1558 $chunk_size = 1; |
|
1559 $i = $start_pos + $newlen; |
|
1560 $start_pos = $i; |
|
1561 $len = strlen($bits); |
|
1562 $crcval = $crcval + $chunklen; |
|
1563 } |
|
1564 } |
|
1565 } |
|
1566 if($crc != $crcval) |
|
1567 { |
|
1568 echo __FUNCTION__.'(): ERROR: length check failed, this is a bug in the algorithm<br />Debug info: aiming for a CRC val of '.$crc.', got '.$crcval; |
|
1569 return false; |
1476 return false; |
1570 } |
1477 |
1571 $compressed = 'cbf:len='.$crc.';crc='.dechex($crc32).';data='.$bits.'|end'; |
1478 $current = intval($bits{0}); |
1572 return $compressed; |
1479 $clen = 0; |
1573 } |
1480 $out = ''; |
|
1481 for ( $i = 0; $i < strlen($bits); $i++ ) |
|
1482 { |
|
1483 $cbit = intval($bits{$i}); |
|
1484 if ( $cbit !== $current || $clen == 127 || $i == strlen($bits) - 1 ) |
|
1485 { |
|
1486 if ( $i == strlen($bits) - 1 && $cbit === $current ) |
|
1487 { |
|
1488 $clen++; |
|
1489 } |
|
1490 // write chunk |
|
1491 $byte = $clen; |
|
1492 if ( $current === 1 ) |
|
1493 $byte |= 0x80; |
|
1494 $out .= chr($byte); |
|
1495 |
|
1496 if ( $i == strlen($bits) - 1 && $cbit !== $current ) |
|
1497 { |
|
1498 $out .= ( $cbit === 1 ) ? chr(0x81) : chr(0x1); |
|
1499 } |
|
1500 |
|
1501 // reset |
|
1502 $current = intval($cbit); |
|
1503 $clen = 0; |
|
1504 } |
|
1505 $clen++; |
|
1506 } |
|
1507 $crc = dechex(crc32($out)); |
|
1508 while ( strlen($crc) < 8 ) |
|
1509 $crc = "0$crc"; |
|
1510 return "cbf2:{$crc}" . hexencode($out, '', ''); |
|
1511 } |
|
1512 |
|
1513 // test case |
|
1514 // $bf = '0111100010000000000000000000000100000000000000001110000000000000000101100000010100001100010000000000000000000000000000111111111111111111111100100001000000000000000000000000000000000000'; |
|
1515 // die('<pre>Original: ' . " $bf\nCompressed: " . compress_bitfield($bf) . "\nProcessed: ".uncompress_bitfield(compress_bitfield($bf)).'</pre>'); |
1574 |
1516 |
1575 /** |
1517 /** |
1576 * Uncompresses a bitfield compressed with compress_bitfield() |
1518 * Uncompresses a bitfield compressed with compress_bitfield() |
1577 * @param string $bits the compressed bitfield |
1519 * @param string $bits the compressed bitfield |
1578 * @return string the uncompressed, original (we hope) bitfield OR bool false on error |
1520 * @return string the uncompressed, original (we hope) bitfield OR bool false on error |
1579 */ |
1521 */ |
1580 |
1522 |
1581 function uncompress_bitfield($bits) |
1523 function uncompress_bitfield($bits) |
|
1524 { |
|
1525 if ( substr($bits, 0, 4) == 'cbf:' ) |
|
1526 { |
|
1527 return uncompress_bitfield_old($bits); |
|
1528 } |
|
1529 if ( substr($bits, 0, 5) != 'cbf2:' ) |
|
1530 { |
|
1531 echo __FUNCTION__.'(): ERROR: Invalid stream'; |
|
1532 return false; |
|
1533 } |
|
1534 $bits = substr($bits, 5); |
|
1535 $crc = substr($bits, 0, 8); |
|
1536 $bits = substr($bits, 8); |
|
1537 $bits = hexdecode($bits); |
|
1538 if ( dechex(crc32($bits)) !== $crc ) |
|
1539 { |
|
1540 echo __FUNCTION__."(): ERROR: CRC failed"; |
|
1541 return false; |
|
1542 } |
|
1543 $out = ''; |
|
1544 for ( $i = 0; $i < strlen($bits); $i++ ) |
|
1545 { |
|
1546 $byte = ord($bits{$i}); |
|
1547 $char = $byte & 0x80 ? '1' : '0'; |
|
1548 $byte &= ~0x80; |
|
1549 for ( $j = 0; $j < $byte; $j++ ) |
|
1550 { |
|
1551 $out .= $char; |
|
1552 } |
|
1553 } |
|
1554 return $out; |
|
1555 } |
|
1556 |
|
1557 /** |
|
1558 * Decompressor for old-format bitfields. |
|
1559 * @param string |
|
1560 * @return string |
|
1561 * @access private |
|
1562 */ |
|
1563 |
|
1564 function uncompress_bitfield_old($bits) |
1582 { |
1565 { |
1583 if(substr($bits, 0, 4) != 'cbf:') |
1566 if(substr($bits, 0, 4) != 'cbf:') |
1584 { |
1567 { |
1585 echo __FUNCTION__.'(): ERROR: Invalid stream'; |
1568 echo __FUNCTION__.'(): ERROR: Invalid stream'; |
1586 return false; |
1569 return false; |